2017-07-14 89 views
0

我有2个工作表,第一个有40k +(Sheet1S)条目,我必须在第二个工作表(Sheet2S)中查找,它有300k条目。VBA Vlookup with Scripting Dictionary

我已经编写了这个脚本来运行基于脚本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脚本运行时。难道我做错了什么?

在此先感谢。

最佳

+0

你实现这个方法看似寻常给我。多少列?你在这两个列表中有没有重复的地方? –

+0

两张表都包含15列,可能有重复。然而,随着保罗比卡的实施,它就像一个魅力。 – Uwewewe

回答

0

我测试你的实现,而不指数(),并限制在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 
+1

哇,这太神奇了!非常感谢。为了好玩,我已经在Sheet1和Sheet2上用300000x15进行了测试,考虑到表单的大小,它仍然非常快。 'S1行:306 271; S2行:306 271;时间:267,23秒 – Uwewewe