Consider the scenario where you have a bunch of assets, and you have numbers associated to each type of assets. We are changing these numbers from set A to set B, so I am writing a script to populate some values for Set B in a new column in excel based on the original set A number. There are 110,000 items in each set.
Due to the information being scattered across a lot of sheets, I have adopted a VBA approach. My original code executed via a simple comparison of the strings:
Public Function SearchSAP(StkCd As Long) As Long
Dim wb As Workbook
Dim shSAP As Worksheet
Dim i As Long
' SAP sheet name is fixed and does not change
Set wb = ActiveWorkbook
Set shSAP = wb.Worksheets("SAP")
' i is the start row of the SAP sheet for data
i = 2
' Define no-match value as -1
SearchSAP = -1
Do While i < shSAP.UsedRange.Rows.Count And i < 106212
If shSAP.Cells(i, 1).value = Stkcd Then
SearchSAP = shSAP.Cells(i, 2).value
Exit Do
End If
i = i + 1
Loop
Set shSAP = Nothing
Set wb = Nothing
End Function
This function took me forever to execute, probably closer to like 15-20 minutes on an i7 net 2.4 GHz core. I almost thought I have coded it wrong with an infinity loop. when it finally gave me "-1" did I realize that it really did take that long. Researching on stackoverflow, I found the post " How to optimize vlookup for high search count ? (alternatives to VLOOKUP) " which seems to indicate that dictionary is the way to go. So I tried that:
Public Function SearchSAP(StkCd As Long) As Long
Dim wb As Workbook
Dim shSAP As Worksheet
Dim Dict As New Scripting.Dictionary
Dim i As Long
' SAP sheet name is fixed and does not change
Set wb = ActiveWorkbook
Set shSAP = wb.Worksheets("SAP")
' i is the start row of the SAP sheet for data
i = 2
' Define null value as -1
SearchSAP = -1
Do While i < shSAP.UsedRange.Rows.Count And i < 106212
Dict.Add shSAP.Cells(i, 1).value, shSAP.Cells(i, 2).value
i = i + 1
Loop
Do While i < shSAP.UsedRange.Rows.Count And i < 106212
If Dict.Exists(StkCd) Then
SearchSAP = Dict(StkCd)
Exit Do
End If
i = i + 1
If i = 150000 Then
Debug.Print "Break"
End If
Loop
Set shSAP = Nothing
Set wb = Nothing
End Function
But this function still took a good 5 mins or so to figure itself out. My question then is, am I approaching this in a pretty dumb manner? How can I do this more efficiently? I am not a full time programmer, so I wasn't sure what I can do to optimize this. Any help would be great!