I have two cells with numbers i.e. A1 and B1. I need a formula to get the digits in A1 which are present in B1 to be shown in cell B2.
In below example, all digits in A1 i.e. 5,3,9,4 are found in B1 and therefore shall be shown in cell B2
cell A1 = 5394
cell B1 = 7284395
cell B2 = 5394 [formula result]
Thank you
The below code will work. It divides the SearchTerm into individual character strings called SearchTerm_Individual based on the length of the SearchTerm. The code further appends the individual characters to the result cell, if found in the SearchIn String.
Option Explicit
Sub Search_Item2()
Dim SearchTerm As String
Dim SearchIn As String
Dim SearchTerm_Length As Integer
Dim X As Byte
SearchTerm = ThisWorkbook.Sheets("Sheet1").Range("A1").Value
SearchIn = ThisWorkbook.Sheets("Sheet1").Range("B1").Value
SearchTerm_Length = Len(SearchTerm)
Dim SearchTerm_Individual() As String
ReDim SearchTerm_Individual(1 To SearchTerm_Length) As String
For X = 1 To SearchTerm_Length
SearchTerm_Individual(X) = Mid(SearchTerm, X, 1)
If InStr(SearchIn, SearchTerm_Individual(X)) > 0 Then
ThisWorkbook.Sheets("Sheet1").Range("C1").Value = ThisWorkbook.Sheets("Sheet1").Range("C1").Value & SearchTerm_Individual(X)
End If
Next X
End Sub
The function below will work but is limited to 4 characters in A1.
=IF(AND(ISNUMBER(FIND(MID(A1, 1, 1), B1)), ISNUMBER(FIND(MID(A1, 2, 1), B1)), ISNUMBER(FIND(MID(A1, 3, 1), B1)), ISNUMBER(FIND(MID(A1, 4, 1), B1))), A1, "")
This looks at each character in A1 using MID(). It passes that to FIND() to see if that character is in B2. It uses ISNUMBER() around FIND() to see if it's getting a valid numerical result. In this case it's easier than checking for an error. It uses AND() to check that all 4 characters are in B2.
Again, this will work but is not flexible at all regarding the length if the text in A1. You likely want something different. Please share more info about what you're trying to accomplish.
Related
So I have this large excel file, over 7000 rows, and what I need to do is pick the content from a cell in a column, for example A2, and extract its content onto A3
The thing is that the content are abbreviatures, like PRD for period, or CLS for class, all abbreviature are separated by underscores with no particular order, so for example A2 can just say PRD but B2 would say PRD_CLS_PPRD_ADVAN and then back to CLS_ADV on C2
What I need is to extract the content from each cell an put it on another cell, the abbreviatures must be replaced by it's original word so instead of PRD it should say Period, or Class instead of CLS, when there's an underscore it should be replaced for a slash. So overall when B2 says PRD_CLS_PPRD_ADVAN then B3 should say Period/Class/Pre-Production/Advance
I've given it a lot of tries to solve this, using LEFT, RIGHT, EXTRACT, but to no avail, would appreciate any suggestion on how to solve this
So, slightly different approach using find():
Formula for C2:
IFERROR(IF(FIND($E$2,$A2,1)>0,VLOOKUP($E$2,$E$2:$F$5,2,0),"")&"/","")&IFERROR(IF(FIND($E$3,$A2,1)>0,VLOOKUP($E$3,$E$2:$F$5,2,0),"")&"/","")&IFERROR(IF(FIND($E$4,$A2,1)>0,VLOOKUP($E$4,$E$2:$F$5,2,0),"")&"/","")&IFERROR(IF(FIND($E$5,$A2,1)>0,VLOOKUP($E$5,$E$2:$F$5,2,0),""),"")
Let you think about the trailing "/"...
'something like that should get you started
Public Sub convertCell()
Dim rowmax As Integer
Dim i As Integer
Dim j As Integer
Dim StrArray() As String
Dim wrds As Integer
'replace sheet1 by the name of you sheets
rowmax = Worksheets("Sheet1").Cells(Rows.Count, 1).End(xlUp).Row
For i = 1 To rowmax
StrArray = Split(Worksheets("Sheet1").Cells(i, 1), "_")
wrds = UBound(StrArray)
For j = 0 To wrds
Worksheets("Sheet1").Cells(i, 2) = Worksheets("Sheet1").Cells(i, 2) & "/" & StrArray(j)
Next j
Next i
End Sub
So basic method using formulae:
Formulae in C2:
VLOOKUP(LEFT(A2,FIND("_",A2,1)-1),$E$2:$F$5,2,0)
Cells E2 to F5 hold the abbreviations, extend the range as needed.
So, update, been playing.
Just done the first two, use mid() for number 3 and right for number 4.
I'm working on a function that returns the formula of its input cell, replacing all references to other cells with the cells' values. My current implementation works fine unless the input cell contains absolute references, which is what I'd like to improve upon.
Currently, I extract the Range.FormulaR1C1 property of the input cell and replace all addresses with values of their respective cells. It's fairly easy to recognize relative addresses, because they contain square brackets, i.e. []. The general format is R[rN]C[cN] with rN and cN denoting relative row or column numbers (integer values) - if either of these equals zero, it gets omitted along with the brackets, so there's two possibilities for a position in a formula to be the start of an address:
Next two characters are "R["
Next three characters are "RC["
(Self referencing is not allowed, so we can exclude "RC".)
When we introduce absolute addresses, the brackets disappear and the general address format becomes RrNCcN. Now it gets more complicated to recognize an address and I'd prefer to stick to the two simple rules R[ and RC[. If I could convert absolute cell references to relative and return them in the R1C1 format, I could leave the current implementation unchanged.
I need to get a cell's formula in the R1C1 format, with all absolute cell references replaced by relative ones. It's theoretically very simple to remove absolute references from an address in the A1 format (Range.Formula property) by just removing all "$" signs. Alas, I don't know how to convert the address back to R1C1 format after doing that. Below is a naive implementation which fails on the penultimate row, but captures the idea I think. I have no clue on how to proceed or if it's even possible to do this as simply as I imagine.
Function returnRelativeFormulaR1C1(refCell As Range) As String
Dim refAddress As String, addressLength As Integer, posRow As Integer, posCol As Integer, iColNr As Integer
refAddress = refCell.Address(ReferenceStyle:=xlR1C1)
addressLength = Len(refAddress)
iColNr = InStr(2, refAddress, "C")
posRow = Val(Mid(refAddress, 2, iColNr - 1)) ' Begin at 2, because there's always "R" at the beginning
posCol = Val(Mid(refAddress, iColNr + 1, addressLength - iColNr))
Dim formulaText As String
formulaText = Cells(posRow, posCol).Formula ' Get formula in A1 format
Dim formulaTextRelative As String
formulaTextRelative = Replace(formulaText, "$", "") ' Remove "$" signs, i.e. convert absolute references to relative
Dim convRange As Range
Set convRange = refCell
convRange.Cells(1, 1).Formula = formulaTextRelative ' Assign the converted formula to a virtual cell? The code fails here.
returnRelativeFormulaR1C1 = convRange.Cells(1, 1).FormulaR1C1 ' If the previous row worked, this should then take care of the conversion back to R1C1 format.
End Function
Many thanks to chris neilsen, ConvertFormula was just what I needed.
Corrected implementation of the conversion:
Function returnRelativeFormulaR1C1(refCell As Range) As String
Dim refAddress As String, addressLength As Integer, posRow As Integer, posCol As Integer, iColNr As Integer
refAddress = refCell.Address(ReferenceStyle:=xlR1C1)
addressLength = Len(refAddress)
iColNr = InStr(2, refAddress, "C")
posRow = Val(Mid(refAddress, 2, iColNr - 1)) ' Begin at 2, because there's always "R" at the beginning
posCol = Val(Mid(refAddress, iColNr + 1, addressLength - iColNr))
Dim formulaTextA1 As String
formulaTextA1 = Cells(posRow, posCol).Formula ' Get formula in A1 format
Dim formulaTextA1Relative As String
formulaTextA1Relative = Replace(formulaTextA1, "$", "") ' Remove "$" signs, i.e. convert absolute references to relative
returnRelativeFormulaR1C1 = Application.ConvertFormula(Formula:=formulaTextA1Relative, fromReferenceStyle:=xlA1, toReferenceStyle:=xlR1C1, RelativeTo:=refCell) ' Convert back to R1C1
End Function
I'm trying to obtain a column that will contain the index number of first word from the referenced column cell by cell.
I am able to get the length of word in a text, for upper cell value in have used ActiveCell.Offset(-1, 0).Activate but it does not work for me.
Public Function StartIndex(ByVal strText As String) As Long
Application.Volatile
Length = UBound(Split(strText, " ")) + 1
StartIndex = ActiveCell.Offset(-1, 0).Activate + Length
End Function
look below, consider I'm having col1 by default and want startIndex through VBA;
Col1 | startIndex
VBA Index Printer Friendly version | 1
Adobe Acrobat version | 6
A UDF can remain in a code module | 9
as shown above consider the table have 3 rows and two columns,the index number of word "VBA"**in col1 row1 is 1 similarly word **"is" next to word "VBA" have an index of 2, and so on .. Consider the rows are a combination of a paragraph and so when we reach Col1 row2 the index of word "Adobe" should be 6 as shown in table
Actually startIndex column shows the index number of the first word from the paragraph which is divided in rows
No need for VBA just use a formula to count the words:
Then add the amount of words to the previous amount of words (from the row above).
Write 1 into B1 (it is always 1)
Use the following formula in B2:
=B1+LEN(TRIM(A1))-LEN(SUBSTITUTE(TRIM(A1)," ",""))+1
Copy the formula from B2 to B3
I've modified your original Function a litte bit, to be able to handle ranges:
Public Function StartIndex(ByVal vRNG As Range) As Long
Application.Volatile
Dim rng As Range
For Each rng In vRNG
StartIndex = UBound(Split(rng.Value, " ")) + 1 + StartIndex
Next rng
End Function
Then, you can apply it like this:
=StartIndex($A$1:A1)+1
But to make it work you need to apply it from row 2....
Another option would be to input in B1 just a 1 (because it always going to be 1) and then in B2, same formula:
=StartIndex($A$1:A1)+1
And it would work:
I'd approach this slightly differently and pass the range instead.
Public Function StartIndex(ByVal textCell As Range) As Long
Dim text As String
text = textCell.Value
Dim result As Long
result = (UBound(Split(text, " ")) + 1)
If textCell.Row > 1 Then
result = result - (UBound(Split(textCell.Offset(-1, 0).Value, " ")) + 1)
End If
StartIndex = result
End Function
example use:
=StartIndex(A1)
or in VBA:
Dim index As Long
index = StartIndex(Range("A1"))
I have a list of cells with values like the below:
a,a,b,c,d
f,g,h,h,h,j
a,b,b
f,f,f,y,y,u,u
I want a formula that will give me the below (unique list of above). I should be able to write it for one row and copy it down.
a,b,c,d
f,g,h,j
a,b
f,y,u
There is no way to do this with a formula that will return comma-separated unique results into one cell, using only the built-in worksheet functions.
But, it is very simple to achieve the same thing with a User Defined Function (UDF).
Just place this small routine in a standard code module:
Public Function UniqueList(s)
Dim i&, k$, v
v = Split(s, ",")
For i = 0 To UBound(v)
If InStr(k, v(i)) = 0 Then k = k & "," & v(i)
Next
UniqueList = Mid$(k, 2)
End Function
If your source string is in cell A1 then in cell B1 enter this formula:
=UniqueList(A1)
That's it. Now copy the formula downward as far as needed.
Considering the repeated letters are in order, as in your sample, this should do the trick:
Function UniqueLetters(ByVal cell As Range) As String
letters = Split(cell.Value, ",")
For Each letter In letters
If letter <> current_letter Then
current_letter = letter
unique_letters = unique_letters + letter + ","
End If
Next
UniqueLetters = Left(unique_letters, Len(unique_letters) - 1)
End Function
I have received a worksheet in Excel which contains kids names and video time tags all in one column, and I need to sort this into a logical format so I can use it. However, the list has no separators.. So I am hoping someone could help me out with a VBA Excel macro.
Below is an example (shortened) string, lets say this is in Cell A1.
" Sandy 25:1132:27Giorgio
09:1114:7Anne Marie 32:10David 17:48Marty
04:3506:1010:3613:1014:32Sandy (2) 04:30Brian 13:4714:37"
I would ideally like for the string to be split up into cells as follows
Cell A2 Sandy
Cell A3 25:11
Cell A4 32:27
Cell A5 Giorgio
Cell A6 09:11
Cell A7 14:7
Cell A8 Anne Marie
Cell A9 32:10
Cell A10 David
Cell A11 17:48
Cell A12 Marty
Cell A13 04:35
Cell A14 06:10
Cell A15 10:36
Cell A16 13:10
Cell A17 14:32
Cell A18 Sandy (2)
Cell A19 04:30
Cell A20 Brian
Cell A21 13:47
Cell A22 14:37
I have tried using some basic "find" and "len" formulas but no luck..
Doesn't do exactly what you want - but it may help get you going in a direction... Hopefully it'll turn out to be the right one...
I pasted your string into cell A1 in my worksheet and then wrote this code in a module in the sheet:-
Function parseText(ByVal text As String, ByVal domain As Integer) As String
Dim returnValue As String
Dim colon As Integer
Dim soFar As Integer
soFar = 0
text = Trim(text)
While soFar < domain
colon = InStr(text, ":")
While (Mid(text, colon + 5, 1) = ":")
colon = colon + 5
Wend
returnValue = Mid(text, 1, colon + 2)
While Not (IsNumeric(Right(returnValue, 1)))
returnValue = Left(returnValue, Len(returnValue) - 1)
Wend
text = Replace(text, returnValue, "")
soFar = soFar + 1
Wend
parseText = returnValue
End Function
Function parseDomain(ByVal domain As String) As String
Dim returnValue As String
Dim part As String
While Len(domain) > 0
part = ""
If InStr(domain, ":") > 0 Then
part = Mid(domain, InStrRev(domain, ":") - 2, 5)
returnValue = part & "~" & returnValue
domain = Left(domain, Len(domain) - Len(part))
End If
If part = "" Then
returnValue = Trim(domain) & "~" & Left(returnValue, Len(returnValue) - 1)
domain = ""
End If
Wend
parseDomain = returnValue
End Function
Function pullPiece(ByVal block As String, ByVal piece As Integer) As String
Dim returnValue As String
Dim pieces() As String
pieces = Split(block, "~")
If piece > UBound(pieces) + 1 Then
returnValue = ""
Else
returnValue = pieces(piece - 1)
End If
pullPiece = returnValue
End Function
This bit is complicated to explain...
In the image below the formula in A14 is the content of cell A4. The formula in A15 is the content of cell A5, etc. all the way down to A10. These formulae break out the block of text for each name.
The formula in B14 is the content of B4. This cell can then be copied down the range to B10 so that the references change to A4 thru A10. These formulae reformat the text with tildes so that the text is easier to split up (later).
The formula in C14 is the contents of C4. This cell can be copied down to C10. This pulls the name from the block it relates to. The second parameter is the "piece" number - 1=name, 2=time1, 3=time2, etc.
The formula in D14 is the contents of cells D4 and pulls the first time out of the block it relates to. I haven't put the definition for the other formulae - but hopefully you can see the pattern on how they are used.
Drop me a message if you want any clarification.
The string is difficult to parse due to the timestamps not appearing to follow a similar format. For example most follow the format 00:00, however the value you wish to place in cell A7 only has a single digit following the colon. I have therefore created some code to get you started in the right direction, but this works on the assumption of the format 00.00 and currently doesn't parse text following numbers. But if you perform a bit more research I'm sure you can complete from this point:
Public Sub TestCode()
Dim strTest As String, strModify() As String, strNew() As String, x As Long
strTest = "Sandy 25:1132:27Giorgio 09:1114:7Anne Marie 32:10David 17:48Marty 04:3506:1010:3613:1014:32Sandy (2) 04:30Brian 13:4714:37"
strModify = Split(strTest)
ReDim strNew(0 To 0)
strNew(0) = strModify(0)
For x = 1 To UBound(strModify)
If Left(strModify(x), 1) Like "[A-Z]" Then
ReDim Preserve strNew(0 To (UBound(strNew) + 1))
strNew(UBound(strNew)) = strModify(x)
ElseIf Left(strModify(x), 1) Like "[0-9]" Then
Do Until InStr(1, strModify(x), ":") = 0
ReDim Preserve strNew(0 To (UBound(strNew) + 1))
strNew(UBound(strNew)) = Left(strModify(x), InStr(1, strModify(x), ":") + 2)
strModify(x) = Right(strModify(x), Len(strModify(x)) - (InStr(1, strModify(x), ":") + 2))
Loop
Else
strNew(UBound(strNew)) = strNew(UBound(strNew)) & " " & strModify(x)
End If
Next x
For x = 0 To UBound(strNew)
Range("A1").Offset(0, x).Value = strNew(x)
Next x
End Sub
To help you understand the code in order to modify, this is basically splitting the original string wherever there is a space (result placed in array called strModify). It then checks the first character in the string to see if it is a letter, number or other character. Based on this information it will place the individual components of the string in to a new array variable called strNew. It then simply reads this array and places each item in to the next available cell.
I hope this helps you begin. Once you have a solution please post your final code on here in order to help others who may have a similar problem.