VBA Vlookup with Scripting Dictionary

时间:2017-07-14 12:43:00

标签: excel vba performance excel-vba dictionary

我有2个工作表,第一个有40k +(Sheet1S)条目,我必须在第二张(Sheet2S)中查看,它有300k +条目。

我已经编写了这个脚本来运行基于脚本dictonary的vlookup,如果我将for循环调整为10行(我取消注释实际的for循环),它可以工作。但是,如果我使用所有行,则需要很长时间:

Sub aTest()
    Dim a As Variant, i As Long
    With CreateObject("Scripting.Dictionary")
        a = Sheets("Sheet2S").Range("A1").CurrentRegion.Value
        For i = 2 To 10
       'For i = 2 To UBound(a, 1)
       .Item(a(i, 1)) = Application.Index(a, i, 0)
    Next

    a = Sheets("Sheet1S").Range("A1").CurrentRegion.Value
   'For i = 2 To UBound(a, 1)
    For i = 2 To 10
        If .exists(a(i, 1)) Then
           a(i, 2) = .Item(a(i, 1))(2)
           'a(i, 4) = .Item(a(i, 2))(3)
        Else
           a(i, 2) = "#N/A"
        End If
    Next i
    End With
    Sheets("Sheet1S").Range("a1").CurrentRegion.Value = a
End Sub

现在根据旧线程(How to optimize vlookup for high search count ? (alternatives to VLOOKUP)),字典方法应该只有几秒钟。如果我使用Application.Vlookup,对于完全相同的工作表,我需要长达10分钟,这对我来说太长了。我正在使用Excel 2016,并且我已经添加了Microsoft Scripting Runtime。难道我做错了什么?

提前致谢。

最佳

1 个答案:

答案 0 :(得分:0)

我测试了你的实现,没有Index(),并且限制为2列:花了2.2秒:

Option Explicit

'Use Early Binding: VBA Editor -> Tools -> References -> Add Microsoft Scripting Runtime

Public Sub VLookUpTest()
    Const N = "#,###"
    Dim a As Variant, i As Long, d As Dictionary
    Dim lr1 As Long, lr2 As Long, t As Double, tt As String

    t = Timer
    Set d = New Dictionary
    With d

        a = Sheets("Sheet2S").Range("A1").CurrentRegion.Columns("A:B").Formula
        lr2 = UBound(a)
        For i = 2 To lr2
            .Item(a(i, 1)) = a(i, 2)
        Next

        a = Sheets("Sheet1S").Range("A1").CurrentRegion.Columns("A:B").Formula
        lr1 = UBound(a)
        For i = 2 To lr1
            a(i, 2) = IIf(.exists(a(i, 1)), .Item(a(i, 1)), "#N/A")
        Next i
        Sheets("Sheet1S").Range("a1").CurrentRegion.Columns("A:B").Formula = a

    End With

tt = Format(Timer - t, "#,###.00") & " seconds"
Debug.Print "S1 rows: " & Format(lr1, N) & "; S2 rows: " & Format(lr2, N) & "; Time: " & tt

    'S1 rows: 50,001; S2 rows: 350,001; Time: 2.23 seconds

End Sub