Excel VBA - Compare matching cell values in arrays and copy entire rows

TropicalMagic

New Member
Joined
Jun 19, 2021
Messages
47
Office Version
  1. 365
Platform
  1. Windows
Hi all,


I would like to compare cell values in column E of Workbook A’s worksheet 1 to those in column A of ReferenceList workbook’s worksheet 1.

Matching cell values will have their entire row be copied over to Workbook B’s worksheet 1, which will be empty at first.


I have placed the ranges into an array for speedier processing, since the number of rows can be in the 1000s.


The screenshots show mock-up samples:


Workbook A’s worksheet 1:

1.png



ReferenceList’s worksheet 1:
2.png



However, the code is not working:


VBA Code:
Sub ACCEPTED_OCEAN_OTQ_CHECK()



Application.ScreenUpdating = False

Application.DisplayAlerts = False



Workbooks.Open ("WorkbookA.xlsx")

Workbooks.Open ("WorkbookB.xlsx")

Workbooks.Open ("ReferenceList")



Dim WorkbookA As Workbook

Set WorkbookA = Workbooks("WorkbookA.xlsx")

Dim WorkbookA_LASTROW, WorkbookA_LASTCOL As Long

WorkbookA_LASTROW = WorkbookA.Sheets(1).Range("A" & Rows.Count).End(xlUp).Row

WorkbookA_LASTCOL = WorkbookA.Sheets(1).Range("A1").CurrentRegion.Columns.Count



Dim WorkbookB As Workbook

Set WorkbookB = Workbooks("WorkbookB.xlsx")

Dim WorkbookB_LASTROW, WorkbookB_LASTCOL As Long

WorkbookB_LASTROW = WorkbookB.Sheets(1).Range("A" & Rows.Count).End(xlUp).Row

WorkbookB_LASTCOL = WorkbookB.Sheets(1).Range("A1").CurrentRegion.Columns.Count



Dim ReferenceList As Workbook

Set ReferenceList = Workbooks("ReferenceList.xlsx")

Dim ReferenceList_LASTROW, ReferenceList_LASTCOL As Long

ReferenceList_LASTROW = ReferenceList.Sheets(1).Range("A" & Rows.Count).End(xlUp).Row

ReferenceList_LASTCOL = ReferenceList.Sheets(1).Range("A1").CurrentRegion.Columns.Count



Dim i, j As Long

Dim Array1, Array2, Array3 As Variant



'Parse all values to an array, reducing interactions with the application

Array1 = Range(WorkbookA.Sheets(1).Cells(1), WorkbookA.Sheets(1).Cells(WorkbookA_LASTROW, WorkbookA_LASTCOL))

Array2 = Range(ReferenceList.Sheets(1).Cells(1), ReferenceList.Sheets(1).Cells(ReferenceList_LASTROW, ReferenceList_LASTCOL))

Array3 = Range(WorkbookB.Sheets(1).Cells(1), WorkbookB.Sheets(1).Cells(WorkbookB_LASTROW, WorkbookB_LASTCOL))



'Creates a temporary array for Workbook B

ReDim Array3(1 To WorkbookA_LASTROW, 1 To WorkbookA_LASTCOL)



'Check for matches in both Workbook A and Reference List, then copies entire row containing matches to Workbook B

For i = 1 To WorkbookA_LASTROW

If Array1(i, 5) = Array2(i, 1) Then

For j = 1 To WorkbookA_LASTCOL

Array3(i, j) = Array1(i, j)

Next

End If

Next



WorkbookB.Sheets(1).Range(WorkbookB.Sheets(1).Cells(1), WorkbookB.Sheets(1).Cells(WorkbookA_LASTROW, WorkbookB_LASTROW)) = Array3



Workbooks("WorkbookA.xlsx").Close SaveChanges:=True

Workbooks("WorkbookB.xlsx").Close SaveChanges:=True

Workbooks("ReferenceList").Close SaveChanges:=True



MsgBox "GENERATED!"



Application.ScreenUpdating = True

Application.DisplayAlerts = True



 End Sub


Can anyone help me with it?



Many thanks!
 

Excel Facts

What does custom number format of ;;; mean?
Three semi-colons will hide the value in the cell. Although most people use white font instead.
Are all three workbooks open when you run the code?
If not what are their file paths?
 
Upvote 0
I have placed the ranges into an array for speedier processing, since the number of rows can be in the 1000s.
Hi, rather than a gas factory code I would better go with a quick enough Excel formula and an advanced filter even under VBA, done in ten codelines …​
 
Upvote 0
Are all three workbooks open when you run the code?
If not what are their file paths?
Thanks for responding!

Nope, but the code will also open the workbooks at the beginning:

Workbooks.Open(Application.DefaultFilePath & "\" & "WorkbookA.xlsx")
Workbooks.Open(Application.DefaultFilePath & "\" & "WorkbookB.xlsx")
Workbooks.Open(Application.DefaultFilePath & "\" & "ReferenceList.xlsx")
 
Upvote 0
Hi, rather than a gas factory code I would better go with a quick enough Excel formula and an advanced filter even under VBA, done in ten codelines …​
Thanks for responding!

I considered it but however, I'll be running the report generation daily thus I am seeking a VBA-oriented solution to automate away repetitive effort and human errors.
 
Upvote 0
Ok, how about
VBA Code:
Sub TropicalMagic()
   Dim WbkA As Workbook, WbkB As Workbook, WbkC As Workbook
   Dim Ary As Variant, Nary As Variant
   Dim Dic As Object
   Dim r As Long, c As Long, nr As Long
   
   Set WbkA = Workbooks.Open(Application.DefaultFilePath & "\" & "WorkbookA.xlsx")
   Set WbkB = Workbooks.Open(Application.DefaultFilePath & "\" & "WorkbookB.xlsx")
   Set WbkC = Workbooks.Open(Application.DefaultFilePath & "\" & "ReferenceList.xlsx")
   Set Dic = CreateObject("scripting.dictionary")
   Dic.comparemode = 1
   
   With WbkC.Sheets(1)
      Ary = .Range("A2", .Range("A" & Rows.Count).End(xlUp)).Value2
   End With
   For r = 1 To UBound(Ary)
      Dic(Cl.Value) = Empty
   Next r
   With WbkA.Sheets(1)
      c = .Cells(1, Columns.Count).End(xlToLeft).Column
      Ary = .Range("A2", .Range("A" & Rows.Count).End(xlUp)).Resize(, c).Value2
   End With
   
   ReDim Nary(1 To UBound(Ary), 1 To UBound(Ary, 2))
   For r = 1 To UBound(Ary)
      If Dic.Exists(Ary(r, 5)) Then
         nr = nr + 1
         For c = 1 To UBound(Ary, 2)
            Nary(nr, c) = Ary(r, c)
         Next c
      End If
   Next r
   Wbk.Sheets(1).Range("A1").Resize(nr, UBound(Nary, 2)).Value = Nary
   
   WbkA.Close True
   WbkB.Close True
   WbkC.Close True
End Sub
 
Upvote 0
Solution
Ok, how about
VBA Code:
Sub TropicalMagic()
   Dim WbkA As Workbook, WbkB As Workbook, WbkC As Workbook
   Dim Ary As Variant, Nary As Variant
   Dim Dic As Object
   Dim r As Long, c As Long, nr As Long
 
   Set WbkA = Workbooks.Open(Application.DefaultFilePath & "\" & "WorkbookA.xlsx")
   Set WbkB = Workbooks.Open(Application.DefaultFilePath & "\" & "WorkbookB.xlsx")
   Set WbkC = Workbooks.Open(Application.DefaultFilePath & "\" & "ReferenceList.xlsx")
   Set Dic = CreateObject("scripting.dictionary")
   Dic.comparemode = 1
 
   With WbkC.Sheets(1)
      Ary = .Range("A2", .Range("A" & Rows.Count).End(xlUp)).Value2
   End With
   For r = 1 To UBound(Ary)
      Dic(Cl.Value) = Empty
   Next r
   With WbkA.Sheets(1)
      c = .Cells(1, Columns.Count).End(xlToLeft).Column
      Ary = .Range("A2", .Range("A" & Rows.Count).End(xlUp)).Resize(, c).Value2
   End With
 
   ReDim Nary(1 To UBound(Ary), 1 To UBound(Ary, 2))
   For r = 1 To UBound(Ary)
      If Dic.Exists(Ary(r, 5)) Then
         nr = nr + 1
         For c = 1 To UBound(Ary, 2)
            Nary(nr, c) = Ary(r, c)
         Next c
      End If
   Next r
   Wbk.Sheets(1).Range("A1").Resize(nr, UBound(Nary, 2)).Value = Nary
 
   WbkA.Close True
   WbkB.Close True
   WbkC.Close True
End Sub

Thanks for responding!

However, I have run into a Run-Time Error 424 : Object Required at the "Dic(Cl.Value) = Empty" line.

Even after I included a "Dim Cl As Range", a new Run-Time Error 91 : Object Variable or With Block Variable Not Set at the "Dic(Cl.Value) = Empty" line.

VBA Code:
Sub TropicalMagic()
   Dim WbkA As Workbook, WbkB As Workbook, WbkC As Workbook
   Dim Ary As Variant, Nary As Variant
   Dim Dic As Object
   Dim Cl As Range
   Dim r As Long, c As Long, nr As Long
   
   Set WbkA = Workbooks.Open(Application.DefaultFilePath & "\" & "WorkbookA.xlsx")
   Set WbkB = Workbooks.Open(Application.DefaultFilePath & "\" & "WorkbookB.xlsx")
   Set WbkC = Workbooks.Open(Application.DefaultFilePath & "\" & "ReferenceList.xlsx")
   Set Dic = CreateObject("scripting.dictionary")
   Dic.comparemode = 1
   
   With WbkC.Sheets(1)
      Ary = .Range("A2", .Range("A" & Rows.Count).End(xlUp)).Value2
   End With
   For r = 1 To UBound(Ary)
      Dic(Cl.Value) = Empty
   Next r
   With WbkA.Sheets(1)
      c = .Cells(1, Columns.Count).End(xlToLeft).Column
      Ary = .Range("A2", .Range("A" & Rows.Count).End(xlUp)).Resize(, c).Value2
   End With
   
   ReDim Nary(1 To UBound(Ary), 1 To UBound(Ary, 2))
   For r = 1 To UBound(Ary)
      If Dic.Exists(Ary(r, 5)) Then
         nr = nr + 1
         For c = 1 To UBound(Ary, 2)
            Nary(nr, c) = Ary(r, c)
         Next c
      End If
   Next r
   Wbk.Sheets(1).Range("A1").Resize(nr, UBound(Nary, 2)).Value = Nary
   
   WbkA.Close True
   WbkB.Close True
   WbkC.Close True
End Sub

Not sure how to address the issue.

Many thanks!
 
Upvote 0
Helps if I put my brain in gear. It should be
VBA Code:
      Dic(Ary(r, 1)) = Empty
 
Upvote 0
Helps if I put my brain in gear. It should be
VBA Code:
      Dic(Ary(r, 1)) = Empty
Thanks for your rapid response!

No worries.

However, I have run into a Run-Time Error 1004 : Application-defined or Object-Defined Error at the

"WbkB.Sheets(1).Range("A1").Resize(nr, UBound(Nary, 2)).Value = Nary" line
 
Upvote 0
That would suggest that the output array is empty, when the error occurs hover the mouse over the nr variable, what does it show?
 
Upvote 0

Forum statistics

Threads
1,214,945
Messages
6,122,397
Members
449,081
Latest member
JAMES KECULAH

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top