Using Find with 2D Arry

Birdie212

New Member
Joined
Jul 4, 2022
Messages
12
Office Version
  1. 2016
Platform
  1. Windows
I have a report that I need to update from the data in another report. Both reports are large, over 50,000 rows, so I read them into arrays so the process would run faster.
I need to split the Source array into separate arrays based on certain conditions in the HR array. I'm getting an object required error when I try to assign a value to the ID variable.
Could anyone help me figure out how to fix this error? Also, am I going about this the right way? Thanks.
Here's my code:

VBA Code:
Option Explicit

Sub SearchArrays()

Dim wb As Workbook, wsSource As Worksheet, wsHR As Worksheet
Dim arrSource() As Variant, arrHR() As Variant, arrNotFound() As Variant, arrRemoved() As Variant, arrUpdated() As Variant
'Dim ID As String
Dim ID As Variant
Dim x As Long, y As Long, nCounter As Long, CounterN As Long, rCounter As Long, CounterR As Long, uCounter As Long, CounterU As Long

Set wb = ThisWorkbook
Set wsSource = wb.Worksheets("Source")
Set wsHR = wb.Worksheets("HR")

wsSource.Activate
arrSource = Range("A2", Range("A2").End(xlDown).End(xlToRight)) 'Read Source data into array
wsHR.Activate
arrHR = Range("A2", Range("A2").End(xlDown).End(xlToRight))     'Read HR data into array

'Use Find to find the values in source array in the hr array
For x = LBound(arrSource, 1) To UBound(arrSource, 1)
    For y = LBound(arrHR, 1) To UBound(arrHR, 1)
        'ID is in column 2 of Source data and column 3 of HR data
        Set ID = arrSource(x, 2).Find(what:=arrHR(y, 3).Value, LookIn:=xlValues, lookat:=xlWhole)
            If ID Is Nothing Then
                'Copy data to Not Found array
                nCounter = nCounter + 1
                ReDim Preserve arrNotFound(1 To 5, 1 To nCounter)   'Redimension the Not Found array with each instance
                For CounterN = 1 To 5    'The arrNotFound equals the current row
                    arrNotFound(CounterN, nCounter) = arrSource(x, CounterN)
                Next CounterN
            ElseIf Not ID Is Nothing And ID.Offset(, 3).Value <> arrHR(y, 3).Offset(, 2) Then
                'Copy to removed array
                rCounter = rCounter + 1
                ReDim Preserve arrRemoved(1 To 5, 1 To rCounter)   'Redimension the Removed array with each instance
                For CounterR = 1 To 5    'The arrRemoved equals the current row
                    arrRemoved(CounterR, rCounter) = arrSource(x, CounterR)
                Next CounterR
            ElseIf Not ID Is Nothing And ID.Offset(, 3).Value = arrHR(y, 3).Offset(, 2) Then
                'Copy to Updated array
                uCounter = uCounter + 1
                ReDim Preserve arrUpdated(1 To 5, 1 To uCounter)   'Redimension the Updated array with each instance
                For CounterU = 1 To 5    'The arrUpdated equals the current row
                    arrUpdated(CounterU, uCounter) = arrSource(x, CounterU)
                Next CounterU
            End If
    Next y
Next x

'Write arrNotFound to a new worksheet
'Write arrRemoved to a new worksheet
'Write arrUpdated to a new worksheet

End Sub

Sample Data:

NameIDJob TitleSalaryDepartment
Nancy DrewA0001Manager$ 50,000.00Sales
Tom HardyA0002Assistant Manager$ 35,000.00Accounting
Bugs BunnyA0003Director$ 65,000.00PR
Daffy DuckA0004CEO$ 150,000.00Finance
Miss PiggyA0005Engineer$ 55,000.00Technology
Peter ParkerA0006Copy$ 42,000.00Mail Room
Andrea BlueA0007Teller$ 35,000.00Banking
Phil DumpfyA0008Gofer$ 48,000.00Audit
Candy LandA0009Chef$ 200,000.00Kitchen
Larry DoyleA0010Editor$ 22,000.00Staffing
 

Excel Facts

How can you turn a range sideways?
Copy the range. Select a blank cell. Right-click, Paste Special, then choose Transpose.
Hi,
welcome to forum
Range.Find method requires the Range object which can be Columns, a property of the Range Object

Try changing this line

VBA Code:
'ID is in column 2 of Source data and column 3 of HR data
        Set ID = arrSource(x, 2).Find(what:=arrHR(y, 3).Value, LookIn:=xlValues, lookat:=xlWhole)

to this
VBA Code:
Set ID = wsSource.Columns(2).Find(what:=arrHR(y, 3), LookIn:=xlValues, lookat:=xlWhole)

and see if resolves your issue

Dave
 
Upvote 0
Hi,
welcome to forum
Range.Find method requires the Range object which can be Columns, a property of the Range Object

Try changing this line

VBA Code:
'ID is in column 2 of Source data and column 3 of HR data
        Set ID = arrSource(x, 2).Find(what:=arrHR(y, 3).Value, LookIn:=xlValues, lookat:=xlWhole)

to this
VBA Code:
Set ID = wsSource.Columns(2).Find(what:=arrHR(y, 3), LookIn:=xlValues, lookat:=xlWhole)

and see if resolves your issue

Dave
I'm not using the worksheet function because I have over 50,000 records in each data source. When I tried this method using find on the worksheet the code just hangs and never finishes. I was hoping that using an array would be faster.
 
Upvote 0
I'm not using the worksheet function because I have over 50,000 records in each data source. When I tried this method using find on the worksheet the code just hangs and never finishes. I was hoping that using an array would be faster.

I have used Range.Find method on much larger data sets without performance issues

As you have code in a for next loop, try clearing the ID variable from memory at each cycle and see if this makes any difference

VBA Code:
Next y
    Set ID = Nothing
Next x

Dave
 
Upvote 0
I have used Range.Find method on much larger data sets without performance issues

As you have code in a for next loop, try clearing the ID variable from memory at each cycle and see if this makes any difference

VBA Code:
Next y
    Set ID = Nothing
Next x

Dave
Dave, here's the code that I executed on the worksheet. I added your suggest to reset the ID to nothing after every For Loop and it still ran for over an hour without completing. Please take a look and see if there is anything wrong with how the code is written. Thanks.

VBA Code:
Set wb = ThisWorkbook
Set wsOutput = wb.Worksheets("Output")
Set wsRemoved = wb.Worksheets("Removed")
Set wsDisabled = wb.Worksheets("Disabled")

LR_HR = wsHR.Cells(Rows.Count, 1).End(xlUp).Row
row_hr = 2
ROW_Output = 2

LR_Output = wsOutput.Cells(Rows.Count, 1).End(xlUp).Row

Do While wsOutput.Cells(ROW_Output, 12).Value <> ""

    For ROW_Output = 2 To LR_Output
    
        Set UserID = wsHR.Range("C:C").Find(what:=wsOutput.Cells(ROW_Output, 12).Value, LookIn:=xlValues, lookat:=xlWhole)
        'If UserID not found then move row to Disabled worksheet
        If UserID Is Nothing Then
            wsOutput.Activate
            Rows(ROW_Output).Copy
            wsDisabled.Range("A" & Rows.Count).End(xlUp).Offset(1, 0).EntireRow.Insert
            Rows(ROW_Output).Delete
            ROW_Output = ROW_Output - 1
            wsHR.Activate
        ElseIf Not UserID Is Nothing Then
            'If UserID found but different Dept in HR table then move row to Removed worksheet
            If wsOutput.Cells(ROW_Output, 23).Value <> wsHR.Cells(row_hr, 3).Offset(0, 8).Value Then
                wsOutput.Activate
                Rows(ROW_Output).Copy
                wsRemoved.Range("A" & Rows.Count).End(xlUp).Offset(1, 0).EntireRow.Insert
                Rows(ROW_Output).Delete
                ROW_Output = ROW_Output - 1
                wsHR.Activate
            End If
        End If

    Next
    'Added
    Set UserID = Nothing
      
Loop
 
Upvote 0
@Birdie212
1. Is column B sorted descending on both sheet?
2. What's the actual ID looks like? Is it like on your example? A0001, A0002,..etc?

I think I have an idea on how to speed up the code significantly faster without using Find & Redim Preserve.
 
Upvote 0
@Birdie212
1. Is column B sorted descending on both sheet?
2. What's the actual ID looks like? Is it like on your example? A0001, A0002,..etc?

I think I have an idea on how to speed up the code significantly faster without using Find & Redim Preserve.
1. The ID column is sorted ascending in both worksheets. I thought this would speed up the code.
2. The ID starts with a letter (A, C, D, etc.) and then the remaining values are numbers. (A42325, C22516, etc.)

Thanks.
 
Upvote 0
Sorry, I just read again your code in this part:
Rich (BB code):
        'ID is in column 2 of Source data and column 3 of HR data
So, data structure on the 2 sheets are different. What's the data look like on HR data?

And I don't understand what you're trying to do in this part? Can you explain in more detail?
VBA Code:
Set ID = arrSource(x, 2).Find(what:=arrHR(y, 3).Value, LookIn:=xlValues, lookat:=xlWhole)
 
Upvote 0
Sorry, I just read again your code in this part:
Rich (BB code):
        'ID is in column 2 of Source data and column 3 of HR data
So, data structure on the 2 sheets are different. What's the data look like on HR data?

And I don't understand what you're trying to do in this part? Can you explain in more detail?
VBA Code:
Set ID = arrSource(x, 2).Find(what:=arrHR(y, 3).Value, LookIn:=xlValues, lookat:=xlWhole)
Akuini, take a look at my reply to Dave above. I posted the original code where I tried to use the find function on the worksheet. I'm taking the UserID from the source worksheet and search through the HR data to find the UserID. If the UserID isn't found in the HR data then I want to move the entire row from Source to Not Found worksheet. If the UserID is found in the HR data but the Department name is different I want to move the entire row from the Source Data to the Removed Worksheet.

I tried this code and it ran for hours without completing. That's why I was trying to do the same using arrays but I'm not sure how to set up the loop using the arrays.

Thanks.
 
Upvote 0
I'm taking the UserID from the source worksheet and search through the HR data to find the UserID.
UserID in both sheets have no duplicates? so if found, you expect to find only one occurrence per UserID?
 
Upvote 0

Forum statistics

Threads
1,223,884
Messages
6,175,177
Members
452,615
Latest member
bogeys2birdies

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