Cleaning VBA needed for Search and Replace - excel

I am new in VBA so i just look for the code online and i modify it for my files.
I would like to know if i can put together the following 2 macros.
It looks for contract number in column AF and then changes the Customer Name (col AN) & Customer Group Name (col AP). can it be donein another way?
I would like to simplify it as later i need, based on Contract Number to change 5 more variables in 5 different columns for other customers.
Sub CorrectCustomerNameXXXX()
Dim LastRow As Long
Dim i As Long
LastRow = Range("AF1000000").End(xlUp).Row
For i = LastRow To 1 Step -1
If Range("AF" & i) = "006-0146157-001" Then
Range("AN" & i).Value = "CUSTOMER_NAME"
End If
Next
End Sub
Sub CorrectCustomerGROUPNameXXXX()
Dim LastRow As Long
Dim i As Long
LastRow = Range("AF1000000").End(xlUp).Row
For i = LastRow To 1 Step -1
If Range("AF" & i) = "006-0146157-001" Then
Range("AP" & i).Value = "CUSTOMER_GROUP"
End If
Next
End Sub
Thanks in advance for your help

Try this code, please. You should use the same iteration:
Sub CorrectWhatever()
Dim LastRow As Long, i As Long
LastRow = Range("AF" & rows.count).End(xlUp).Row
For i = 1 To LastRow
If Range("AF" & i).Value = "006-0146157-001" Then
Range("AN" & i).Value = "CUSTOMER_NAME"
Range("AP" & i).Value = "CUSTOMER_GROUP"
End If
Next
End Sub

Related

Value of counter is not updating in a For Loop

I have data in B Column of an excel file. I have made a loop that If the value in B Cell is greater than a particular (len1) value, then the code puts the Cell (Value-Len1) value in a new cell at the end of the rows.
I increment the counter as lastrow = lastrow+1 everytime when the row is added. Now here is the problem. Iniitially in the input file I had 122 set of data. But by the time the For loop finishes the value of lastrow becomes 160, but the loop exits at 122. WHY?? Any Help will be appreciated.
For i = 1 To lastrow Step 1
If Range("B" & i).Value > len1 Then
Range("A" & lastrow + 1).Value = Range("A" & i).Value
Range("B" & lastrow + 1).Value = Range("B" & i).Value - len1
Range("B" & i).Value = len1
lastrow = lastrow + 1
End If
Next
To get the behaviour you want you need a while loop (or do loop)
i = 1
While i <= lastrow
If Range("B" & i).Value > len1 Then
lastrow = lastrow + 1
Range("A" & lastrow).Value = Range("A" & i).Value
Range("B" & lastrow).Value = Range("B" & i).Value - len1
Range("B" & i).Value = len1
End If
i = i + 1
Wend
I tested it with the sub below:
Sub LoopBeyondLastRow()
Dim i As Long, lastrow As Long, len1 As Long
len1 = 10
With ThisWorkbook.Sheets("Sheet1")
lastrow = .Cells(Rows.Count, "B").End(xlUp).Row
i = 1
While i <= lastrow
If .Range("B" & i).Value > len1 Then
lastrow = lastrow + 1
.Range("A" & lastrow).Value = .Range("A" & i).Value
.Range("B" & lastrow).Value = .Range("B" & i).Value - len1
.Range("B" & i).Value = len1
End If
i = i + 1
Wend
End With
End Sub
Please note the following:
Inside the loop I incremented lastrow first and then used it in the following 2 statements (to reduce the number of addition operations)
In my test code I added With ThisWorkbook.Sheets("Sheet1") to fully qualify all ranges. Not doing this is the source of many bugs that are sometimes very difficult to pinpoint. One should get in the habbit of never to write Range or Cells without a little . before them.
A faster method would be to export the range values to array and then do the comparision. Store the final output into a temp array and write it back to the worksheet.
If you want to follow your approach then is this what you are trying? I have commented the code so you should not have a problem understanding it. Basically you need 2 loops if you want to recheck the data that you are adding at the end of the row.
Option Explicit
Sub Sample()
Dim ws As Worksheet
Dim ComparisionValue As Long
Dim countOfMatchedValues As Long
Dim lRow As Long
Dim i As Long
Dim outputRow As Long
Dim rng As Range
'~~> Change this to the relevant sheet
Set ws = Sheet1
'~~> Change this to the relevant
'~~> comparision value
ComparisionValue = 122
With ws
'~~> Start an indefinite loop
Do
'~~> Find last row
lRow = .Range("A" & .Rows.Count).End(xlUp).Row
'~~> Fix the output row for the new data
outputRow = lRow + 1
'~~> Check if there are any matches for your condition
countOfMatchedValues = Application.WorksheetFunction.CountIf( _
.Range("B1:B" & lRow), ">" & ComparisionValue)
'~~> If not then exit loop
If countOfMatchedValues = 0 Then Exit Do
'~~> Do your stuff
For i = 1 To lRow
If .Range("B" & i).Value > ComparisionValue Then
.Range("A" & outputRow).Value = .Range("A" & i).Value
.Range("B" & outputRow).Value = .Range("B" & i).Value - ComparisionValue
.Range("B" & i).Value = ComparisionValue
outputRow = outputRow + 1
End If
Next i
Loop
End With
End Sub
In Action
for loops use a pre-defined number of iterations. For an unknown number of iterations you need to use a while loop.
Your code uses the value of lastRow at the time it was interpreted, and is never updated again.
This is similar to:
lastRow = 1
Debug.Print lastRow
lastRow = lastRow + 1
Debug.Print lastRow
You will see:
1
2
and not:
2
2
because once the first Debug statement has been executed, changing the value of lastRow doesn't affect this particular output anymore.
Test the next code, please:
Sub TestLoopAddedRowsInclusive()
'..... your code defining LastRow and len1
Dim lastRInit As Long
lastRInit = LastRow
For i = 1 To Rows.count
If Range("B" & i).Value = "" And i >= lastRInit Then Exit For
If Range("B" & i).Value > len1 Then
Range("A" & LastRow + 1).Value = Range("A" & i).Value
Range("B" & LastRow + 1).Value = Range("B" & i).Value - len1
Range("B" & i).Value = len1
LastRow = LastRow + 1
End If
Next
End Sub

Putting a loop inside of an if condition - can it be done?

I'm creating a tool that pulls in data from SQL and then extracts the data depending on dates and users relating to that data. I need this to work in a large range of users.
I have some code that currently has a nested for loop. Using lastrow variables, it checks to see if the value of a cell and the first loop value - for example .range("b" & R) - equals the value of a cell and the second loop value - .range("H" & i). In this, there's an if statement e.g
If the date in range("E"&r) = the date in range("G"&i) and lcase(range("A" & r) = lcase(range("H" & y) then...
I need the value of y to change to basically say if G&i = H&y or H&y and so on until it gets to the end of my range.
Sub mysub(sheet As String)
Dim i As Long
Dim r As Long
Dim y As Long
Dim lastRow As Long
Dim lastRow2 As Long
Dim hours As Single
Dim lastRow3 As Long
Application.ScreenUpdating = False
Sheets(sheet).Activate
lastRow = ActiveSheet.Range("A" & Rows.Count).End(xlUp).Row
lastRow2 = ActiveSheet.Range("AD" & Rows.Count).End(xlUp).Row
lastRow3 = Sheets("mysheet").Range("B" & Rows.Count).End(xlUp).Row
For r = 4 To lastRow2
For i = 2 To lastRow
For y = 2 To lastRow3
If ActiveSheet.Range("E" & i).Value = ActiveSheet.Range("AH" & r) And _
LCase(ActiveSheet.Range("A" & i).Value) = LCase(Sheets("agents").Range("B" & y).Value) Then
hours = hours + ActiveSheet.Range("D" & i).Value
End If
Next y
Next i
ActiveSheet.Range("AE" & r).Value = hours
ActiveSheet.Range("AE" & r).NumberFormat = "[h]:mm"
hours = 0
Next r
Application.ScreenUpdating = True
End Sub
Any help on this would be a massive help.

"Object is required"

I am currently trying to do mathematical operation of adding 3 columns (Y, AA and AB).
But each time running the code, it displays error message of
object is required
Sub QCValue()
Dim Number1 As Range
Dim Number2 As Range
Dim Number3 As Range
Set Number1 = Sheets("RawData").Range("Y2:Y" & Range("A" & Rows.Count).End(xlUp).Row)
Set Number2 = Sheets("RawData").Range("AA2:AA" & Range("A" & Rows.Count).End(xlUp).Row)
Set Number3 = Sheets("RawData").Range("AB2:AB" & Range("A" & Rows.Count).End(xlUp).Row)
Sheets("RawData").Range("AJ2:AJ" & Range("A" & Rows.Count).End(xlUp).Row).Value = Number1 + Number2 + Number3
End Sub
Kindly please assist me in troubleshooting.
You have work a loop for that. Like this below should do the job.
Sub QCValue()
Dim i As Integer
For i = 2 To Range("A" & Rows.Count).End(xlUp).Row
Sheets("RawData").Range("AJ" & i).Value = Sheets("RawData").Range("Y" & i).Value + Sheets("RawData").Range("AA" & i).Value + Sheets("RawData").Range("AB" & i).Value
Next
End Sub
If i have understand correctly you could use:
Code:
Option Explicit
Sub QCValue()
Dim LastRow As Long
With ThisWorkbook.Sheets("RawData")
'Find Last rows of Columns Y
LastRow = .Cells(.Rows.Count, "Y").End(xlUp).Row
.Range("AJ2:AJ" & LastRow).FormulaR1C1 = "=SUM(RC[-11],RC[-9],RC[-8])"
End With
End Sub
Results:

Merge rows into one based on full stop

I have a table in the following format.
all that is
well known for
let be apples.
abs kdjhkj kfhksh sh
kjsfhkshgkh dh.
I want the rows to merge based on the fullstop, whenever a full stop comes, a new row should be created untill next full stop occurs.
example
all that is well known for let be apples.
abs kdjhkj kfhksh sh kjsfhkshgkh dh.
I see we can merge by n number of rows into one using inbuild tools. But I have a huge list, I cannot go around and do that for each set.
Any solution, in code or through excel or libreoffice calc will be helpful.
though I can try macro but not preferring that. Anyways if that is the only way to achieve it then why not.
I think there is no way to archive this with excel function. i try to create a code fulfill your needs:
Code:
Option Explicit
Sub test()
Dim str As String
Dim i As Long, LastRowA As Long, LastRowC As Long
With ThisWorkbook.Worksheets("Sheet1")
LastRowA = .Cells(.Rows.Count, "A").End(xlUp).Row
For i = 1 To LastRowA
If InStr(1, .Range("A" & i).Value, ".") > 0 Then
If str = "" Then
str = .Range("A" & i).Value
Else
str = str & " " & .Range("A" & i).Value
End If
LastRowC = .Cells(.Rows.Count, "C").End(xlUp).Row
If LastRowC = 1 And .Range("C1").Value = "" Then
.Range("C" & LastRowC).Value = str
Else
.Range("C" & LastRowC + 1).Value = str
End If
str = ""
Else
If str = "" Then
str = .Range("A" & i).Value
Else
str = str & " " & .Range("A" & i).Value
End If
End If
Next i
End With
End Sub
Results:
If you just import it in a google drive you can do it with:
=SPLIT(CONCATENATE(A1:A5);".")
You can do it in excel by using concatenate in the same way and then also separating by "." but I do not think you can't split in that way to my knowledge. In any case, in VBA is not a difficult code. But I guess you just want to solve this and you are doing it in excel beceause you don't know how to do it in any other way.
The below code is effective compare to first answer.
Sub Program1()
Dim wb As Workbook
Dim ws As Worksheet
Dim Lastrow As Long
Dim Str1 As String
Set wb = ThisWorkbook
Set ws = wb.Worksheets("Sheet1")
Lastrow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
j = 1
For i = 1 To Lastrow
If InStr(1, ws.Cells(i, 1).Value, ".") > 0 Then
ws.Cells(j, 3).Value = Str1 & ws.Cells(i, 1).Value
j = j + 1
Str1 = ""
Else
Str1 = Str1 & ws.Cells(i, 1).Value
End If
Next
End Sub

Selecting all rows with the same ID number, then iterating - VBA

I have a sorted list of ID's in Excel. I want to grab all the rows with the same ID, then I'll be manipulating them.
Sub Selectingabox()
Dim I As Integer
Dim N As Integer
'Defining
I = 1
N = 1
'Initializing
While I < 3000
'If I have more than 3k rows I'm in serious trouble anyways
If Range("A" & I).Select = Range("A" & I + 1).Select Then
I = I + 1
Else: Range("A" & N, "AJ" & I).Select
'Lots of stuff manipulating the data range we just selected
N = I + 1
'The new top row
I = I + 1
'The new bottom row
Wend
End Sub
Not quite working.. the wend is unhappy with me, and I'm not sure why. Also have no idea if the code will work!
Couple of things:
dim your values as long rather than integer, so you won't get an error at row 32k
Use a FOR loop rather than a while loop to make your code more efficient
Rather then using number 3000 you can use VBA to find the last row automatically using Cells(Rows.Count, "A").End(xlUp).Row
I would not recommend using .Select in your code. What are you trying to manipulate?
Sub Selectingabox()
Dim I As Long
Dim N As Long
Dim lastrow As Long
lastrow = Cells(Rows.Count, "A").End(xlUp).Row
N = 1
For I = 1 To lastrow
If I = lastrow Then
If Range("A" & I).Value <> Range("A" & I - 1).Value Then
Range("A" & N & ":AJ" & I).Select
N = I + 1
End If
Else
If Range("A" & I).Value <> Range("A" & I + 1).Value Then
Range("A" & N & ":AJ" & I).Select
'Lots of stuff manipulating the data range we just selected
N = I + 1
End If
End If
Next I
End Sub
Add an End If into your code - that will resolve the Compile Error
Sub Selectingabox()
Dim I As Integer
Dim N As Integer
'Defining
I = 1
N = 1
'Initializing
While I < 3000
'If I have more than 3k rows I'm in serious trouble anyways
If Range("A" & I).Select = Range("A" & I + 1).Select Then
I = I + 1
Else: Range("A" & N, "AJ" & I).Select
'Lots of stuff manipulating the data range we just selected
N = I + 1
'The new top row
I = I + 1
'The new bottom row
End If ' add this here
Wend
End Sub

Resources