次の代替案を検討しました。
- VLOOKUP 配列式
- マッチ/インデックス
- VBA (辞書を使用)
比較したパフォーマンスは次のとおりです。
- VLOOKUP 単純式 : ~10 分
- VLOOKUP 配列式 : ~10 分 (1:1 パフォーマンス インデックス)
- MATCH / INDEX : ~2 分 (5:1 パフォーマンス インデックス)
- VBA (辞書を使用): ~6 秒 (100:1 パフォーマンス インデックス)
同じ参照シートを使用する
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
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
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
注意: なんらかの (外部内部) 理由により、vbalookup は一度に 65536 を超えるデータを返すことができません。そのため、配列数式を 2 つに分割する必要がありました。
および関連する 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
注意:Scripting.Dictionary
参照をMicrosoft Scripting Runtime
手動で追加する必要があります (Excel VBA ウィンドウの [ツール] -> [参照] メニュー)。
結論 :
このコンテキストでは、辞書を使用する VBA は、VLOOKUP を使用するよりも 100 倍速く、MATCH/INDEX よりも 20 倍高速です。