If condition in for loop - excel

Sub NewRefesh()
If Not Range("X2") = "COMPLETE" Or Range("X2") = "CANCELLED" Then
Range("X2").Select
ActiveCell.FormulaR1C1 = "=GetOrderStatus(RC[1])"
End If
End Sub
The above code does for only X2 but i want do it till X52.
(Ex: Next check in X3 = COMPLETE" Or Range("X3") = "CANCELLED" Then
Range("X3").Select
ActiveCell.FormulaR1C1 = "=GetOrderStatus(RC[1])"and do the action, next X4 and so on

I think in your post you meant your criteria to be :
Not Range("X2") = "COMPLETE" >> can be replaced also with Range("X2") <> "COMPLETE"
Not Range("X2") = "CANCELLED" >> can be replaced also with Range("X2") <> "CANCELLED"
Note: it's better to stay away from Select and ActiveCell, instead use referenced Ranges. In your code you code directly use Range("X" & i).FormulaR1C1
Code
Option Explicit
Sub NewRefesh()
Dim i As Long
' simple For loop, you can modify to find last row with data instead of 52
For i = 2 To 52
If (Not Range("X" & i).Value = "COMPLETE") And (Not Range("X" & i).Value = "CANCELLED") Then
Range("X" & i).FormulaR1C1 = "=GetOrderStatus(RC[1])"
End If
Next i
End Sub

use row/col numbering
x is Column number 24
for i = 2 to 52
If Not cells(i,24) = "COMPLETE" Or cells(i,24) = "CANCELLED" Then
Range(i,24).Select
Whatever you want done.........
End If
Next i

Related

Comment Used To Track Changes

I have encountered a few issues with some code in VBA. I am trying to have the changes made to a cells on an excel sheet show up in comments on the cell the change was made to and I wish for these changes to be stored in a list so I can view them all later. I have tried lots of different pieces of code I have found to try and implement it into the code but none have worked.
Any ideas on how to get this to work?
Worksheet
The below code is what I am currently using
Private Sub Worksheet_Change(ByVal Target As Range)
Dim Adding As Boolean, Finding As Boolean, Subtracting As Boolean
Dim f As Range, v
Select Case Target.Address(True, True)
Case "$A$4": Adding = True
Case "$C$4": Subtracting = True
Case "$E$4": Finding = True
Case Else: Exit Sub
End Select
v = Trim(Target.Value)
If Len(v) = 0 Then Exit Sub
Set f = Me.Range("C8").Resize(1000, 1).Find(v, lookat:=xlWhole)
If Adding Then
If f Is Nothing Then
'not found: add as new row
Set f = Me.Cells(Rows.Count, 3).End(xlUp).Offset(1, 0)
f.Value = v
End If
f.Offset(0, 1).Value = f.Offset(0, 1).Value + 1
doDate f.Offset(0, 2)
Target.Value = ""
ElseIf Subtracting Then
If f Is Nothing Then
MsgBox v & " not found for subtraction!"
Else
f.Offset(0, 1).Value = f.Offset(0, 1).Value - 1
doDate f.Offset(0, 3)
Target.Value = ""
End If
Else 'finding
If Not f Is Nothing Then
f.EntireRow.Select
Target.Value = ""
Else
MsgBox v & " not found."
End If
End If
If Adding Or Subtracting Then Target.Select
End Sub
Sub doDate(c As Range)
With c
.NumberFormat = "m/d/yyyy h:mm AM/PM"
.Value = Now
End With
End Sub
I have implemented a few formulas on the worksheet but don't see any reason why it would matter in this situation since they only track quantity of items with the same unique identifier.
I also tried some code that added comments to the cells as they were changed that worked but always returned the previous cell value as blank. It is not actually added into the current code though.
Option Explicit
Public preValue As Variant
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Count > 1 Then Exit Sub
Target.ClearComments
Target.AddComment.Text Text:="Previous Value was " & preValue & Chr(10) & "Revised " & Format(Date, "mm-dd-yyyy") & Chr(10) & "By " & Environ("UserName")
End Sub
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Target.Count > 1 Then Exit Sub
If Target = "" Then
preValue = "a blank"
Else: preValue = Target.Value
End If
End Sub
By and large, the code below should do what you want. I marveled at your use of A4 and C4 to express addition and subtraction. As it is, whatever you change in those two cells, apart from clearing them, will result in a quantity of 1 being added or subtracted. I would have expected that a quantity must be entered there which is processed. If the quantity is fixed at 1 the system appears too elaborate.
Anyway, here's the code. I guess you'll be able to modify it to better suit your needs.
Private Sub Worksheet_Change(ByVal Target As Range)
' 038
Dim LookUp As Variant ' subject
Dim Action As Variant ' add = 1, subtract = -1, find = 2
Dim Fnd As Range ' Result of Find method
Dim Txt As String ' comment text
With Target
If (.Row <> 4) Or (.CountLarge > 1) Then Exit Sub
LookUp = Cells(4, "E").Value
On Error Resume Next
Action = Array(0, 1, 0, -1, 0, 2)(.Column)
End With
If Action And (LookUp <> "") Then
' C8 to end of column C
With Range(Cells(8, "C"), Cells(Rows.Count, "C").End(xlUp))
Set Fnd = .Find(LookUp, .Cells(.Cells.Count), xlValues, xlWhole, xlByRows)
End With
End If
If Fnd Is Nothing Then
Select Case Action
Case -1
MsgBox """" & LookUp & """ not found.", vbInformation, "Can't subtract"
Action = -2
Case 2
MsgBox """" & LookUp & """ not found.", vbInformation, "No record"
Action = -2
Case Else
Set Fnd = Cells(Rows.Count, "C").End(xlUp).Offset(1)
Fnd.Value = LookUp
End Select
End If
With Fnd
If Abs(Action) <> 2 Then
With .Offset(0, 1)
If .Comment Is Nothing Then
.AddComment
Else
Txt = Chr(10)
End If
Txt = "Previous Qty = " & .Value & Chr(10) & _
"Revised " & Format(Date, "mm-dd-yyyy") & Chr(10) & _
"by " & Environ("UserName") & Txt
.Comment.Text Txt, 1, False
.Value = Val(.Value) + Action
With .Offset(0, 2)
.NumberFormat = "m/d/yyyy h:mm AM/PM"
.Value = Now
End With
End With
ElseIf Action = 2 Then
.EntireRow.Select
End If
End With
If Action <> 2 Then Target.Select
End Sub

Excel VBA script not working when grouping multiple levels

I have an excel document that runs a VBA script that I use user forms to input data. The script works fine, except for the grouping. There are 2 groups. The first is at the Customer Name, which works fine. The second is at the Effort Name, which does not. It groups the effort, but when grouped it still displays the last row. The developer I hired to write the script said that this error appears to be a bug in Excel or for some reason by design when two groups have the same last row.
Does anyone have a solution?
Images show the macros script and grouping Image of marcos
Image of grouping
Below is the VBA script that was written for creating the effort via user form.
Private Sub ButtonAddEffort_Click()
Dim c As Object
Dim sht As Worksheet
Dim foundrow As Long
Dim blassign As Boolean
Dim x As Long
Dim rowstart As Long
Dim rowend As Long
Dim i As Long
Dim rowstarteffort As Long
If IsNull(Me.txtProjectNumberLocate) Or Me.txtProjectNumberLocate = "" Then
MsgBox "Please enter a project number."
Me.txtProjectNumberLocate.SetFocus
Exit Sub
End If
If IsNull(Me.txtEffortName) Or Me.txtEffortName = "" Then
MsgBox "Please enter an effort name."
Me.txtEffortName.SetFocus
Exit Sub
End If
If Not IsNull(Me.txtStartDate) And Me.txtStartDate <> "" Then
If Not IsDate(Me.txtStartDate) Then
MsgBox "Please enter a valid start date in 'mm/dd/yyyy' format."
Me.txtStartDate.SetFocus
Exit Sub
End If
End If
If Not IsNull(Me.txtFinishDate) And Me.txtFinishDate <> "" Then
If Not IsDate(Me.txtFinishDate) Then
MsgBox "Please enter a valid finish date in 'mm/dd/yyyy' format."
Me.txtFinishDate.SetFocus
Exit Sub
End If
End If
Set sht = Sheets("Sheet1")
Set c = sht.Range("F:F").Find(what:=Me.txtProjectNumberLocate, after:=sht.Cells(1, 6), LookIn:=xlValues, lookat:=xlWhole, searchorder:=xlByRows, searchdirection:=xlPrevious, MatchCase:=False)
If Not c Is Nothing Then
foundrow = c.Row
rowstart = foundrow
rowstarteffort = foundrow
Else
foundrow = 0
End If
If foundrow = 0 Then
MsgBox "Could not find project # " & Me.txtProjectNumberLocate
Exit Sub
End If
''any efforts exist1
Set c = sht.Range("A:A").Find(what:="*", after:=sht.Cells(foundrow, 1), LookIn:=xlValues, lookat:=xlPart, searchorder:=xlByRows, searchdirection:=xlNext, MatchCase:=False)
If Not c Is Nothing Then
foundrownext = c.Row
Else
foundrownext = 0
End If
If foundrownext > foundrow Then
foundrow = foundrownext - 1
End If
'check work order format
For x = 1 To 8
If Not IsNull(Me("txtworkorder" & x)) And Me("Txtworkorder" & x) <> "" Then
If Me("CheckBox" & x) = True Then
If Len(Me("txtWorkOrder" & x)) <> 8 Then
MsgBox "Work order numbers must be in 'xxxx-xxx' format."
Me("txtWorkOrder" & x).SetFocus
Exit Sub
End If
If InStr(1, Me("txtWorkOrder" & x), "-") = 0 Then
MsgBox "Work order numbers must be in 'xxxx-xxx' format."
Me("txtWorkOrder" & x).SetFocus
Exit Sub
End If
If Mid(Me("txtworkorder" & x), 5, 1) <> "-" Then
MsgBox "Work order numbers must be in 'xxxx-xxx' format."
Me("txtWorkOrder" & x).SetFocus
Exit Sub
End If
If InStr(1, Left(Me("txtWorkOrder" & x), 4), "-") <> 0 Then
MsgBox "Work order numbers must be in 'xxxx-xxx' format."
Me("txtWorkOrder" & x).SetFocus
Exit Sub
End If
If InStr(1, Right(Me("txtWorkOrder" & x), 3), "-") <> 0 Then
MsgBox "Work order numbers must be in 'xxxx-xxx' format."
Me("txtWorkOrder" & x).SetFocus
Exit Sub
End If
End If
End If
Next x
i = 0
If foundrownext > 1 Then
sht.Rows(rowstart + 1 & ":" & foundrownext - 1).Select
On Error Resume Next
Selection.Rows.Ungroup
On Error GoTo 0
End If
blassign = False
For x = 8 To 1 Step -1
If Me("CheckBox" & x) = True Then
blassign = True
End If
Next x
If blassign = False Then
sht.Range(foundrow + 1 & ":" & foundrow + 1).EntireRow.Insert shift:=xlDown
sht.Range("B" & foundrow + 1) = Me.txtEffortName
sht.Range("B" & foundrow + 1).Font.Color = 13998939
sht.Range("B" & foundrow + 1).Font.Underline = True
sht.Range("I" & foundrow + 1) = Me.txtStartDate
sht.Range("J" & foundrow + 1) = Me.txtFinishDate
i = 1
Else
sht.Range(foundrow + 1 & ":" & foundrow + 1).EntireRow.Insert shift:=xlDown
sht.Range("B" & foundrow + 1) = Me.txtEffortName
sht.Range("B" & foundrow + 1).Font.Color = 13998939
sht.Range("B" & foundrow + 1).Font.Underline = True
sht.Range("I" & foundrow + 1) = Me.txtStartDate
sht.Range("J" & foundrow + 1) = Me.txtFinishDate
For x = 8 To 1 Step -1
If Me("CheckBox" & x) = True Then
sht.Range(foundrow + 2 & ":" & foundrow + 2).EntireRow.Insert shift:=xlDown
sht.Range("F" & foundrow + 2) = Me("txtWorkOrder" & x)
sht.Range("G" & foundrow + 2) = Me("cmbAssign" & x)
i = i + 1
End If
Next x
End If
''group new efforts
If foundrownext <= 1 Then
foundrownext = rowstart + 1
End If
sht.Rows(foundrow + 2 & ":" & foundrownext + i).Select
Selection.Rows.Group
''ungroup and group old project data
rowend = foundrownext + i - 1
sht.Rows(rowstart + 1 & ":" & rowend).Select
Selection.Rows.Group
''
MsgBox "Done!"
End Sub
Private Sub ButtonClose_Click()
Unload Me
End Sub
Private Sub ComboBox1_Change()
End Sub
Private Sub ComboBox2_Change()
End Sub
Private Sub ComboBox3_Change()
End Sub
Private Sub ComboBox4_Change()
End Sub
Private Sub TextBox9_Change()
End Sub
Private Sub UserForm_Click()
End Sub
Outline (group) in Excel requires a summary row, that depending on the settings you have in your computer, should be placed below (default) or above each outline level.
Your situation
What's happening in your spreadsheet is that you currently have the default settings, i.e. summary row should be below the current outline level. And you're grouping the rows 9,10 and 13.
My guess here is that the developer tried to group effort 1 and effort 2 and it didn't work, because to group effort 2 without leaving an additional row would just look like this:
Note: See the 4 dots on the right of rows 13 to 16
The Excel solution
In this case, you need to toggle the settings so the summary rows are above the detail
How to adjust the settings
Outline settings:
Current configuration:
Adjusted configuration
This would allow to have the summary row above details like this:
And when collapsed:
The VBA solution
Now, about the VBA code you have, although it can certainly be improved, I understand it accomplishes your requirements.
I suggest to specially check these two blocks:
Block # 1:
''group new efforts
If foundrownext <= 1 Then
foundrownext = rowstart + 1
End If
sht.Rows(foundrow + 2 & ":" & foundrownext + i).Select
Selection.Rows.Group
Block #2
''ungroup and group old project data
rowend = foundrownext + i - 1
sht.Rows(rowstart + 1 & ":" & rowend).Select
Selection.Rows.Group
I'd suggest the developer to read this article on how and why to avoid select in Excel VBA.
Please let me know if the solution works and remember to mark the answer (tick the check mark at the left) if it does.

VBA: How to pop up a messagebox when activecell.value having a division error

How to set up a message box popup when an active cell value is #DIV/0!
Dim GP
GP = "=(" & "Sheet1_Revenue!" & INR1Value & "-" & "Sheet2_Cost!" & INR2Value & ")/" & "Sheet1_Revenue!" & INR1Value
Sheets("Sheet2_Cost").Cells(I + 3, J).Select
ActiveCell = GP
Selection.NumberFormat = "0.00%"
With Selection.Interior
.Color = 65535
End With
If ActiveCell.Value = "#DIV/0!" Then
MsgBox "Not an Error: Kindly feed INR values under Sheet1_Revenue"
End If
I tried If ActiveCell.Value = as well as If GP.Value = but both are not working please help me to understand how to resolve this issue.
Thanks in Advance
Replace:
If ActiveCell.Value = "#DIV/0!" Then
with:
If ActiveCell.Text = "#DIV/0!" Then
Say we start with:
This code:
Sub ErrorGrabber()
MsgBox ActiveCell.Value
End Sub
will produce:
but this code:
Sub ErrorGrabber()
MsgBox ActiveCell.Text
End Sub
will produce:
The Excel shows you the value "#DIV/0!" when your are divide a number into Zero.... but this value isn't a string....
your if-statement should be in the main part of programming like this example
dim a as single, b as single, ans ans single
if b = 0 then
msgbox "...."
else
ans = a / b
end if
To "trap" a "#DIV/0!" is a 2-step code:
If IsError(ActiveCell.Value) Then ' first check if cells contains an error
If ActiveCell.Value = CVErr(xlErrDiv0) Then ' check the type of error
MsgBox "Not an Error: Kindly feed INR values under Sheet1_Revenue"
End If
End If
However, I think the best method is to check the value of the value of the Divisor, before performing the division.
Note: there is no need to use ActiveCell, you can run your code directly on the fully qualified Range:
With Sheets("Sheet2_Cost").Cells(I + 3, J)
.Value = GP
.NumberFormat = "0.00%"
With .Interior
.Color = 65535
End With
End With

WorksheetChange Event to Concatenate Row and First Letter of First Name + First Letter of Last Name

I think the code should be something like this, but I'm getting an error on this line where I am trying to handle the first and last names. Basically, I want to create a code in Column A, which is the first letter of the person's first name and first letter of the person's last name, concatenated with the row number. The row will be the active row (always Column A) and the first and last names will be stored in Column B.
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Column <> 1 Then Exit Sub
On Error GoTo ErrHandler
Application.EnableEvents = False
If Target.Column = 1 Then
Target.Offset(0, 0).FormulaR1C1 = "=ROW()"
TV1 = Target.Offset(0, 0).FormulaR1C1
Target.Offset(0, 0).FormulaR1C1 = "=UPPER(LEFT(R[" & "=ROW()" & "]C[1],1)&MID(R[" & "=ROW()" & "]C[1],FIND("" "",R[" & "=ROW()" & "]C[1],1)+1,1))"
TV2 = Target.Offset(0, 0).FormulaR1C1
Target.Offset(0, 0).Value = TV2 & "-" & TV1
End If
End Sub
I don't like to avoid dealing with more than a single cell as the Target. It isn't hard to deal with multiple cells.
After disabling events and performing your processing, you are not turning them back on again. You code will only run once without manually turning events back on.
If you are putting first and last names into column B, shouldn't the processing be subject to column B and not column A?
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Columns("B")) Is Nothing Then
On Error GoTo ErrHandler
Application.EnableEvents = False
Dim trgt As Range
For Each trgt In Intersect(Target, Target.Parent.UsedRange, Columns("B"))
trgt = StrConv(Trim(trgt.Value2), vbProperCase)
If CBool(InStr(2, trgt.Value2, Chr(32))) Then
trgt.Offset(0, -1) = _
UCase(Left(trgt.Value2, 1)) & _
UCase(Mid(trgt.Value2, InStr(1, trgt.Value2, Chr(32)) + 1, 1)) & _
Format(trgt.Row, "000")
End If
Next trgt
End If
ErrHandler:
Application.EnableEvents = True
End Sub
I've added some trim and proper-case conversion to auto-correct the values being typed into column B.
In the following image, I copied the names from G5:G8 and pasted them into B2:B5.
I would do this differently. Why write formulas when you can do it simply in VBA?
I've made some annotations to your original code also:
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Column <> 1 Then Exit Sub
Application.EnableEvents = False
' No error handler in your code
'On Error GoTo ErrHandler
' don't need to check if column 1 since we already did that and exited the sub if it was not
' If Target.Column = 1 Then
'Target.Offset(0,0) = Target
'Target.Offset(0, 0).FormulaR1C1 = "=ROW()"
'TV1 = Target.Offset(0, 0).FormulaR1C1
'Target.Offset(0, 0).FormulaR1C1 = "=UPPER(LEFT(R[" & "=ROW()" & "]C[1],1)&MID(R[" & "=ROW()" & "]C[1],FIND("" "",R[" & "=ROW()" & "]C[1],1)+1,1))"
'TV2 = Target.Offset(0, 0).FormulaR1C1
'Target.Offset(0, 0).Value = TV2 & "-" & TV1
'Just do the creation in VB
With Target
.Value = .Row & Left(.Offset(0, 1), 1) & Left(Split(.Offset(0, 1))(1), 1)
End With
'If you have more than two space-separated words in the name, then something like
Dim V As Variant
With Target
V = Split(.Offset(0, 1))
.Value = .Row & Left(V(0), 1) & Left(V(UBound(V)), 1)
End With
'Don't forget to reenable events
Application.EnableEvents = True
End Sub
Also, since the names are in Column B, why are you testing for a change in Column A? There could be reasons, but if there are not, it might be smoother to check for changes in column B.
I figured it out!!
If Target.Column = 1 Then
Target.Offset(0, 0).FormulaR1C1 = "=ROW()"
TV1 = Target.Value
Target.Offset(0, 0).FormulaR1C1 = "=UPPER(LEFT(RC[1],1)&MID(RC[1],FIND("" "",RC[1],1)+1,1))"
TV2 = Target.Value
Target.Value = TV2 & "-" & TV1
End If

How to optimize Macro Code That Looks into 2 Worksheets

Problem:
I have 1 Excel Sheet with 2 tabs
Tab 1 = Shipment Package
Tab 2 = Mass Update Steps
I want to go through all the values in column B of Tab 2 one by one.
As I go through each row in Tab 2, I will select and copy the values in column C and D of Tab 2.
After selecting and copying, I want to find Tab 2-column B's corresponding values in Tab 1 column G.
If a match is found, I will select column E of Tab 1 (in row where the match was found), and paste there the values copied from Tab 2.
So far this is the code I have which works. However the values from being searched are hard coded. With the values growing in number in Tab 2, the code is hard to maintain. I would like to optimize it. I have googled several possible solutions. But I keep on getting these run-time errors when declaring or setting the range for the 2 sheets. Here is my code.
Private Sub btn_Updt_Steps_Click()
Dim lastRow As Long
With Sheets("Shipment Package")
.Activate
lastRow = .Range("G65000").End(xlUp).Row
For i = 1 To lastRow
If (InStr(1, .Range("G" & i).Value, "Code 001", vbTextCompare) > 0) Then
Sheets("Mass Update Steps").Activate
ActiveSheet.Range("C4:D4").Select
Selection.Copy
Sheets("Shipment Package").Activate
.Range("E" & i).Select
ActiveSheet.Paste
ElseIf (InStr(1, .Range("G" & i).Value, "Code 002", vbTextCompare) > 0) Then
Sheets("Mass Update Steps").Activate
ActiveSheet.Range("C5:D5").Select
Selection.Copy
Sheets("Shipment Package").Activate
.Range("E" & i).Select
ActiveSheet.Paste
ElseIf (InStr(1, .Range("G" & i).Value, "Code 003", vbTextCompare) > 0) Then
Sheets("Mass Update Steps").Activate
ActiveSheet.Range("C6:D6").Select
Selection.Copy
Sheets("Shipment Package").Activate
.Range("E" & i).Select
ActiveSheet.Paste
End If
Next
End With
NotFoundErr:
Debug.Print "value not found"
End Sub
Solution:
Private Sub btn_Updt_Steps_Click()
Dim i As Long
Dim j As Long
Dim Tab2ColC As String
Dim Tab2ColD As String
Dim Tab1ColE As String
Dim Tab1ColF As String
Tab1 = "Shipment Package"
Tab2 = "Mass Update Steps"
With Worksheets(Tab1)
LastRowTab1 = .Cells(.Rows.Count, "G").End(xlUp).Row 'LastRowInColumn(2, Tab1)
End With
With Worksheets(Tab2)
LastRowTab2 = .Cells(.Rows.Count, "B").End(xlUp).Row 'LastRowInColumn(2, Tab2)
End With
For i = 4 To LastRowTab2
Tab2ColumnB = Trim(Sheets(Tab2).Range("B" & i).Value)
Sheets(Tab2).Activate
If Tab2ColumnB <> "" Then
Tab2ColC = "C" & i
Tab2ColD = "D" & i
ActiveSheet.Range(Tab2ColC, Tab2ColD).Copy
For j = 16 To LastRowTab1
Tab1ColumnG = Trim(Sheets(Tab1).Range("G" & j).Value)
If Tab1ColumnG = Tab2ColumnB Then
Sheets(Tab1).Activate
Tab1ColE = "E" & j
Tab1ColF = "F" & j
Sheets(Tab1).Range(Tab1ColE, Tab1ColF).Select
ActiveSheet.Paste
End If
Next
End If
Next
End Sub
For optimization, you can avoid select statements, activate statements etc. Check the code below.
For i = 1 To lastRow
Application.ScreenUpdating = False
If YourCondn1 Then
Sheets("Mass Update Steps").Range("C4:D4").Copy
Sheets("Shipment Package").Range("E" & i).PasteSpecial xlPasteAll
ElseIf YourCondn2 Then
Sheets("Mass Update Steps").Range("C5:D5").Copy
Sheets("Shipment Package").Range("E" & i).PasteSpecial xlPasteAll
ElseIf YourCondn3 Then
Sheets("Mass Update Steps").Range("C6:D6").Copy
Sheets("Shipment Package").Range("E" & i).PasteSpecial xlPasteAll
End If
Application.ScreenUpdating = True
Next
Adding the code that you require. Hope this will work. I haven't tested it. Please check.
Private Sub btn_Updt_Steps_Click()
'Finding LastRow in Tab 2
Tab1 = "Shipment Package"
Tab2 = "Mass Update Steps"
With Worksheets(Tab2)
LastRowTab2 = .Cells(.Rows.Count, 2).End(xlUp).Row 'LastRowInColumn(2, Tab2)
End With
MatchFound = 0
For i = 1 To LastRowTab2
'checking whether value in tab2 column b is same as tab1 column g
Tab2ColumnB = Trim(Sheets(Tab2).Range("B" & i).Value)
Tab1ColumnG = Trim(Sheets(Tab1).Range("G" & i).Value)
If Tab2ColumnB = Tab1ColumnG Then
Tab2ColumnC = Trim(Sheets(Tab2).Range("C" & i).Value)
Tab2ColumnD = Trim(Sheets(Tab2).Range("D" & i).Value)
Sheets(Tab1).Range("E" & i).Value = Tab2ColumnC
Sheets(Tab1).Range("F" & i).Value = Tab2ColumnD
MatchFound = MatchFound + 1
End If
Next
If MatchFound = 0 Then
MsgBox "No matches found"
ElseIf MatchFound > 0 Then
MsgBox MatchFound & " matches were found."
End If
End Sub
I think you can achieve what you want with simple Excel formulas.
In Shipment Package, type the following into E1 and F1 and then drag formula down:
E1 = VLOOKUP(G1,'Mass Update Steps'!$B$1:$D$20,2,0)
F1 = VLOOKUP(G1,'Mass Update Steps'!$B$1:$D$20,3,0)
NB - you'll need to amend $B$1:$D$20 depending on how much data you have in Mass Update
Finally, this assumes that there is always a match. If not, and you want to get rid of those pesky #N/A values, then update the formuals with ISNA e.g.
E1 = IF(ISNA(VLOOKUP(G1,'Mass Update Steps'!$B$1:$D$4,2,0)),"",VLOOKUP(G1,'Mass Update Steps'!$B$1:$D$4,2,0))
Hope that helps.

Resources