I have some calculations I need to do on a data-set. The calculations are simple (i.e input 1 x input 2 = output), but they take inputs recorded in two different excel workbooks by different people. Due to the different input sources the parameters between the two are sometimes in different orders or with slightly different names - the picture attached should show what I mean.
My plan was to take the relevant sheet of input book 1, and the relevant sheet of input book 2, and copy them into a single workbook where i hope to match the parameters with some sort of lookup/find macro, and perform the calculations automatically using a loop to work across the headers and down the rows
combined worksheet concept
Would really appreciate any help.
Even if you look less interested than me to solve this problem, I prepared the next code with the assumption that the array obtained from the the string "apple,banana,orange,grape" covers both sheets strange style head of columns naming.
I used "X1" for your first sheet name, "X2" for the second one and "Result" for the one matching values of the first two:
Sub MatchingLike_bis()
Dim arrNames As Variant, sh1 As Worksheet, sh2 As Worksheet, sRez As Worksheet
Dim lastR1 As Long, lastR2 As Long, arrRez As Variant, arr1 As Variant, arr2 As Variant
Dim i1 As Long, i2 As Long, El As Variant, k As Long, col1 As Long, col2 As Long
Dim strProbl1 As String, strProbl2 As String, colTot As Long, boolF As Boolean, i As Long
arrNames = Split("apple,banana,orange,grape,lemon", ",")
colTot = UBound(arrNames) + 2 'The array is zero based and A is excepted
Set sh1 = ThisWorkbook.Sheets("X1")
Set sh2 = ThisWorkbook.Sheets("X2")
Set sRez = ThisWorkbook.Sheets("Result")
lastR1 = sh1.Range("A" & sh1.Rows.count).End(xlUp).Row
lastR2 = sh2.Range("A" & sh2.Rows.count).End(xlUp).Row
arr1 = sh1.Range(sh1.Cells(1, 1), sh1.Cells(lastR1, colTot)).Value
arr2 = sh2.Range(sh2.Cells(1, 1), sh2.Cells(lastR1, colTot)).Value
'preliminary check if all fruits name has a corespondent in both necessary sheets:__________
strProbl1 = "": strProbl2 = ""
For Each El In arrNames
For i1 = 2 To colTot 'make checking in first sheet
If InStr(UCase(arr1(1, i1)), UCase(El)) > 0 Then
boolF = True: Exit For
End If
Next i1
If Not boolF Then strProbl1 = strProbl1 & El & vbCrLf
boolF = False
For i2 = 2 To colTot 'make checking in the second sheet
If InStr(UCase(arr2(1, i2)), UCase(El)) > 0 Then
boolF = True: Exit For
End If
Next i2
If Not boolF Then strProbl2 = strProbl2 & El & vbCrLf
boolF = False
Next
If strProbl1 <> "" Then MsgBox "In " & sh1.Name & " sheet, the next fruit names are" & _
" incorrect, or missing:" & vbCrLf & _
vbCrLf & strProbl1 & vbCrLf & "Please correct the spelling and run the application again!", _
vbInformation, "Wrong spelling in " & sh1.Name & " worksheet": sh1.Activate: Exit Sub
If strProbl2 <> "" Then MsgBox "In " & sh2.Name & " sheet, the next fruit names are" & _
" incorrect, or missing:" & vbCrLf & _
vbCrLf & strProbl2 & vbCrLf & "Please correct the spelling and run the application again!", _
vbInformation, "Wrong spelling in " & sh2.Name & " worksheet": sh2.Activate: Exit Sub
'_________________________________________________________________________________________________
ReDim arrRez(1 To UBound(arr1, 1), 1 To colTot) 'result array will have exactly the
'number of rows and columns as arr1
For i1 = 1 To UBound(arr1, 1)
If i1 = 1 Then
arrRez(i1, 1) = Empty
For i = 2 To colTot
arrRez(i1, i) = arr1(i1, i)
Next i
Else
For i2 = 1 To UBound(arr2, 1)
If arr1(i1, 1) = arr2(i2, 1) Then
arrRez(i1, 1) = arr1(i1, 1)
'find the right reference in the accepted keys array:
For Each El In arrNames
For k = 2 To colTot
If InStr(UCase(arr1(1, k)), UCase(El)) > 0 Then col1 = k
If InStr(UCase(arr2(1, k)), UCase(El)) > 0 Then col2 = k
Next k
If col1 > 0 And col2 > 0 Then
arrRez(i1, col1) = arr1(i1, col1) + arr2(i2, col2)
col1 = 0: col2 = 0
End If
Next
End If
Next i2
End If
Next i1
With sRez.Range(sRez.Range("A1"), sRez.Cells(lastR1, colTot))
.Value = arrRez
.EntireColumn.AutoFit
End With
End Sub
This version allows adding of a new fruit name in the string "apple,banana,orange,grape,lemon" (I already added lemon) and the code adapts itself to return as many columns as necessary. It makes a preliminary check and sends relevant messages for fruit names wrongly spelled in both input sheets. The code will completely run only if all the fruit names are matched in both input sheets...
Related
I have an excel with 2 columns,say 10 values each as given in the below diagram. The 10 values in A and B are added in a drop down in column E and column F. I want the column D, "Result", to show me 100 different possible permutations of the values again in a drop down. I tried to write a macro but getting lost somewhere. EDIT: Added the error that i am getting. any help is greatly appreciated. Example of what is expected (remember column E and F are dropdowns)
Below is the macro i have tried:
Sub Combination()
Dim arr1 As Variant
Dim arr2 As Variant
Dim i As Long, j As Long, k As Long
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets("Sheet1")
arr1 = ws.Range("E1", ws.Range("E" & ws.Rows.Count).End(xlUp).Row).Value
arr2 = ws.Range("F1", ws.Range("F" & ws.Rows.Count).End(xlUp).Row).Value
ws.Range("D1").Value = "Result"
k = 1
For i = LBound(arr1, 1) To UBound(arr1, 1)
For j = LBound(arr2, 1) To UBound(arr2, 1)
ws.Range("D" & k + 1).Value = arr1(i, 1) & ", " & arr2(j, 1)
k = k + 1
If k = 101 Then Exit For
Next j
If k = 101 Then Exit For
Next i
End Sub
Debugger shows an error in this line of code:
arr1 = ws.Range("E1", ws.Range("E" & ws.Rows.Count).End(xlUp).Row).Value
How else am i supposed to read the values in the drop down?
This task doesn't necessarily require a VBA solution: it is achievable using dynamic spreadsheet functions (if you have a relatively recent version of Excel). To my mind, people reach for VBA too readily, when it would be better to exhaust the possibilities of spreadsheet functions first.
1. Calculate the permutations
Put this formula in cell H2:
=LET(a,A2:A11,b,B2:B10,na,ROWS(a),nb,ROWS(b),s,SEQUENCE(na*nb,,0),INDEX(a,1+(INT(s/nb))) & "," & INDEX(b,1+MOD(s,nb)))
2. Set the Data Validation:
Note the # on the end of the $D$2# reference for Source. This tells Excel that the reference is to a dynamic array.
If you don't want the intermediate column displayed, then it can be Hidden or even put on another tab. Currently Excel only allows relatively simple formulae for Data Validation ranges, otherwise this column would not be needed.
Display the selections for Options A & B:
Cell E2 has the formula =LEFT(D2,FIND(",",D2)-1)
Cell F2 has the formula =RIGHT(D2,LEN(D2)-LEN(E2)-1)
You can use MATCH() to recover the index of the option in input list if required, eg =MATCH(E2,A2:A11,0) if that is needed.
Notes:
Using spreadsheet formulae rather than VBA has three benefits:
The sheet can still be saved and shared as a .xlsx file and not
.xlsm, so reducing the number of security warnings;
It is easier to see the results and test;
The sheet will update automatically (if calculation is set to Automatic), whereas a VBA macro would have to be re-run.
EDIT: An alternative, slightly more complicated formula for H2 could be:
=LET(optA,A2,optB,B2,colA,A:A,colB,B:B,
rngA,INDEX(colA,ROW(optA),,1):INDEX(colA,COUNTA(colA),ROW(optA)-1),
rngB,INDEX(colB,ROW(optB),,1):INDEX(colB,COUNTA(colB),ROW(optB)-1),
na,ROWS(rngA),nb,ROWS(rngB),s,SEQUENCE(na*nb,,0),
INDEX(rngA,1+(INT(s/nb))) & "," & INDEX(rngB,1+MOD(s,nb)))
This would handle changes to size of the Option A and Option B columns. An even more adaptive formula could use INDIRECT(), but I am against that on principle!
Answering my own question:
Wrote Macro 1:
Sub Combination1()
Dim arr1 As Variant
Dim arr2 As Variant
Dim i As Long, j As Long, k As Long
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets("Sheet1")
arr1 = ws.Range("E1", ws.Range("E" & ws.Rows.Count).End(xlUp)).SpecialCells(xlCellTypeConstants).Value
arr2 = ws.Range("F1", ws.Range("F" & ws.Rows.Count).End(xlUp)).SpecialCells(xlCellTypeConstants).Value
ws.Range("D1").Value = "Result"
k = 1
For i = LBound(arr1, 1) To UBound(arr1, 1)
For j = LBound(arr2, 1) To UBound(arr2, 1)
ws.Range("D" & k + 1).Value = arr1(i, 1) & ", " & arr2(j, 1)
k = k + 1
If k = 101 Then Exit For
Next j
If k = 101 Then Exit For
Next i
' Add data validation to column D
With ws.Range("D2", ws.Range("D" & k).End(xlUp))
.Validation.Delete
.Validation.Add Type:=xlValidateList, Formula1:="=" & ws.Range("D2:D" & k).Address
End With
End Sub
This basically reads the values from drop downs.
Macro 2:
Sub Combination2()
Dim arr3 As Variant
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets("Sheet1")
arr3 = ws.Range("D2", ws.Range("D" & ws.Rows.Count).End(xlUp)).SpecialCells(xlCellTypeConstants).Value
ws.Range("G1").Value = "Result"
For i = LBound(arr3, 1) To UBound(arr3, 1)
ws.Range("G" & i + 1).Value = arr3(i, 1)
Next i
' Add data validation to column G
With ws.Range("G2")
.Validation.Delete
.Validation.Add Type:=xlValidateList, Formula1:="=" & ws.Range("D2:D" & UBound(arr3, 1) + 1).Address
End With
' Clear values in column G except for cell G2
ws.Range("G3", ws.Range("G" & ws.Rows.Count).End(xlUp)).ClearContents
End Sub
This helps to populate the values in another dropdown
Macro 3:
Sub CombinedMacros()
Call Combination1
Call Combination2
End Sub
Happy to "help" people if they have any doubts.
I have two sheets in my excel workbook.
Contained in these sheets are my primary key columns.
I want to compare the first column (which is the master) to the second column (source) using a VBA loop.
The reason is because the source usually contains new primary keys.
Please can anyone be kind enough to help me figure out a logic to compare these columns and add the unique values to the master column.
Thank you.
this image shows the sample master code
this image shows the sample source code
The code below shows what I have so far
Sub PullUniques()
Dim rngCell As Range
For Each rngCell In Sheet1.Range("W3:W40")
If WorksheetFunction.CountIf(Range("D3:D40"), rngCell) = 0 Then
Range("C" & Rows.Count).End(xlUp).Offset(1) = rngCell
End If
Next
For Each rngCell In Sheet6.Range("D3:D40")
If WorksheetFunction.CountIf(Range("W3:W40"), rngCell) = 0 Then
Range("W" & Rows.Count).End(xlUp).Offset(1) = rngCell
End If
Next
End Sub
Try this code, please. It is based on the assumption that in source sheet there could be keys not existing in your "Master" sheet, which will be add on the first empty row of the master sheet.
Sub testMasterUpdate()
Dim shM As Worksheet, shS As Worksheet, s As Long, boolF As Boolean
Dim lastRM As Long, lastRS As Long, m As Long
Dim arrM As Variant, arrS As Variant, arrDif As Variant, d As Long
Set shM = Worksheets("Master") 'please, use here your sheet name
Set shS = Worksheets("Source") 'please, use here your sheet name
lastRM = shM.Range("A" & Cells.Rows.Count).End(xlUp).Row
lastRS = shS.Range("A" & Cells.Rows.Count).End(xlUp).Row
arrM = shM.Range("A2:A" & lastRM).value
arrS = shS.Range("A2:A" & lastRS).value
ReDim arrDif(1 To 1, 1 To UBound(arrM) + UBound(arrS)): d = 1
For s = 1 To UBound(arrS)
For m = 1 To UBound(arrM)
If arrS(s, 1) = arrM(m, 1) Then
boolF = True
Exit For
End If
Next m
If Not boolF Then
arrDif(1, d) = arrS(s, 1)
d = d + 1
End If
boolF = False
Next s
If d > 1 Then
ReDim Preserve arrDif(1 To 1, 1 To d - 1)
'shM.Range("A" & lastRM + 1).Resize(UBound(arrDif, 2), 1).value = _
WorksheetFunction.Transpose(arrDif)
shM.Range("A" & lastRM).Resize(UBound(arrDif, 2), 1).value = _
WorksheetFunction.Transpose(arrDif)
lastRM = shM.Range("A" & Cells.Rows.Count).End(xlUp).Row
shM.Range("A" & lastRM + 1).Formula = "=CountA(A2:A" & lastRM & ")"
End If
End Sub
Please, replace generic sheet names with your real ones.
Beforehand, be aware that I just began using VBA, and I have few coding experience prior to it.
I have two sheets:
public
contacts
There is one parameter on column A that is definitely on "contacts" sheet, but may be or not be on column A on "public" sheet.
What I'm doing is:
Checking if the parameter contacts.A2 is on public.A2.
If it is, I need to copy columns, on the exact order:
public: A, C, G.
contacts: E, F.
I've found the following code online, and I'm running some adaptations to it, but I'm stuck.
Sub match()
Dim I, total, frow As Integer
Dim found As Range
total = Sheets("public").Range("A" & Rows.Count).End(xlUp).Row
'MsgBox (total) '(verifica se a contagem está ok)
For I = 2 To total
pesquisa = Worksheets("public").Range("A" & I).Value
Set found = Sheets("contacts").Columns("A:A").Find(what:=pesquisa) 'finds a match
If found Is Nothing Then
Worksheets("result").Range("W" & I).Value = "NO MATCH"
Else
frow = Sheets("contacts").Columns("A:A").Find(what:=pesquisa).Row
Worksheets("result").Range("A" & I).Value = Worksheets("public").Range("A" & frow).Value
Worksheets("result").Range("B" & I).Value = Worksheets("public").Range("C" & frow).Value
Worksheets("result").Range("C" & I).Value = Worksheets("public").Range("G" & frow).Value
Worksheets("result").Range("D" & I).Value = Worksheets("contacts").Range("F" & frow).Value
Worksheets("result").Range("E" & I).Value = Worksheets("contacts").Range("G" & frow).Value
End If
Next I
End Sub
What I expect:
to the code do ignore the line 1, as those are headers;
to eliminate de IF above, since I don't need the "NO MATCH"
to the resulting list to be ordered on ascending order, based on the A column.
Can you help me?
edited to include samples of the data and expected results:
I believe I can simplify my needs with the images above. I want to check a client on the public sheet, grab the manager contacts (emails) from the contacts sheet, and create a list that contains branch, manager, and both e-mails on the results sheet.
Creating those images, I realized I have forgotten to account for the second parameter (manager), as there can be multiple managers on a branch. So this is another parameter to account for.
`Public sheet (image)
Contacts sheet(image)
Result sheet(image)
spreadsheet
`
As per my comments, and your updated question with sample, I do believe that your current results do not match that what you say is required; which is looking for both parameters "Branch" and "Manager". Neither does your expected result look like the columns you wanted to extract according to your question. However, going by your sample data and expected output I tried the following:
Sub BuildList()
'Define your variables
Dim x As Long, y As Long
Dim arr1 As Variant, arr2 As Variant
Dim dict As Object: Set dict = CreateObject("Scripting.Dictionary")
'Fill 1st array variable from sheet Contacts
With Sheet1 'Change accordingly
x = .Cells(.Rows.Count, 1).End(xlUp).Row
arr1 = .Range("A2:D" & x).Value
End With
'Fill dictionary with first array
For x = LBound(arr1) To UBound(arr1)
dict.Add arr1(x, 1) & "|" & arr1(x, 2), arr1(x, 3) & "|" & arr1(x, 4)
Next x
'Fill 2nd array variable from sheet Public
With Sheet2 'Change accordingly
x = .Cells(.Rows.Count, 1).End(xlUp).Row
arr2 = .Range("A2:B" & x).Value
End With
'Compare array against dictionary and fill sheet Results
With Sheet3 'Change accordingly
y = 2
For x = LBound(arr2) To UBound(arr2)
If dict.Exists(arr2(x, 1) & "|" & arr2(x, 2)) Then
.Cells(y, 1).Value = arr2(x, 1)
.Cells(y, 2).Value = arr2(x, 2)
.Cells(y, 3).Value = Split(dict(arr2(x, 1) & "|" & arr2(x, 2)), "|")(0)
.Cells(y, 4).Value = Split(dict(arr2(x, 1) & "|" & arr2(x, 2)), "|")(1)
y = y + 1
End If
Next x
End With
End Sub
This solution makes use of arrays and dictionary which should be fast. It has given me the following result:
As David suggested, it would be better to have an input and output sample. Maybe you can try this:
Option Explicit
Public Sub match()
Dim wsPub As Worksheet
Dim wsCon As Worksheet
Dim wsRes As Worksheet
Dim pubRow As Long
Dim conRow As Long
Dim resRow As Long
Dim i As Long
Dim rng As Range
Dim cel As Range
Dim found As Long
Dim order(1 To 5) As Integer
Set wsPub = ThisWorkbook.Worksheets("public")
Set wsCon = ThisWorkbook.Worksheets("contacts")
Set wsRes = ThisWorkbook.Worksheets("result")
pubRow = wsPub.Cells(wsPub.Rows.Count, 1).End(xlUp).Row
conRow = wsCon.Cells(wsPub.Rows.Count, 1).End(xlUp).Row
resRow = wsRes.Cells(wsRes.Rows.Count, 1).End(xlUp).Row
Set rng = wsPub.Range("A2:A" & pubRow)
order(1) = 1
order(2) = 3
order(3) = 7
order(4) = 6
order(5) = 7
For Each cel In rng
If Not IsError(Application.match(cel.Value, wsCon.Range("A2:A" & conRow), 0)) Then
found = Application.match(cel.Value, wsCon.Range("A2:A" & conRow), 0) + 1
resRow = wsRes.Cells(wsRes.Rows.Count, 1).End(xlUp).Row
For i = 1 To 5
If i < 4 Then
wsRes.Cells(resRow, i).Offset(1, 0).Value _
= cel.Offset(0, order(i) - 1).Value
Else
wsRes.Cells(resRow, i).Offset(1, 0).Value _
= wsCon.Cells(found, order(i)).Value
End If
Next
End If
Next
wsRes.Range("A1").AutoFilter
wsRes.AutoFilter.Sort.SortFields.Clear
wsRes.AutoFilter.Sort.SortFields.Add2 Key:= _
Range("A1:A" & resRow), SortOn:=xlSortOnValues, order:=xlAscending, DataOption:= _
xlSortNormal
wsRes.AutoFilter.Sort.Apply
End Sub
I am trying to identify a specific range in column-A and concatenate two cells within the specific range and delete the empty cell. I have been successful in putting a code together and it does the job very well. But, I don't know how to loop it to identify next range. Any help would be appreciated.
As per below image and code, First, I am finding and selecting a range between two (MCS) in column-A with a condition that, if the rows are more than 8 between two MCS. Then I am concatenating first 2 cells immediately after MCS and delete the empty row.
The below code works well for first range but I am unable to loop to identify next range from row 22 to 32 and perform concatenations.
I dont know how to loop in column-A and select ranges and concatenate. Any help would be much appreciated. Thanks
Sub MergeStem()
Dim findMCS1 As Long
Dim findMCS2 As Long
Dim myCount As Integer
Dim myStems As Long
Dim mySelect As Range
Dim c As Range
findMCS1 = Range("A:A").Find("MCS", Range("A1")).Row
findMCS2 = Range("A:A").Find("MCS", Range("A" & findMCS1)).Row
myCount = Range("A" & findMCS1 + 1 & ":A" & findMCS2 - 1).Cells.Count
Range("B1").Value = myCount
MsgBox "Number of rows =" & myCount
Set mySelect = Selection
If myCount > 8 Then
myStems = Range("A" & findMCS1 + 2 & ":A" & findMCS2 - 9).Select
Set mySelect = Selection
For Each c In mySelect.Cells
If firstcell = "" Then firstcell = c.Address(bRow, bCol)
sArgs = sArgs + c.Text + " "
c.Value = ""
Next
Range(firstcell).Value = sArgs
End If
Columns("A").SpecialCells(xlCellTypeBlanks).EntireRow.Delete
Application.ScreenUpdating = True
End Sub
Can you try this? Ordinarily, Find would be the way to go but because you are deleting rows it's hard to keep track of which cells you've found.
Sub x()
Dim r As Long, n1 As Long, n2 As Long
With Range("A1", Range("A" & Rows.Count).End(xlUp))
For r = .Count To 1 Step -1
If .Cells(r).Value = "MCS" Then
If n1 = 0 Then
n1 = .Cells(r).Row
Else
n2 = .Cells(r).Row
End If
If n1 > 0 And n2 > 0 Then
If n1 - n2 > 9 Then
.Cells(r + 1).Value = .Cells(r + 1).Value & .Cells(r + 2).Value
'.Cells(r + 2).EntireRow.Delete
'Call procedure to delete row
End If
n1 = n2
n2 = 0
End If
End If
Next r
End With
End Sub
Im having trouble deleting Rows when running the code not in debug mode. I put stars next to the line giving me a problem. Works in debug mode but not normally running the code. Any help? I have tried using doevent but in the beginning of the for loop but that didnt work.
Public Sub ItemUpdate(ByVal startRow As Integer, ByVal endRow As Integer, ByVal itemCol As String, ByVal statusCol As String, ByVal manuPNCol As String)
Dim orgSheet As Worksheet
Dim commonSheet As Worksheet
Dim partDesCol As String
Dim partDes As String
Dim vendorColNumber As Integer
Dim vendorColLetter As String
Dim manuPN As String
Dim counter As Integer
Dim replaceRnge As Range
Set orgSheet = ThisWorkbook.ActiveSheet
partDesCol = FindPartDesCol()
Set commonSheet = ThisWorkbook.Worksheets("Common Equipment")
For counter = startRow To endRow
'Get part description value
partDes = Range(partDesCol & counter).Value
'Delete row of empty cells if there is any
If partDes = "" Then
'deleteing empty row
orgSheet.Rows(counter).Delete '************************** Only works in
debug mode.
endRow = endRow - 1
If counter < endRow Then
counter = counter - 1
Else
Exit For
End If
Else
manuPN = Range(manuPNCol & counter).Value
'Search for user part in common sheet
Set rangeFind = commonSheet.Range("1:200").Find(partDes, lookat:=xlWhole)
If rangeFind Is Nothing Or partDes = "" Then
Debug.Print "Part " & partDes & " not found in Common Equipment"
'MsgBox "Part " & partDes & " not found in Common Equipment"
'Now check if manuPN is in common equipment
Set rangeFind = commonSheet.Range("1:200").Find(manuPN, lookat:=xlWhole)
If rangeFind Is Nothing Or partDes = "" Then
Debug.Print "PartNumber " & manuPN & " not found in Common Equipment"
'Now check if vendor value of item is empty
'Get vendor col
vendorCol = FindSearchCol()
If orgSheet.Range(vendorCol & counter).Value = "" Then
'Copy and paste manufact. data to vendor
'converting from letter column to number and visa versa
vendorColNumber = Range(vendorCol & 1).Column
ManuColTemp = vendorColNumber - 2
ManuPNColTemp = vendorColNumber - 1
VendorPNColTemp = vendorColNumber + 1
ManuCol = Split(Cells(1, ManuColTemp).Address(True, False), "$")(0)
manuPNCol = Split(Cells(1, ManuPNColTemp).Address(True, False), "$")(0)
VendorPNCol = Split(Cells(1, VendorPNColTemp).Address(True, False), "$")
(0)
orgSheet.Range(ManuCol & counter & ":" & manuPNCol & counter).Copy Range(vendorCol & counter & ":" & VendorPNCol & counter)
End If
Else
'Copy new data from common equipment and paste in place of old data
'Get value of status
If statusCol <> "error" Then
orderStatus = orgSheet.Range(statusCol & counter).Value
End If
commonSheet.Rows(rangeFind.Row).EntireRow.Copy
orgSheet.Range(itemCol & counter).PasteSpecial xlPasteValues
If statusCol <> "error" Then
orgSheet.Range(statusCol & counter).Value = orderStatus
End If
End If
Else
'Copy new data from common equipment and paste in place of old data
'Get value of status
If statusCol <> "error" Then
orderStatus = orgSheet.Range(statusCol & counter).Value
End If
commonSheet.Rows(rangeFind.Row).EntireRow.Copy
orgSheet.Range(itemCol & counter).PasteSpecial xlPasteValues
If statusCol <> "error" Then
orgSheet.Range(statusCol & counter).Value = orderStatus
End If
End If
End If
Next counter
'call renumber item numbers
Call NumberItems(0, 0, 0, False)
End Sub
Most likely, you need to step backwards through your range. When you step forward, as you are doing, the counter will skip a row whenever you delete a row:
For counter = startRow To endRow
Change to
For counter = endRow To startRow Step -1
Also, you should declare endRow and startRow as data type Long. The range of Integer will not cover all the rows in an Excel worksheet; and also VBA is said to convert Integers to Longs when doing the math anyway.