d-s*_*yer 23 performance vba dictionary excel-vba vlookup
我正在寻找vlookup的替代品,在感兴趣的环境中提高性能.
上下文如下:
VLOOKUP是FALSE)一个架构来解释:
参考表:( "sheet1")
A B
1
2 key1 data1
3 key2 data2
4 key3 data3
... ... ...
99999 key99998 data99998
100000 key99999 data99999
100001 key100000 data100000
100002
Run Code Online (Sandbox Code Playgroud)
查找表:
A B
1
2 key51359 =VLOOKUP(A2;sheet1!$A$2:$B$100001;2;FALSE)
3 key41232 =VLOOKUP(A3;sheet1!$A$2:$B$100001;2;FALSE)
4 key10102 =VLOOKUP(A3;sheet1!$A$2:$B$100001;2;FALSE)
... ... ...
99999 key4153 =VLOOKUP(A99999;sheet1!$A$2:$B$100001;2;FALSE)
100000 key12818 =VLOOKUP(A100000;sheet1!$A$2:$B$100001;2;FALSE)
100001 key35032 =VLOOKUP(A100001;sheet1!$A$2:$B$100001;2;FALSE)
100002
Run Code Online (Sandbox Code Playgroud)
在我的Core i7 M 620 @ 2.67 GHz上,计算时间约为10分钟
在这种情况下,VLOOKUP是否有更好的性能?
d-s*_*yer 22
我考虑了以下替代方案:
比较的表现是:
使用相同的参考表
1)查找表:( vlookup数组公式版)
A B
1
2 key51359 {=VLOOKUP(A2:A10001;sheet1!$A$2:$B$100001;2;FALSE)}
3 key41232 formula in B2
4 key10102 ... extends to
... ... ...
99999 key4153 ... cell B100001
100000 key12818 ... (select whole range, and press
100001 key35032 ... CTRL+SHIFT+ENTER to make it an array formula)
100002
Run Code Online (Sandbox Code Playgroud)
2)查找表:(匹配+索引版)
A B C
1
2 key51359 =MATCH(A2;sheet1!$A$2:$A$100001;) =INDEX(sheet1!$B$2:$B$100001;B2)
3 key41232 =MATCH(A3;sheet1!$A$2:$A$100001;) =INDEX(sheet1!$B$2:$B$100001;B3)
4 key10102 =MATCH(A4;sheet1!$A$2:$A$100001;) =INDEX(sheet1!$B$2:$B$100001;B4)
... ... ... ...
99999 key4153 =MATCH(A99999;sheet1!$A$2:$A$100001;) =INDEX(sheet1!$B$2:$B$100001;B99999)
100000 key12818 =MATCH(A100000;sheet1!$A$2:$A$100001;) =INDEX(sheet1!$B$2:$B$100001;B100000)
100001 key35032 =MATCH(A100001;sheet1!$A$2:$A$100001;) =INDEX(sheet1!$B$2:$B$100001;B100001)
100002
Run Code Online (Sandbox Code Playgroud)
3)查询表:( vbalookup版)
A B
1
2 key51359 {=vbalookup(A2:A50001;sheet1!$A$2:$B$100001;2)}
3 key41232 formula in B2
4 key10102 ... extends to
... ... ...
50000 key91021 ...
50001 key42 ... cell B50001
50002 key21873 {=vbalookup(A50002:A100001;sheet1!$A$2:$B$100001;2)}
50003 key31415 formula in B50001 extends to
... ... ...
99999 key4153 ... cell B100001
100000 key12818 ... (select whole range, and press
100001 key35032 ... CTRL+SHIFT+ENTER to make it an array formula)
100002
Run Code Online (Sandbox Code Playgroud)
注意:对于某些(外部内部)原因,vbalookup一次无法返回超过65536个数据.所以我不得不将数组公式分成两部分.
以及相关的VBA代码:
Function vbalookup(lookupRange As Range, refRange As Range, dataCol As Long) As Variant
Dim dict As New Scripting.Dictionary
Dim myRow As Range
Dim I As Long, J As Long
Dim vResults() As Variant
' 1. Build a dictionnary
For Each myRow In refRange.Columns(1).Cells
' Append A : B to dictionnary
dict.Add myRow.Value, myRow.Offset(0, dataCol - 1).Value
Next myRow
' 2. Use it over all lookup data
ReDim vResults(1 To lookupRange.Rows.Count, 1 To lookupRange.Columns.Count) As Variant
For I = 1 To lookupRange.Rows.Count
For J = 1 To lookupRange.Columns.Count
If dict.Exists(lookupRange.Cells(I, J).Value) Then
vResults(I, J) = dict(lookupRange.Cells(I, J).Value)
End If
Next J
Next I
vbalookup = vResults
End Function
Run Code Online (Sandbox Code Playgroud)
注意:Scripting.Dictionary需要Microsoft Scripting Runtime手动添加参考(Excel VBA窗口中的工具 - >参考菜单)
结论:
在这种情况下,使用字典的VBA比使用VLOOKUP快100倍,比MATCH/INDEX快20倍
您也可以考虑使用"双Vlookup"方法(不是我的想法 - 在别处看到).我在工作表2(随机分类)上的100,000个查找值上测试了它,其数据集与您在表1中描述的数据集相同,并且在不到4秒的时间内进行了计时.代码也有点简单.
Sub FastestVlookup()
With Sheet2.Range("B1:B100000")
.FormulaR1C1 = _
"=IF(VLOOKUP(RC1,Sheet1!R1C1:R100000C1,1)=RC1,VLOOKUP(RC1,Sheet1!R1C1:R100000C2,2),""N/A"")"
.Value = .Value
End With
End Sub
Run Code Online (Sandbox Code Playgroud)
小智 5
切换到Excel 2013并使用数据模型.在那里,您可以在两个表中定义具有唯一ID键的列,并将这两个表与数据透视表中的关系绑定.如果绝对必要,您可以使用Getpivotdata()填充第一个表.我有一个~250K行的表在类似的~250K行表中执行vlookup.停止Excel一小时后计算它.使用数据模型花了不到10秒.
| 归档时间: |
|
| 查看次数: |
41704 次 |
| 最近记录: |