Excel VBA 逆引き集 | 2段Dictionary

Excel VBA
スポンサーリンク

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で高速に実現 できます。

タイトルとURLをコピーしました