I need to compare two ranges and see if value in one range appears in the other. This is the code I use:
Dim rng1 As Range
Dim rng2 As Range
Dim cell as Range
Dim found as Range
set rng1 = ....
set rng2 = ....
for each cell in rng1
set found = rng2.Find(what:=cell,.....
Next cell
This code is OK if the range is in thousands of rows, single column. When it comes to tens of thousands, it's very slow.
Anyway to speed it up?
This might be the fastest way for large amounts of data:
Option Explicit
Sub Test()
Dim rng1 As Range
Set rng1 = YourShorterRange
Dim rng2 As Range
Set rng2 = YourLargerRange
Dim C As Range
Dim Matches As Object: Set Matches = CreateObject("Scripting.Dictionary")
'input the larger data inside a dictionary
For Each C In rng2
If Not Matches.Exists(C.Value) Then Matches.Add C.Value, 1
Next C
Dim i As Long
Dim arr As Variant
'input the shorter data inside an array
arr = rng1.Value
For i = 1 To UBound(arr)
If Matches.Exists(arr(i, 1)) Then
'your code if the value is found
End If
Next i
End Sub
Edit for Dorian:
Option Explicit
Sub Test()
Dim rng1 As Range
Set rng1 = YourShorterRange
Dim rng2 As Range
Set rng2 = YourLargerRange
Dim i As Long, j As Long
Dim arr As Variant
Dim Matches As Object: Set Matches = CreateObject("Scripting.Dictionary")
arr = rng1.Value
'input the larger data inside a dictionary
For i = 1 To UBound(arr)
For j = 1 To UBound(arr, 2)
If Not Matches.Exists(arr(i, j)) Then Matches.Add arr(i, j), 1
Next j
Next i
'input the shorter data inside an array
arr = rng2.Value
For i = 1 To UBound(arr)
For j = 1 To UBound(arr, 2)
If Matches.Exists(arr(i, j)) Then
'your code if the value is found
End If
Next j
Next i
End Sub
Maybe something along these lines:
Sub Test()
Dim arr1 As Variant, arr2 As Variant
Dim arrList As Object: Set arrList = CreateObject("System.Collections.ArrayList")
Dim x As Long
arr1 = rng1 'Specify your range
arr2 = rng2 'Specify your range
For x = LBound(arr2) To UBound(arr2)
arrList.Add arr2(x, 1)
Next x
For x = LBound(arr1) To UBound(arr1)
If arrList.contains(arr1(x, 1)) = True Then
Debug.Print arr1(x, 1) & " contained within range 2"
End If
Next x
End Sub
I would suggest you :
Application.match
You can also look here you will find an interesting studies on 3 different ways of Search. Those 3 Different way will be studied By Time and By number of occurences.
According Fastexcel the conclusion of this study is :
Don’t use Range.Find unless you want to search a large number of
columns for the same thing (you would have to do a Match for each
column).
The Variant array approach is surprisingly effective,
particularly when you expect a large number of hits.
Match wins easily
for a small number of hits.
So If you except a large number of hit you might have to give a try variant array method. The 3 ways are listed in Fastexcel tuto
Edit
After reading some comment I did a new test :
Variant code
Sub Test1()
Dim vArr As Variant
Dim j As Long
Dim n As Long
Dim dTime As Double
dTime = MicroTimer
vArr = Range("A1:B100000").Value2
Dim Matches As Object: Set Matches = CreateObject("Scripting.Dictionary")
arr = Range("G1:G15").Value
For i = 1 To UBound(arr)
For j = 1 To UBound(arr, 2)
If Not Matches.Exists(arr(i, j)) Then Matches.Add arr(i, j), 1
Next j
Next i
For j = LBound(vArr) To UBound(vArr)
If Matches.Exists(vArr(j, 1)) Or Matches.Exists(vArr(j, 2)) Then n = n + 1
Next j
Debug.Print "Using Variant : " & n & " Timer :" & (MicroTimer - dTime) * 1000
End Sub
Dictionary
Sub Test()
Dim rng1 As Range
Set rng1 = Range("A1:B100000")
Dim rng2 As Range
Set rng2 = Range("G1:G15")
Dim i As Long, j As Long
Dim arr As Variant
Dim dTime As Double
dTime = MicroTimer
Dim Matches As Object: Set Matches = CreateObject("Scripting.Dictionary")
arr = rng2.Value
'input the larger data inside a dictionary
For i = 1 To UBound(arr)
For j = 1 To UBound(arr, 2)
If Not Matches.Exists(arr(i, j)) Then Matches.Add arr(i, j), 1
Next j
Next i
'input the shorter data inside an array
arr = rng1.Value
For i = 1 To UBound(arr)
For j = 1 To UBound(arr, 2)
If Matches.Exists(arr(i, j)) Then
'your code if the value is found
cpt = cpt + 1
End If
Next j
Next i
Debug.Print "Using Damian Method : " & cpt & " Timer : " & (MicroTimer - dTime) * 1000
End Sub
Related
I want to create a variant array when using a union to join ranges.
If I select one of the ranges the variant array will work.
When I union, I only receive the row dimensions and not the column dimensions.
For example,
Sub arrTest()
'Declare varbs
Dim ws As Worksheet
Dim myArr() As Variant
Dim lRow As Integer
Dim myRng As Range
'Assign varbs
Set ws = ThisWorkbook.Worksheets("Sheet1")
With ws
lRow = .Cells(Rows.count, "C").End(xlUp).row
Set myRng = Application.Union(.Range("G3:G" & lRow), .Range("J3:O" & lRow), .Range("AD3:AE" & lRow), .Range("AI3:AI" & lRow))
myArr = myRng.Value2
End With
Will return a variant of
myArr(1, 1)
myArr(2, 1)
myArr(1, 3)
However if I were to select one of the ranges within the union for example:
Sub arrTest()
'Declare varbs
Dim ws As Worksheet
Dim myArr() As Variant
Dim lRow As Integer
Dim myRng As Range
'Assign varbs
Set ws = ThisWorkbook.Worksheets("Sheet1")
With ws
lRow = .Cells(Rows.count, "C").End(xlUp).row
Set myRng = .Range("J3:O" & lRow)
myArr = myRng.Value2
End With
I properly get
myArr(1, 1)
myArr(1, 2)
myArr(1, 3)
etc.
How do I return the column dimensions as well, without looping through the sheet?
Like this:
Sub ArrayTest()
Dim ws As Worksheet
Dim arr, lrow As Long
Set ws = ThisWorkbook.Worksheets("Sheet1")
lrow = ws.Cells(Rows.Count, "C").End(xlUp).Row
arr = GetArray(ws.Range("G3:G" & lrow), ws.Range("J3:O" & lrow), _
ws.Range("AD3:AE" & lrow), ws.Range("AI3:AI" & lrow))
With ThisWorkbook.Worksheets("Sheet2").Range("B2")
.Resize(UBound(arr, 1), UBound(arr, 2)).Value = arr
End With
End Sub
'Given a number of input ranges each consisting of one or more columns (assumed all input ranges have
' the same # of rows), return a single 1-based 2D array with the data from each range
Function GetArray(ParamArray sourceCols() As Variant) As Variant
Dim arr, rng, numCols As Long, numRows As Long, r As Long, c As Long, tmp, col As Long
numRows = sourceCols(0).Rows.Count
'loop over ranges and get the total number of columns
For Each rng In sourceCols
numCols = numCols + rng.Columns.Count
Next rng
ReDim arr(1 To numRows, 1 To numCols) 'size the output array
c = 0
For Each rng In sourceCols 'loop the input ranges
tmp = As2DArray(rng) 'get range source data as array ####
For col = 1 To UBound(tmp, 2) 'each column in `rng`
c = c + 1 'increment column position in `arr`
For r = 1 To numRows 'fill the output column
arr(r, c) = tmp(r, col)
Next r
Next col
Next rng
GetArray = arr
End Function
'Get a range's value, always as a 2D array, even if only a single cell
Function As2DArray(rng)
If rng.Cells.Count > 1 Then
As2DArray = rng.Value
Else
Dim arr(1 To 1, 1 To 1)
arr(1, 1) = rng.Value
As2DArray = arr
End If
End Function
I have autofiltered a worksheet and am trying to establish the unique values within the filtered data. I feel like I have the correct approach, but the my results only show 2 of the possible 8 unique values.
Private Sub GetAllCampusDomains(DomainCol As Collection)
Dim data(), dict As Object, r As Long, i%, lastrow As Long
Set dict = CreateObject("Scripting.Dictionary")
'Clear the previous filter
shtData.ShowAllData
'Filter the data
shtData.Range("A:Y").AutoFilter Field:=6, Criteria1:=shtSetup.Range("CampusName") 'SchoolName
shtData.Range("A:Y").AutoFilter Field:=9, Criteria1:="DomainPerformance" 'ColI
'Inspect the visible cells in ColP
lastrow = shtData.Cells(shtData.Rows.Count, "P").End(xlUp).row
data = shtData.Range("P2:P" & lastrow).SpecialCells(xlCellTypeVisible)
'Find the unique values
For r = 1 To UBound(data)
dict(data(r, 1)) = Empty
Next
data = WorksheetFunction.Transpose(dict.keys())
'Walk through the unique values
For i = 1 To UBound(data)
Debug.Print data(i, 1)
'DomainCol.Add data(i, 1)
Next i
End Sub
The error seems to have to do with this line:
data = shtData.Range("P2:P" & lastrow).SpecialCells(xlCellTypeVisible)
This call only seems to create a 90x1 sized array, when it should be much bigger.
I greatly appreciate your help!
Josh
Non-Contiguous Column Range to Jagged Array
Instead of...
data = shtData.Range("P2:P" & lastrow).SpecialCells(xlCellTypeVisible)
'Find the unique values
For r = 1 To UBound(data)
dict(data(r, 1)) = Empty
Next
...use the following...
Private Sub GetAllCampusDomains(DomainCol As Collection)
'...
Dim rng As Range
Set rng = shtData.Range("P2:P" & lastrow).SpecialCells(xlCellTypeVisible)
getNonContiguousColumn Data, rng
'Find the unique values
Dim j As Long
For j = 0 To UBound(Data)
For r = 1 To UBound(Data(j))
dict(Data(j)(r, 1)) = Empty
Next r
Next j
'...
End Sub
...backed up by the following:
Sub getNonContiguousColumn(ByRef Data As Variant, _
NonContiguousColumnRange As Range, _
Optional FirstIndex As Long = 0)
Dim j As Long
j = FirstIndex - 1
ReDim Data(FirstIndex To NonContiguousColumnRange.Areas.Count + j)
Dim ar As Range
Dim OneCell As Variant
ReDim OneCell(1 To 1, 1 To 1)
For Each ar In NonContiguousColumnRange.Areas
j = j + 1
If ar.Cells.Count > 1 Then
Data(j) = ar.Value
Else
OneCell(1, 1) = ar.Value
Data(j) = OneCell
End If
Next ar
End Sub
Test the previous Sub with something like the following:
Sub testGetNCC()
Const rngAddr As String = "A2:A20"
Dim Data As Variant
Dim rng As Range
Set rng = Range(rngAddr).SpecialCells(xlCellTypeVisible)
getNonContiguousColumn Data, rng
Dim j As Long, i As Long
For j = 0 To UBound(Data)
For i = 1 To UBound(Data(j))
Debug.Print Data(j)(i, 1)
Next i
Next j
End Sub
Please, replace this piece of code:
data = shtData.Range("P2:P" & lastrow).SpecialCells(xlCellTypeVisible)
'Find the unique values
For r = 1 To UBound(data)
dict(data(r, 1)) = Empty
Next
with the next one:
Dim rng As Range, C As Range
Set rng = shtData.Range("P2:P" & lastRow).SpecialCells(xlCellTypeVisible)
'Find the unique values
For Each C In rng.cells
dict(C.Value) = Empty
Next
Your initial code iterates between the first area range cells.
The second one will iterate between all visible range cells...
This is posted by Dammer15 and this is what I'm looking for. However I need it to loop through the entire column. I would ask there directly but I can not comment yet.
Dim My_Number As String
Dim i As Integer
My_Number = Range("AJ")
For i = 1 To Len(My_Number) - 1
If InStr(1, My_Number, "0") = 1 Then
My_Number = Right(My_Number, Len(My_Number) - 1)
Else
Range("AJ") = My_Number
Exit For
End If
Next
You will need to iterate through each value. I would recommend uploading the whole range into an array and then looping through that instead:
Sub foo()
Dim rng As Range
Dim i As Long, j As Long
Dim arr() As Variant
Dim lastRow As Long
With ActiveSheet
lastRow = .Cells(.Rows.Count, "AJ").End(xlUp).Row
Set rng = .Range("AJ1", .Cells(lastRow, "AJ"))
arr = rng.Value
For i = LBound(arr, 1) To UBound(arr, 1)
My_Number = arr(i, 1)
For j = 1 To Len(arr(i, 1)) - 1
If Mid(arr(i, 1), j, 1) <> 0 Then
arr(i, 1) = Right(arr(i, 1), Len(arr(i, 1)) - (j - 1))
Exit For
End If
Next j
Next i
rng.Value = arr
End With
End Sub
You could use a regex to match the lead 0s instead of the bulky replace function you currently have:
Sub TestRe()
Dim LastCell As Range: Set LastCell = ActiveSheet.Columns("AJ").Find("*", SearchDirection:=xlPrevious)
Dim Rng As Range: Set Rng = ActiveSheet.Range("AJ1", LastCell)
Dim Cell As Range: For Each Cell In Rng
Cell.Value = RemoveLead0s(Cell.Value)
Next Cell
End Sub
Function RemoveLead0s(AlphaNum As String) As String
RemoveLead0s = AlphaNum
' RegExp requires "Microsoft VBScript Regular Expressions 5.5" reference
Dim RegEx As New RegExp
With RegEx
.Pattern = "^0*"
If .test(AlphaNum) Then RemoveLead0s = .Replace(AlphaNum, "")
End With
End Function
I found this code in this forumn. I want to copy this unique values into an array
Dim sheetName As String
sheetName = Application.InputBox("Enter Sheet Name")
Sheets(sheetName).Range("E:E").AdvancedFilter Action:=xlFilterCopy, _
CopyToRange:=Sheets(sheetName).Range("O:O"), unique:=True
If you want to cut out the range middleman, you can get the values directly into a 1-dimensional VBA array by using a dictionary to make sure that only unique values are grabbed:
Function UniqueVals(Col As Variant, Optional SheetName As String = "") As Variant
'Return a 1-based array of the unique values in column Col
Dim D As Variant, A As Variant, v As Variant
Dim i As Long, n As Long, k As Long
Dim ws As Worksheet
If Len(SheetName) = 0 Then
Set ws = ActiveSheet
Else
Set ws = Sheets(SheetName)
End If
n = ws.Cells(Rows.Count, Col).End(xlUp).Row
ReDim A(1 To n)
Set D = CreateObject("Scripting.Dictionary")
For i = 1 To n
v = ws.Cells(i, Col).Value
If Not D.Exists(v) Then
D.Add v, 0
k = k + 1
A(k) = k
End If
Next i
ReDim Preserve A(1 To k)
UniqueVals = A
End Function
For example, UniqueVals("E",sheetName) will return an array consisting of the unique values in column E of sheetName.
Here's another method using VBA's Collection object instead of a dictionary.
Sub Dural()
Dim sheetName As String
Dim V As Variant, COL As Collection
Dim I As Long
Dim vUniques() As Variant
sheetName = Application.InputBox("Enter Sheet Name")
'Copy all data into variant array
' This will execute significantly faster than reading directly
' from the Worksheet range
With Worksheets(sheetName)
V = .Range(.Cells(1, "E"), .Cells(.Rows.Count, "E").End(xlUp))
End With
'Collect unique values
'Use the key property of the collection object to
' ensure no duplicates are collected
' (Trying to assign the same key to two items fails with an error
' which we ignore)
Set COL = New Collection
On Error Resume Next
For I = 1 To UBound(V, 1)
COL.Add Item:=V(I, 1), Key:=CStr(V(I, 1))
Next I
On Error GoTo 0
'write collection to variant array
ReDim vUniques(1 To COL.Count)
For I = 1 To COL.Count
vUniques(I) = COL(I)
Next I
Stop
End Sub
Another version, also using a dictionary. It works for me, but I must admit that still don't know how it works (I'm a beginner). I found this code somewhere in Stackoverflow, but can't spot the place.
Dim dU1 As Object, cU1 As Variant, iU1 As Long, lrU As Long
Dim i As Integer
Private Sub Go_Click()
Set dU1 = CreateObject("Scripting.Dictionary")
lrU = Cells(Rows.Count, 1).End(xlUp).Row
cU1 = Range("E1:E" & lrU)
For iU1 = 1 To UBound(cU1, 1)
dU1(cU1(iU1, 1)) = 1
Next iU1
For i = 0 To dU1.Count - 1
MsgBox "dU1 has " & dU1.Count & " elements and key#" & i & " is " & dU1.Keys()(i)
Next
End Sub
I have to loop search multiple ranges and find match to 100k + records. Problem is I get mismatch error when assigning value to variant Arr2(i, 1).
Dim Arr1, Arr2 As Variant
Dim Wks0, Wks1 As Worksheet
Dim i As Integer
Dim Row0, Row1 As Long
Dim C As Object
Set Wks0 = Sheets("HOST")
Set Wks1 = Sheets("OFICI_BANC_USA")
'-- Create array of range -------------------------------------------*
Row0 = Wks0.Cells(Rows.Count, "A").End(xlUp).Row
Row1 = Wks1.Cells(Rows.Count, "A").End(xlUp).Row
Arr1 = Wks1.Range("A2:A" & Row1)
'-- Loop create value on sheet OFIC_BANC_USA found value in sheet HOST -----*
For i = 1 To 5 'UBound(Arr1)
With Wks0.Range("A2:A" & Row0)
Set C = .Find(Arr1(i, 1), LookAt:=xlPart,SearchOrder:=xlByRows, SearchDirection:=xlNext)
If Not C Is Nothing Then
'ReDim Preserve Arr2(i, 1)
Arr2(i, 1) = "OK"
Else
Arr2(i, 1) = "NO"
End If
End With
Next
' Transpose new array onto worksheet -------------------------------*
Wks1.Range("B2:B6") = WorksheetFunction.Transpose(Arr2)
'Arr1 = Nothing
'Arr2 = Nothing
I think you want to deal with a two-dimensioned array for the values coming in from wks1 (since you have no choice in the matter) and a single dimensioned array to hold the OK / NO values before stuffing them back into the worksheet.
Sub t()
Dim Arr0() As Variant, Arr1() As Variant, Arr2() As Variant
Dim Wks0 As Worksheet, Wks1 As Worksheet
Dim i As Long
Dim Row0 As Long, Row1 As Long
Dim C As Range
Set Wks0 = Sheets("HOST")
Set Wks1 = Sheets("OFICI_BANC_USA")
'-- Create array of range -------------------------------------------*
Row0 = Wks0.Cells(Wks0.Rows.Count, "A").End(xlUp).Row
Row1 = Wks1.Cells(Wks1.Rows.Count, "A").End(xlUp).Row
Arr1 = Wks1.Range("A2:A" & Row1)
'-- Loop create value on sheet OFIC_BANC_USA found value in sheet HOST -----*
For i = 1 To UBound(Arr1, 1)
With Wks0.Range("A2:A" & Row0)
Set C = .Find(Arr1(i, 1), LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext)
ReDim Preserve Arr2(i) '<~~ NOTE ReDim single dimensioned array here!
If Not C Is Nothing Then
Arr2(i) = "OK"
Else
Arr2(i) = "NO"
End If
End With
Next
' Transpose new array onto worksheet -------------------------------*
Wks1.Range("B2").Resize(UBound(Arr2), 1) = WorksheetFunction.Transpose(Arr2)
End Sub
Note where I've redimmed arr2. It's going to get a value either way so you need to extend its size in preparation to receive an OK / NO.
Scripting.Dictionary
Sub tt()
Dim arr As Variant, dHOST As Object
Dim Wks0 As Worksheet, Wks1 As Worksheet
Dim i As Long, j As Long
Dim Row0 As Long, Row1 As Long
Dim c As Range, rHOST As Range
Debug.Print Timer
Application.EnableEvents = False
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Set Wks0 = Worksheets("HOST")
Set Wks1 = Sheets("OFICI_BANC_USA")
Set dHOST = CreateObject("Scripting.Dictionary")
dHOST.CompareMode = vbTextCompare
'-- Create dictionary of HOST range --------------------------
Row0 = Wks0.Cells(Wks0.Rows.Count, "A").End(xlUp).Row
arr = Wks0.Range("A2:D" & Row0).Value2
For i = LBound(arr, 1) To UBound(arr, 1)
For j = LBound(arr, 2) To UBound(arr, 2)
'If Not dHOST.Exists(arr(i, j)) Then _
dHOST.Item(arr(i, j)) = j '<~~ for first match (adds 1½ seconds)
dHOST.Item(arr(i, j)) = j '<~~ for overwrite match
Next j
Next i
'-- Create array of OFICI_BANC_USA range ----------------------
Row1 = Wks1.Cells(Wks1.Rows.Count, "A").End(xlUp).Row
arr = Wks1.Range("A2:E" & Row1).Value2
For i = LBound(arr, 1) To UBound(arr, 1)
For j = LBound(arr, 2) + 1 To UBound(arr, 2)
arr(i, j) = "NO" '<~~ seed all NO matches
Next j
Next i
'-- Loop arrayed values from sheet OFIC_BANC_USA found value in dictionary HOST values --
For i = LBound(arr, 1) To UBound(arr, 1)
If dHOST.Exists(arr(i, 1)) Then _
arr(i, dHOST.Item(arr(i, 1)) + 1) = "OK"
Next i
' Stuff it all back into worksheet -------------------------------*
With Wks1.Range("A2:E" & Row1)
.Cells = arr
End With
Application.Calculation = xlCalculationAutomatic
Application.EnableEvents = True
Application.ScreenUpdating = True
Debug.Print Timer
End Sub
200K records in column A of OFICI_BANC_USA worksheet
4 columns # 50K rows each in HOSTS worksheet
~76% match rate
14.73 seconds start-to-finish
In addition to #VincentG's comment, you need to explicitly state which Rows you're using. Also, I uncommented the ReDim, and it seems to be working now:
Sub t()
Dim Arr0() As Variant, Arr1() As Variant, Arr2() As Variant
Dim Wks0 As Worksheet, Wks1 As Worksheet
Dim i As Integer
Dim Row0 As Long, Row1 As Long
Dim C As Object
Set Wks0 = Sheets("HOST")
Set Wks1 = Sheets("OFICI_BANC_USA")
'-- Create array of range -------------------------------------------*
Row0 = Wks0.Cells(Wks0.Rows.Count, "A").End(xlUp).Row
'Arr0 = Wks0.Range("A2:A" & Row0)
Row1 = Wks1.Cells(Wks1.Rows.Count, "A").End(xlUp).Row
Arr1 = Wks1.Range("A2:A" & Row1)
'-- Loop create value on sheet OFIC_BANC_USA found value in sheet HOST -----*
For i = 1 To 5 'UBound(Arr1)
With Wks0.Range("A2:A" & Row0)
Set C = .Find(Arr1(i, 1), LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext)
If Not C Is Nothing Then
ReDim Preserve Arr2(i, 1)
Arr2(i, 1) = "OK"
Else
Arr2(i, 1) = "NO"
End If
End With
Next
' Transpose new array onto worksheet -------------------------------*
Wks1.Range("B2:B6") = WorksheetFunction.Transpose(Arr2)
'Arr0 = Nothing
'Arr1 = Nothing
'Arr2 = Nothing
End Sub
I think I am understanding what you are trying to do. I set my two sheets up like this:
Then using the following code:
Sub jorge()
Application.ScreenUpdating = False
Dim Arr1 As Variant, Arr2 As Variant, Arr3 As Variant
Dim Wks0 As Worksheet, Wks1 As Worksheet
Dim i As Long, j As Long, k As Long
Dim Row0 As Long, Row1 As Long
Set Wks0 = Sheets("HOST")
Set Wks1 = Sheets("OFICI_BANC_USA")
'-- Create array of range -------------------------------------------*
Row0 = Wks0.Cells(Rows.Count, "A").End(xlUp).Row
Row1 = Wks1.Cells(Rows.Count, "A").End(xlUp).Row
Arr1 = Wks1.Range("A2:A" & Row1)
ReDim Arr2(1 To Row1, 1 To 4)
Arr3 = Wks0.Range("A2:D" & Row0)
'-- Loop create value on sheet OFIC_BANC_USA found value in sheet HOST -----*
For i = 1 To UBound(Arr1, 1)
For j = 1 To UBound(Arr3, 2)
Arr2(i, j) = "NO"
For k = 1 To UBound(Arr3, 1)
If Arr3(k, j) = Arr1(i, 1) Then
Arr2(i, j) = "OK"
Exit For
End If
Next k
Next j
Next i
Wks1.Range("B2").Resize(Row1, 4).value = Arr2
Application.ScreenUpdating = true
End Sub
I get this:
This formula will do the same thing, put this in B2:
=IF(ISNUMBER(MATCH($A2,HOST!A:A,0)),"OK","NO")
Copy across and down. This may be prohibitive with the sheer number of calculations, but it is here if you want to try it.