2段Dictionary(入れ子構造)
Excel VBAの Dictionary は「キーと値のペア」を管理する便利な入れ物ですが、値にさらにDictionaryを入れることで 2段構造(入れ子) を作ることができます。これにより「商品カテゴリ → 商品名 → 数量」といった階層的なデータを扱えるようになります。初心者向けに、コード例やテンプレートをかみ砕いて説明します。
基本の考え方
- 外側Dictionary → 大分類(カテゴリや顧客など)。
- 内側Dictionary → 小分類(商品や明細など)。
- アクセス方法:
dict("カテゴリ")("商品")のように二重で参照。
- 用途:
- 商品カテゴリごとの集計。
- 顧客ごとの購入履歴。
- 多段階のデータ管理。
テンプレ1:カテゴリ→商品→数量の2段Dictionary
Sub TwoLevelDict_Basic()
Dim dictOuter As Object: Set dictOuter = CreateObject("Scripting.Dictionary")
Dim dictInner As Object
' フルーツカテゴリ
Set dictInner = CreateObject("Scripting.Dictionary")
dictInner("りんご") = 10
dictInner("みかん") = 20
dictOuter("フルーツ") = dictInner
' 野菜カテゴリ
Set dictInner = CreateObject("Scripting.Dictionary")
dictInner("にんじん") = 15
dictInner("キャベツ") = 25
dictOuter("野菜") = dictInner
' 出力
Dim cat As Variant, item As Variant
For Each cat In dictOuter.Keys
Debug.Print "カテゴリ=" & cat
For Each item In dictOuter(cat).Keys
Debug.Print " 商品=" & item, "数量=" & dictOuter(cat)(item)
Next item
Next cat
End Sub
VB- 結果:
カテゴリ=フルーツ 商品=りんご 数量=10 商品=みかん 数量=20 カテゴリ=野菜 商品=にんじん 数量=15 商品=キャベツ 数量=25
テンプレ2:シートデータを2段Dictionaryに格納
Sub TwoLevelDict_FromSheet()
Dim ws As Worksheet: Set ws = Worksheets("Data")
Dim rg As Range: Set rg = ws.Range("A2:C20") ' A=カテゴリ, B=商品, C=数量
Dim v As Variant: v = rg.Value
Dim dictOuter As Object: Set dictOuter = CreateObject("Scripting.Dictionary")
Dim dictInner As Object
Dim r As Long, cat As String, item As String
For r = 1 To UBound(v, 1)
cat = v(r, 1)
item = v(r, 2)
If dictOuter.Exists(cat) Then
Set dictInner = dictOuter(cat)
Else
Set dictInner = CreateObject("Scripting.Dictionary")
dictOuter(cat) = dictInner
End If
If dictInner.Exists(item) Then
dictInner(item) = dictInner(item) + v(r, 3)
Else
dictInner(item) = v(r, 3)
End If
Next r
' 出力
Dim k As Variant, j As Variant, i As Long: i = 2
For Each k In dictOuter.Keys
For Each j In dictOuter(k).Keys
ws.Cells(i, 5).Value = k
ws.Cells(i, 6).Value = j
ws.Cells(i, 7).Value = dictOuter(k)(j)
i = i + 1
Next j
Next k
End Sub
VB- ポイント:
- A列=カテゴリ、B列=商品、C列=数量を読み込む。
- E列以降に「カテゴリ・商品・集計数量」を出力。
テンプレ3:アクセス方法(特定カテゴリの商品を取得)
Sub TwoLevelDict_Access()
Dim dictOuter As Object: Set dictOuter = CreateObject("Scripting.Dictionary")
Dim dictInner As Object: Set dictInner = CreateObject("Scripting.Dictionary")
dictInner("りんご") = 10
dictInner("みかん") = 20
dictOuter("フルーツ") = dictInner
MsgBox "フルーツカテゴリのりんご数量=" & dictOuter("フルーツ")("りんご")
End Sub
VB- ポイント:
dictOuter("カテゴリ")("商品")で二段アクセス。
テンプレ4:2段Dictionaryで件数カウント
Sub TwoLevelDict_Count()
Dim dictOuter As Object: Set dictOuter = CreateObject("Scripting.Dictionary")
Dim dictInner As Object
' 顧客ごとの購入商品件数
Set dictInner = CreateObject("Scripting.Dictionary")
dictInner("りんご") = 2
dictInner("みかん") = 1
dictOuter("顧客A") = dictInner
Set dictInner = CreateObject("Scripting.Dictionary")
dictInner("バナナ") = 3
dictInner("ぶどう") = 2
dictOuter("顧客B") = dictInner
' 出力
Dim cust As Variant, prod As Variant
For Each cust In dictOuter.Keys
Debug.Print "顧客=" & cust
For Each prod In dictOuter(cust).Keys
Debug.Print " 商品=" & prod, "件数=" & dictOuter(cust)(prod)
Next prod
Next cust
End Sub
VB例題で練習
'例1:カテゴリ→商品→数量の2段構造
Sub Example1()
TwoLevelDict_Basic
End Sub
'例2:シートデータを2段Dictionaryに格納
Sub Example2()
TwoLevelDict_FromSheet
End Sub
'例3:特定カテゴリの商品を取得
Sub Example3()
TwoLevelDict_Access
End Sub
'例4:顧客ごとの購入件数を管理
Sub Example4()
TwoLevelDict_Count
End Sub
VB初心者向けポイント
- Dictionaryの値にDictionaryを入れる → 2段構造が作れる。
- Existsで判定して追加 → 新しいカテゴリや商品を安全に追加。
- 二段アクセスで値取得 →
dictOuter("カテゴリ")("商品")。 - シートデータも高速処理 → Rangeを配列に読み込んで2段Dictionaryに格納。
- 実務で便利 → 「カテゴリ別集計」「顧客別購入履歴」「地域別売上」などに応用可能。
👉 この「2段Dictionaryテンプレ」を覚えておけば、SQLのような階層的なデータ管理や集計を Excel VBAで高速に実現 できます。
