In an Excel column, either there is one value (alphanumerical) that I should copy to the cell of the same row but in another column or there are more than one value separated by space and I should copy the last one in to the other column. The values have the same format, digits 5 or 6 followed by a character and three digits (8 or 9 chars). How can I copy correctly if there is one value in the other column and if there are more than one value the last one on 8 or 9 characters?
Thanks
Carol
(updated after additional input and chat)
In one shot!
=IF( AND(ISERR(FIND(CHAR(10), A1)), ISERR(FIND(CHAR(32), A1))), A1,
MID(A1, MAX(IFERROR(FIND("#",SUBSTITUTE(A1,CHAR(10),"#",LEN(A1)-LEN(SUBSTITUTE(A1,CHAR(10),"")))),0),IFERROR(FIND("#",SUBSTITUTE(A1,CHAR(32),"#",LEN(A1)-LEN(SUBSTITUTE(A1,CHAR(32),"")))),0) )+1, LEN(A1)- MAX(IFERROR(FIND("#",SUBSTITUTE(A1,CHAR(10),"#",LEN(A1)-LEN(SUBSTITUTE(A1,CHAR(10),"")))),0),IFERROR(FIND("#",SUBSTITUTE(A1,CHAR(32),"#",LEN(A1)-LEN(SUBSTITUTE(A1,CHAR(32),"")))),0) ) )
)
In words...
if no line break or space is found then take the entire cell text,
otherwise
find the last occurrence of a linebreak (char 10) or space (char 32) and take the text from that index
You can also use this formula.
=IF(ISNUMBER(SEARCH(" ",A1)),TRIM(RIGHT(SUBSTITUTE(A1," ",REPT(" ",LEN(A1))),LEN(A1))),A1)
Use following VBA sub to copy to another column.
Public Sub CopyAnotherColumn()
Dim LastUsedCell As Long
Dim stCopyItIt As String
LastUsedCell = Range("A1").End(xlDown).Row
For Each rCell In Range("A1:A" & LastUsedCell)
If InStr(1, rCell, " ", vbTextCompare) > 0 Then
stCopyItIt = StrReverse(rCell.Value)
stCopyItIt = Left(stCopyItIt, InStr(1, stCopyItIt, " ", vbTextCompare))
ReturnLastWord = StrReverse(Trim(stCopyItIt))
rCell.Offset(0, 2).Value = ReturnLastWord
Else
rCell.Offset(0, 2).Value = rCell.Value
End If
Next
End Sub
Related
I have a chart with a text-column with numerous entries per cell.
Entries are separated with “;”.
Entries have the format “xy 00/00” (e.g. “AB 03/18”).
I need Excel to find and give in the next column a specific entry I predefine per row (above the column, example below).
Only the first two and last two characters are defined, the characters in the middle can be whatever (e.g. “AB ??/18”).
A cell can have more than one entry with the definition of “AB ??/18” (e.g. “AB 03/18” & “AB 08/18” etc.).
I need to know, if there are more than 1 of this predefined entries.
If I change the search box to “ZZ ??/12”, it should overwrite the previous defined search and give me back only the ZZ… ones.
For example:
Screenshot Chart
I tried a formula, but it gives me the first AB…, not the rest.
If it is only possible to give back the amount of the searched text in the cell above, that would also be ok.
Your screenshot doesn't seem entirely consistent with your objective, i.e.
the pattern AB ##/18 can be found 3 times in the string
blabla WF 12/23; AB 08/18; AB 09/18; AB 08/18
but your count column registers only 1 result (for AB 08/18)- there is also a match in the 1st row (for AB 12/18), but there you have a count of 0...
The code below assumes that the 4 data cells from your screenshot are in the range A3:A6 and that they are not part of a table
Sub txtMatching()
Dim results As String, cell As Range, incidence As Integer, pattern As String, pos As Integer, temp As String
pattern = "AB ##/18"
For Each cell In Range("A3:A6")
pos = 1
If cell.Value Like "*" & pattern & "*" Then
Do
pos = InStr(pos, cell.Value2, Mid(pattern, 1, InStr(1, pattern, "#") - 1))
If pos = 0 Then Exit Do
temp = Mid(cell.Value2, pos, Len(pattern))
If temp Like pattern Then
results = results & temp & "; "
incidence = incidence + 1
End If
pos = pos + Len(pattern)
Loop While pos < Len(cell.Value2)
cell.Offset(0, 1).Resize(1, 2).Value2 = Array(Mid(results, 1, Len(results) - 2), incidence)
results = vbNullString
incidence = 0
Else
cell.Offset(0, 2).Value2 = 0
End If
Next cell
End Sub
I looked for several hours for a satisfactory answer to this question and couldn't find one, so I rolled my own.
For example, suppose cell A1 = "word1", A2 = "word2", A3 = "word3", and A4 = "word4."
I want B1 to be "word1 word2 word3 word4 "
If none, any, or all the words in column A are bold, I want that reflected in B1. Like this:
partial sheet image
Sub test1()
Dim Row As Integer
Dim Start As Integer
Dim Length As Integer
' concatenate the words with a space between each
Range("B1").Value = ""
For Row = 1 To 4
Range("B1").Value = Range("B1").Value & " " & Cells(Row, "A").Value
Next Row
' match bold formatting
Start = 1
For Row = 1 To 4
Length = Len(Cells(Row, "A").Value)
Range("B1").Characters(Start, Length + 1).Font.Bold = Cells(Row, "A").Font.Bold
Start = Start + Length + 1
Next Row
End Sub
I found I needed two separate loops to make this work. With one loop, Excel made bold all the words following the first bold one, except the last word if it was not bold.
Why did I need (Start, Length + 1) in the code above?
I know this is not an exact answer but maybe can provide you ideas:
With ActiveCell.Characters(Start:=13, Length:=6).Font
.FontStyle = "Bold"
End With
You need to find how to set your Start and Length values using the functions that fit your needs.
The usage of Length + 1 makes that select all the text in your cell before Start.
I have a spreadsheet with a load of random text and numbers in column A like so:
Column A
Row 1 = 471806121601 5205569 - 0007 Standard White Toilet Tissue 27
Row 2 = 471814121601 5206177 - 0014 Premium White Toilet Tissue 6
Row 3 = 471814121601 5206178 - 0007 Premium White Toilet Tissue 27
Row 4 = 471806121601 5206180 - 0014 Premium Kitchen Towel 2x75l 6
I have about 2000 lines in total. In each cell, is a Purchase order number (12 digits) and an item number next to it (7 digits).
I am trying to extract the po number and put it into column B and extract the item number and put it into column C
Column B Column C
471806121601 5205569
471814121601 5206177
471814121601 5206178
471806121601 5206180
Here is my code:
Option Explicit
Sub main()
Dim cell As Range
Dim arr As Variant, arrElem As Variant
With Worksheets("Orders") '<--| change "Strings" to your actual worksheet name
For Each cell In .Range("A1", .Cells(.Rows.Count, "A").End(xlUp))
arr = Split(Replace(cell.Value, " ", " "), " ") '<--| change "A"'s to your actual relevant column index
For Each arrElem In arr
If IsNumeric(arrElem) Then
If Len(arrElem) = 12 Then cell.Offset(0, 1).Value = arrElem
End If
Next arrElem
Next cell
End With
Dim cell2 As Range
Dim arr2 As Variant, arrElem2 As Variant
With Worksheets("Orders") '<--| change "Strings" to your actual worksheet name
For Each cell2 In .Range("A1", .Cells(.Rows.Count, "A").End(xlUp))
arr2 = Split(Replace(cell2.Value, " ", " "), " ") '<--| change "A"'s to your actual relevant column index
For Each arrElem2 In arr2
If IsNumeric(arrElem2) Then
If Len(arrElem2) = 7 Then cell2.Offset(0, 3).Value = arrElem2
End If
Next arrElem2
Next cell2
End With
End Sub
This code does work. However it takes absolutely ages and only does one line at a time...Slowly.
Is there a quicker way of doing this? Thanks
If your PO and IN are always the same length in col B put
=MID(A2, 1, 12)
And in col C
=MID(A2, 14, 7)
However if your number change but are always the first two swap the above for,
=MID(A2,1,FIND(" ",A2,1)-1)
And
=MID(A2, FIND(" ", A2, 1)+1, 7)
Respectively.
just use split(string,delimiter)(0) and (1) why replace the space, just use that as the delim. If Row # is in, then use (1) and (2), or you could consider split(split(input,"-")," ") maybe a little faster, not sure though. Also, once you're done no need to complete the loop, so consider, do until with flags rather than for next, although exit for is available
Formula wise, it could be done using something like this
=MID(D1,FIND("é",SUBSTITUTE(D1," ","é",3)),FIND("é",SUBSTITUTE(D1," ","é",4))-FIND("é",SUBSTITUTE(D1," ","é",3)))
and
=MID(D1,FIND("é",SUBSTITUTE(D1," ","é",4)),FIND("é",SUBSTITUTE(D1," ","é",5))-FIND("é",SUBSTITUTE(D1," ","é",4)))
I have a one column filled with values like 3 days, 6 days, etc.
How can I strip out the text and force convert these to integers?
If you want to convert them "in-place", then select the cells and run this little macro:
Sub fixData()
Dim r As Range, v As String, i As Long
For Each r In Intersect(Selection, ActiveSheet.UsedRange)
v = r.Text
i = InStr(1, v, " ")
If i <> 0 Then
r.Value = Mid(v, 1, i - 1)
End If
Next r
End Sub
You could try substitute on a column next to you data:
=substitute(A1," days","") +0
Substitute replaces the string part " data" with nothing (zls "") and adding zero returns a number. This assumes your data is in col A. Drag down the formula and voila
If you don't mind changing the data you could also just select it all hit ctrl+F choose find and replace find field is " days", leave replace with blank and hit "Replace all"
If its VBA, you could actually use the Val function to do this.
If A1 has the data and you want this integer value in A2
So something like:
Range("A2").value = Val(Range("A1").value)
The returned value is actually a double. If a double isn't good enough,
Range("A2").value = CInt(Val(Range("A1").value))
Hope that helps.
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.