replace string in cell range with part of the original text - excel

I have an excel sheet with a column for Car number. It is currently downloaded as a report with the format "58 58" for car number 58.
I would like to replace each occurrence down column H and replace "58 58" with a numeric "58" | "60 60" with "a numeric "60" | "90 90" with a numeric "90" and so on.
This is all done in VBA.
Thank you
UPDATED CODE:
Dim X As Long
For X = 2 To Range("I" & Rows.Count).End(xlUp).Row 'Change 1 to 2 if you have a heading in row 1
Range("I" & X).Formula = Split(Range("I" & X).Text, " ")(0)
I used the above code, but it gave me runtime error (9) subscript out of range

Probably the easiest way is to loop. Going backwards alleviates possible issues with 101 being messed up if you start at 1.
Sub DoubleToSingle()
Dim X As Long
For X = 100 To 1 Step -1
Cells.Replace X & " " & X, X
Next
End Sub
This works on all cells, if you want it on just a column replace Cells. with Columns(2). where 2 is column B and 3 would be C etc.
Edit: use this code for your updated questions:
Sub DoubleToSingle2()
Dim X As Long
For X = 2 To Range("I" & Rows.Count).End(xlUp).Row
If InStr(1, Range("I" & X).text, " ") > 0 Then Range("I" & X).Formula = Split(Range("I" & X).text, " ")(0)
Next
End Sub
How it works: It polls through all cells in column I that have data and for each cell it splits the text of the cell into an array using space, then it takes just the first element in the array (basically everything before the first space) and posts that back to the cell.

Related

Adding items by keeping the order vba

I have the bellow list, where I should add items in column B in each sheet ; liste_lameM1, liste_lameM2, liste_lameM3 et liste_lameM4:
enter image description here
I need to set a condition on the numbers of the column A, to add new item I need to specify the model from a combobox where i have 4 options( M1, M2, M3, M4) to choose the sheet where the item should be added (this part works well).
The second condition is to select a number from 001 to 300 from a combobox to be able to add my item in the correct place on column B, so if I choose 006, modele M1 my data should be in column B, line 7 in worksheet liste_lameM1, if I choose 007, modele M1 my data should be in column B line8 worksheet liste_lameM1, if I choose 010 , modele M2, my data is added on column B line 11 worksheet liste_lameM2 and so on.
here is my code:
Private Sub CommandButton1_Click()
Dim fin_liste As Range, ligne As Long, ws_lame As Worksheet, ctrl As Boolean
Set ws_lame = ActiveWorkbook.Worksheets("Liste_Lame_" & Me.ComboBox_Modele.Value)
Set fin_liste = ThisWorkbook.Worksheets("Liste_Lame_" & Me.ComboBox_Modele.Value).Cells(Rows.Count, "B").End(xlUp).Offset(1, 0)
For j = 2 To fin_liste
If ws_lame.Range("A" & j) = Me.ComboBox_Num.Value Then
ctrl = True
fin_liste = Me.ComboBox_Num.Value & "-" & Me.TextBox_Mois.Value & "-" & Me.TextBox_Annee.Value & "-" & Me.ComboBox_Modele.Value & "-" & Me.ComboBox_Const.Value
Exit For
End If
Next
If ctrl = False Then
j = fin_liste + 1
ws_lame.Range("A" & j).Value = Me.ComboBox_Num.Value
fin_liste = Me.ComboBox_Num.Value & "-" & Me.TextBox_Mois.Value & "-" & Me.TextBox_Annee.Value & "-" & Me.ComboBox_Modele.Value & "-" & Me.ComboBox_Const.Value
End If
End Sub
The problem with my code is that it is not respecting the numbers I am choosing, it just adds the items one after the other, what editing should I make ? thanks
Variable "j" for looping, I change to "ligne".
Based on your explanation, you can't make the second condition if you use this code as I give you before.
fin_liste = ThisWorkbook.Worksheets(combo.Value).Cells(Rows.Count, "B").End(xlUp).Offset(1, 0)
So even you choose number between 001 & 300, it still add the data exactly on the last row at column "B".
For example, if the last data on cell "B3" (B4 still empty) then you choose number 5 (you hope the data will add on "B6"), the data will add on "B4".
Then maybe you'll find that you can change the .offset(ComboBox_Num.Value, 0), but it will make your data in a mess.
So the code that I give you before ineffective for the 2nd condition.
Based on the 2nd condition, you can use this.
fin_liste = ThisWorkbook.Worksheets(combo.Value).Cells(ComboBox_Num.Value, "B").offset(1, 0)
I still write .offset(1, 0), because I think you want to add the first data on cell "B2", right?
Actually that code have a problem, but based on you question, I think that problem will not affect you. You'll find it out soon. (You should consider Zac's comment)
I've rewrite your code so I can try it on my excel easier. You can change it into your version.
Private Sub CommandButton1_Click()
Dim fin_liste As Range, ligne As Long, ws_lame As Worksheet, ctrl As Boolean
Set ws_lame = ActiveWorkbook.Worksheets(combo.value)
Set fin_liste = ThisWorkbook.Worksheets(combo.Value).Cells(combo2.Value, "B").Offset(1, 0) '.End(xlUp).Offset(combo2.Value, 0)
For ligne = 2 To fin_liste
If ws_lame.Range("A" & ligne) = combo2.Value Then
ctrl = True
fin_liste = text.Value
End If
Next
If ctrl = False Then
ligne = fin_liste + 1
ws_lame.Range("A" & ligne) = combo2.Value
fin_liste = text.Value
End If
End Sub

Trying to improve quality and efficiency of my VBA code

I have 50,000 name and address strings each occupying one cell. In order to Split the cell out to different Name, Street Number, Street, City etc I am trying to split the cells to columns that match either Street Number and Or Street Name.
Cell Examples all in column E:
Row Col: E
aparts. 56 Johnston Terrace Keyham Road
90 & 92 Wolseley Road
2 Ainslie Terrace
Dyer & Cleaner 10 & 12 Mount Gold Road
48b Alexander Road
Dairy Farmer Stratham Priory Road
NewCell Result in columns;
Row. Col.F | Col.G | Col.H
aparts.| 56 | Johnston Terrace Keyham Road
'*' | 90 & 92 | Wolseley Road
'*' | 2 | Ainslie Terrace
Dyer & Cleaner | 10 & 12 | Mount Gold Road
'*' | 48b | Alexander Road
Dairy Farmer | '*' | Stratham Priory Road
At the present my Excel Sheet does not have specific column names, only A; B; C etc. I have VBA code that will separate each cell. However, the Street Number and/or Street Name will be split differently depending on the "textnumbertext" string in each cell.
I have separate VBA code to add an asterisk in front of any entry that starts with a Street Number (see Code). This then places each cell in the correct column (I can delete the asterisk later). However, I feel that this code is inefficient and perhaps could be less verbose if perhaps I were to use the Case function.
A further complication is some Street numbers will be 14A or 12B or 10c, or 12a. If I add these options to the below code then everything becomes very long winded and inefficient. Any thoughts please?
Sub ReplaceFirstNumber()
'If the first character in the string starts with a number between 1-9 THEN
'ADD a * to the string
Dim r As Range
Dim c As Range
On Error Resume Next
Set r = Range(Range("E1"), Range("E" & Rows.Count).End(xlDown))
For Each c In r
If Left(c.Value, 1) = "1" _
Or Left(c.Value, 1) = "2" _
Or Left(c.Value, 1) = "3" _
Or Left(c.Value, 1) = "4" _
Or Left(c.Value, 1) = "5" _
Or Left(c.Value, 1) = "6" _
Or Left(c.Value, 1) = "7" _
Or Left(c.Value, 1) = "8" _
Or Left(c.Value, 1) = "9" Then
c.Value = " * " & c.Value
End If
Next c
End Sub
The function below will hopefully help you make this task a tad easier. It strips all numeric characters from the address string, and will include any trailing single letters.
Function getnumbersfromstring(address As String) As String
For i = 1 To Len(address)
If IsNumeric(Mid(address, i, 1)) Then getnumbersfromstring = getnumbersfromstring & Mid(address, i, 1)
Next i
CharAfterNumber = Mid(address, Instr(1, address, getnumbersfromstring) + Len(getnumbersfromstring), 1)
If IsNumeric(CharAfterNumber) = False And Not CharAfterNumber = " " And Not CharAfterNumber = "" Then
getnumbersfromstring = getnumbersfromstring & CharAfterNumber
End If
End Function
This function can be called in a regular Sub like so
Sub breakupaddress()
Dim r As Range
Dim c As Range
Dim addressnr As String
On Error Resume Next
Set r = Range(Range("E1"), Range("E" & Rows.Count).End(xlDown))
For Each c In r
addressnr = getnumbersfromstring(c.Value)
MsgBox "The address number is '" & addressnr & "'.", vbInformation, "Information"
Next c
End Sub
I'm curious about how you will code everything, but about your question, something that might work would be:
Sub ReplaceFirstNumber()
'If the first character in the string starts with a number between 1-9 THEN
'ADD a * to the string
Dim r As Range
Dim c As Range
Set r = Range("E1:E" & Range("E" & Rows.Count).End(xlUp).Row)
For Each c In r
If IsNumeric(Left(c.Value, 1))=True Then c.Value = "*" & c.Value
Next c
End Sub
In your code you use Range(Range("E1"), Range("E" & Rows.Count).End(xlDown)). This means all cells in column E!. And that's like a million cells in Excel 2007 or higher. In my code, the range is Set r = Range("E1:E" & Range("E" & Rows.Count).End(xlUp).Row) This will select only all cells between E1 and the last non blank cell in Column E, so it will improve executing times a lot if you have only 50.000 rows of data.
Also, if you are learning VBA, I strongly encourage you to never use On Error Resume Next statement, because it hides errors, but they still occur.
Hope you can finally code this, or at least, find this answer helpful.
But anyways, you still got a lot to code.

Find and replace values after looking up table

I have a sheet called "Table" where I have the table I'm looking up its A2:B20,
A2:A20 contains numbers in "XX" format these are the numbers I will be looking up.
The B2:B20 part of the table contains text is this text I want to use to replace values with.
I have my main sheet (currently called "Test") which contains my data, I want to look in Column M and check if I can find a value where the first 2 chars match any one of the values in A2:A20, if I do find a match I then want to replace the value of column F on my data sheet (Test) with the corresponding value from B2:B20 if not I want to leave it as is and move on.
I'm running into problems as the data in column M is numbers stored as text and it is replacing the wrong value when the table list 1 or 11 or 2 and 22.
'
Dim MyString As String
Counter = 2
1:
MyString = Sheets("Table").Range("A" & Counter).Value
For X = 1 To Range("M" & Rows.Count).End(xlUp).Row
If Replace(MyString, Left(Sheets("TEST").Range("M" & X).Value, 2), "") <> MyString Then Sheets("TEST").Range("F" & X).Value = Sheets("Table").Range("B" & Counter).Value
Next
Counter = Counter + 1
If Counter <= Range("M" & Rows.Count).End(xlUp).Row Then
GoTo 1:
Else
End If
End Sub
I solved my own problem, I was doing too much - simplified it forces values to .text and my issues went away.
Sub BBK_Name()
'Checks column U for start of data (1st 2 chars)
' if they match an entry in bank table changes entry in column G to match table entry.
'
Dim MyString As String
Counter = 2
1:
MyString = Sheets("Table").Range("A" & Counter).Text
RplcValue = Sheets("Table").Range("B" & Counter).Text
For X = 1 To Range("M" & Rows.Count).End(xlUp).Row
If Left(Sheets("TEST").Range("M" & X).Value, 2) = MyString Then _
Sheets("TEST").Range("F" & X).Value = RplcValue
Next
Counter = Counter + 1
If Counter <= Range("M" & Rows.Count).End(xlUp).Row Then
GoTo 1:
Else
End If
End Sub

Concatenate cell text with up to 100 leading characters of another cell's text

I have two columns of data. Column B has 8 characters of data and begins at row 11. Column C has extensive data and begins at row 11 as well.
I am trying to take the first 8 characters in a cell in column B, combine it with up to 100 characters in column C, and place this combined data into column A. This will loop for the next 200 rows of data.
Sub concat()
For X = 11 To 200
Range("A" & X).Value = Left("B" & X, 8) & Right("C" & X, 100)
Next X
End Sub
Original data:
A B C
testdata SomeExtremelylongtext...
Expected Results:
A B C
testdataSomeExtremelylongtext... testdata SomeExtremelylongtext...
What I get:
A B C
B11C11 testdata SomeExtremelylongtext...
You need to change:
Range("A" & X).Value = Left("B" & X, 8) & Right("C" & X, 100)
to:
Range("A" & X).Value = Left(Range("B" & X), 8) & Right(Range("C" & X), 100)
You are literally finding the left 8 of the text string "B11" and the Right 100 of the text string "C11", when you want the values in the ranges B11 and C11.
And if you want the first 100 characters from "C" then change RIGHT to LEFT
Range("A" & X).Value = Left(Range("B" & X).Value, 8) & Left(Range("C" & X).Value, 100)

Excel VBA code mid function

I have the following string "123 - 456789". What I am trying to do is find a way to only capture the remaining characters after the second space - "456789" - regardless the length of the string.
I have the follow set of code:
For leftLoop = 2 To leftNumberOfCells
Range("A" & iRow) = Split(Range("B" & iRow).Value, " ")
Range("B" & iRow) = Mid("B" & iRow, InStr("B" & iRow, " "), 100)
iRow = iRow + 1
Next leftLoop
The code line "Range("B" & iRow) = Mid("B" & iRow, InStr("B" & iRow, " "), 100)" is what I tried, among other ways (from searching online, but I can't seem to get it to work.
I have two questions:
Does someone know what the correct code should be? and...
Can I reference the cell where the string is located and replace it in that same cell after doing the mid function without having to temporarily put it into another cell and copy and paste it back? For example, my string "123 - 456789" is in cell B2, is there a way to code it so I can reference cell B2 and simultaneous replace the cell B2 with "456789" and not having to place it in another cell then copy and paste it back into B2. I hope you get what i'm asking.
Thanks for you help!
This addresses part 2.
Sub strings()
Dim replace As String
Dim bCell As Range
For leftLoop = 2 To leftNumberOfCells
Set bCell = Range("B" & iRow)
replace = Mid(bCell, InStr(bCell, "-") + 2, 100)
Range("B" & iRow) = replace
iRow = iRow + 1
Next leftLoop
End Sub
Try this:
result = Split(TextToSplit, " ", 3)(2)
Split(TextToSplit, " ", 3) will split the text on spaces, returning a zero-based array. The last argument 3 limits the splitting to 3 portions: before the first space, between the first and second space, and everything else. The (2) at the end of the statement returns the last element of the array.
Hope that helps

Resources