cnt = 1
Dim txt As String
' The assumption is that the array of data which is the target of the searching is on
'"sheet1"
With Worksheets("sheet1")
' this finds the last row with data in it in column B of sheet 1
lastrow = .Cells(Rows.Count, "B").End(xlUp).Row
' this loads all the data from the worksheet from columns 1 to 36 (columns A to AJ)
' and rows 1 to the last row which has data in it as found in column B
inarr = Range(.Cells(1, 1), .Cells(lastrow, 36))
End With
' The assumption is that there is a list of data in column A on sheet2 where
' you want to find the matching values in column B of sheet1 and then pick data fromthe same row in sheet 1
With Worksheets("sheet2")
' this finds the last row with data in it in column A of sheet2
lastrow2 = .Cells(Rows.Count, "A").End(xlUp).Row
' this loads all the data in column A of sheet2 into a variant array
search4 = Range(.Cells(1, 1), .Cells(lastrow2, 1))
End With
' This outer loop goes down each row column A of sheet 2
' Note i have swapped the two loops round becasuse it will work better that way
For j = 1 To lastrow2
' this inner loop goes down each row of sheet 1
For i = 1 To lastrow
' i Have added an extra if here to chekc for blank cells
If inarr(i, 2) <> "" Then
' this is the critical check: it checks in turn each value in column A of sheet 2
' which is in search4 (j,1)
' It checks this against each value in column B of sheet 1 , this is in
' inarr(i,2). (i is the row number and 2 is the column number )
If search4(j, 1) = inarr(i, 2) Then
' if they are equal, then i will give you the row number on sheet 1 with all the data for that row
' Since we loaded all the columns from sheet 1 into the variant array
' you can access the values directly by referring to the variant arary inarr.
' for example inarr(i,1) will be the value from column A , inarr(i,36) will be column AJ
' inarr(i,10) will be column 10 ,etc
For k = 3 To 36
' do what ever you want to do with the values from C to AJ here
txt = inarr(i, k)
If cnt < 6 Then
MsgBox (txt)
cnt = cnt + 1
End If
Next k
End If
End If
Next i
Next j
if search4(j,1)= inarr(i,2) and search4(j,2)= inarr(i,3) then
Sub testlookup()
Dim lastrow, lastrow2, i As Long
Dim Searchfor, j, inarr As Variant
lastrow = Cells(Rows.Count, "A").End(xlUp).Row
lastrow2 = Cells(Rows.Count, "E").End(xlUp).Row
inarr = Range(Cells(1, 1), Cells(lastrow, 2))
On Error Resume Next
For i = 2 To lastrow2
For j = 2 To lastrow
Searchfor = Cells(i, 5)
If inarr(j, 1) = Searchfor Then
Cells(i, 6) = inarr(j, 2)
Exit For
End If
Next j
Next i
End Sub
Yes there is a much faster way of doing it and that is using variant arrays. The main reason this is faster is because VBA is very slow at accessing the worksheet, so the way to speed up VBA is to minimise the number of accesses to any of the worksheets. One thing to realise is that the time taken to load a singe cell into VBa is almost the same as the time taken to load a large range of data into VBa. So to speed up the process of looking for a match DON'T use the EXCEL functions operating on ranges on the worksheet , load all the data in memory usng variant arrays and then do the searching in memory . The code below does a very simple VLookup equivalent. I have two lists of data in column A and B I have the item I want to match against column A in Cell E1, it puts the results in F1
This code will be extremely fast even over 10000 rows.
Code:lastrow = Cells(Rows.Count, "A").End(xlUp).Row inarr = Range(Cells(1, 1), Cells(lastrow, 2)) Searchfor = Cells(1, 5) For i = 1 To lastrow If inarr(i, 1) = Searchfor Then Cells(1, 6) = inarr(i, 2) Exit For End If Next i
Obviously without more details of your exact layout I can't give any more detailed help
Sub testlookup()
Dim lastrow, lastrow2, i As Long
Dim Searchfor, j, inarr As Variant
lastrow = Cells(Rows.Count, "A").End(xlUp).Row
lastrow2 = Cells(Rows.Count, "E").End(xlUp).Row
inarr = Range(Cells(1, 1), Cells(lastrow, 2))
' load variant array with sercha variables
searcharr = Range(Cells(1, 5), Cells(lastrow, 5))
' define an output aray
outarr = Range(Cells(1, 6), Cells(lastrow, 6))
On Error Resume Next
For i = 2 To lastrow2
For j = 2 To lastrow
Searchfor = searcharr(i, 1)
If inarr(j, 1) = Searchfor Then
outarr(i, 1) = inarr(j, 2)
Exit For
End If
Next j
Next i
' writeout the output array
Range(Cells(1, 6), Cells(lastrow, 6)) = outarr
End Sub
Sub testlookup()
Dim lastrow, lastrow2, i As Long
Dim Searchfor, j, inarr As Variant
lastrow = Cells(Rows.Count, "A").End(xlUp).Row
lastrow2 = Cells(Rows.Count, "E").End(xlUp).Row
inarr = Range(Cells(1, 1), Cells(lastrow, 2))
' load variant array with sercha variables
searcharr = Range(Cells(1, 5), Cells(lastrow2, 5))
' define an output aray
outarr = Range(Cells(1, 6), Cells(lastrow2, 6))
On Error Resume Next
For i = 2 To lastrow2
For j = 2 To lastrow
Searchfor = searcharr(i, 1)
If inarr(j, 1) = Searchfor Then
outarr(i, 1) = inarr(j, 2)
Exit For
End If
Next j
Next i
' writeout the output array
Range(Cells(1, 6), Cells(lastrow, 6)) = outarr
End Sub
' writeout the output array
Range(Cells(1, 6), Cells(lastrow2, 6)) = outarr
Option Explicit
Public Sub FastWB(Optional ByVal opt As Boolean = True)
With Application
.Calculation = IIf(opt, xlCalculationManual, xlCalculationAutomatic)
.DisplayAlerts = Not opt
.DisplayStatusBar = Not opt
.EnableAnimations = Not opt
.EnableEvents = Not opt
.ScreenUpdating = Not opt
End With
FastWS , opt
End Sub
Public Sub FastWS(Optional ByVal ws As Worksheet = Nothing, _
Optional ByVal opt As Boolean = True)
If ws Is Nothing Then
For Each ws In Application.ActiveWorkbook.Sheets
EnableWS ws, opt
Next
Else
EnableWS ws, opt
End If
End Sub
Private Sub EnableWS(ByVal ws As Worksheet, ByVal opt As Boolean)
With ws
.DisplayPageBreaks = False
.EnableCalculation = Not opt
.EnableFormatConditionsCalculation = Not opt
.EnablePivotTable = Not opt
End With
End Sub
Public Function GetMaxCell(Optional ByRef Rng As Range = Nothing) As Range
'Returns the last cell containing a value, or A1 if Worksheet is empty
Const NONEMPTY As String = "*"
Dim lRow As Range, lCol As Range
If Rng Is Nothing Then Set Rng = Application.ActiveWorkbook.ActiveSheet.UsedRange
If WorksheetFunction.CountA(Rng) = 0 Then
Set GetMaxCell = Rng.Parent.Cells(1, 1)
Else
With Rng
Set lRow = .Cells.Find(What:=NONEMPTY, LookIn:=xlFormulas, _
After:=.Cells(1, 1), _
SearchDirection:=xlPrevious, _
SearchOrder:=xlByRows)
If Not lRow Is Nothing Then
Set lCol = .Cells.Find(What:=NONEMPTY, LookIn:=xlFormulas, _
After:=.Cells(1, 1), _
SearchDirection:=xlPrevious, _
SearchOrder:=xlByColumns)
Set GetMaxCell = .Parent.Cells(lRow.Row, lCol.Column)
End If
End With
End If
End Function
I realised there was a slight error in my code which wouldn't stop it working but make it very slightly slower( cut and paste!!)
This corrects it:
Code:Sub testlookup() Dim lastrow, lastrow2, i As Long Dim Searchfor, j, inarr As Variant lastrow = Cells(Rows.Count, "A").End(xlUp).Row lastrow2 = Cells(Rows.Count, "E").End(xlUp).Row inarr = Range(Cells(1, 1), Cells(lastrow, 2)) ' load variant array with sercha variables searcharr = Range(Cells(1, 5), Cells(lastrow2, 5)) ' define an output aray outarr = Range(Cells(1, 6), Cells(lastrow2, 6)) On Error Resume Next For i = 2 To lastrow2 For j = 2 To lastrow Searchfor = searcharr(i, 1) If inarr(j, 1) = Searchfor Then outarr(i, 1) = inarr(j, 2) Exit For End If Next j Next i ' writeout the output array Range(Cells(1, 6), Cells(lastrow, 6)) = outarr End Sub
Could anybody download this Excel file ?I uploaded an Excel file with some benchmark tests.
https://www.dropbox.com/s/p1yn2ewttdc7n6o/Binair_Zoeken3g.xlsb?dl=0