🚀The world's best VBA AI has evolved. ExcelMaster is now an autonomous Agent.Read more →
Back to Blog

Excel VBA Dictionary の使い方 — 検索・重複削除・グループ化(6つの例)

|

Excel VBA Dictionary の使い方 — 検索・重複削除・グループ化(6つの例)

検証環境: Excel 365 v2509 · Excel 2021 · Excel 2019 · 最終確認 2026-06-05

要点 — Dictionary は キー → 値 のペアを格納し、ループなしでキーから値を一瞬で取り出します。作って、入れて、調べる:

Sub Dictの基本()
    Dim dict As Object
    Set dict = CreateObject("Scripting.Dictionary")

    dict("AAPL") = 182.5          ' キーで追加または更新
    dict("MSFT") = 410.2

    If dict.Exists("AAPL") Then    ' 読む前に存在を確認
        MsgBox "AAPL = " & dict("AAPL")
    End If
End Sub

配列が1件を見つけるのに全件を走査するのに対し、Dictionary は目的に直行します。だからアナリストは主に2つの用途で使います——重複削除集計/グループ化です。どちらも下にあります。

なぜ Dictionary か——そしてキーとは

キーは一意のラベル、値はそのキーの下にしまうものです。キーは一意でなければならないので、「これは前に見たか?」「各々いくつ?」という問いには Dictionary が最適です。キーによる検索は O(1)——件数に関係なく実質一瞬です。

例1 — 準備:実行時バインディングと事前バインディング

Dictionary を作る方法は2つあり、取り違えると悪名高いエラー 「ユーザー定義型が定義されていません」 が出ます。

' ── 実行時バインディング(設定不要、どこでも動く)──
Dim dict As Object
Set dict = CreateObject("Scripting.Dictionary")
' ── 事前バインディング(高速 + IntelliSense)──
' 先に: ツール ▸ 参照設定 ▸ "Microsoft Scripting Runtime" にチェック
Dim dict As New Scripting.Dictionary

どちらを使う? 配布するコードには実行時バインディング(相手のPCで設定不要)。開発中は補完が効く事前バインディング。本記事はそのまま動くよう実行時バインディングを使います。

例2 — 追加・更新と「サイレント追加」のコツ

データを入れる方法は2つあり、その違いが効いてきます。

dict.Add "AAPL", 182.5      ' 明示 — "AAPL" が既にあるとエラー
dict("MSFT") = 410.2        ' 代入 — 新規なら追加、あれば更新

2つ目の形がサイレント追加です。存在しないキーへの代入はそのキーを作成します。重複でエラーにならないので、次の2つのパターンがとても簡潔になります。

例3 — 読む前に .Exists(幻のキーを防ぐ)

存在しないキーを dict(key) で読むと、そのキーを暗黙的に作成します(空で)。何も追加せずに所属を判定するには、必ず .Exists を使います。

Dim sku As String
sku = Range("A2").Value

If dict.Exists(sku) Then
    Range("B2").Value = dict(sku)        ' 安全 — キーは本当に存在する
Else
    Range("B2").Value = "見つかりません"
End If

例4 — 一意のリストを作る(1パスで重複削除)⭐

定番の仕事です。A 列に重複を含む数千行があり、各値を一度だけ欲しい。サイレント追加が重複を自動でまとめます。

Sub 一意の値()
    Dim dict As Object
    Set dict = CreateObject("Scripting.Dictionary")

    Dim cell As Range
    For Each cell In Range("A2:A10000")
        If cell.Value <> "" Then dict(cell.Value) = 1   ' 重複キーは上書き、リストは一意のまま
    Next cell

    ' dict.Keys が重複削除済みのリスト — D 列に書き出す:
    Range("D2").Resize(dict.Count).Value = Application.Transpose(dict.Keys)
    MsgBox dict.Count & " 件の一意の値"
End Sub

入れ子ループも並べ替えも作業列も不要——10万行でも高速なままです。

例5 — 集計/グループ化(頻度のカウント)⭐

「地域ごとに注文が何件か」を出したい? キーを見るたびに値へ1を足します。サイレント追加は存在しないキーを0から始めるので、最初の + 1 から正しく動きます。

Sub 地域別カウント()
    Dim dict As Object
    Set dict = CreateObject("Scripting.Dictionary")

    Dim cell As Range
    For Each cell In Range("A2:A10000")          ' A 列 = 地域
        dict(cell.Value) = dict(cell.Value) + 1  ' 初回: 0 + 1
    Next cell

    ' 集計を F:G 列に出力
    Dim k As Variant, r As Long
    r = 2
    For Each k In dict.Keys
        Cells(r, 6).Value = k                    ' F = 地域
        Cells(r, 7).Value = dict(k)              ' G = 件数
        r = r + 1
    Next k
End Sub

ピボットテーブル相当のグループ化が12行で——しかも挙動を完全に制御できます。

例6 — キーと値を一緒にループ

.Keys.Items はそれぞれ0始まりの配列を返し、位置で対応しています。

Dim keys As Variant, items As Variant, i As Long
keys = dict.Keys
items = dict.Items
For i = 0 To dict.Count - 1
    Debug.Print keys(i) & " => " & items(i)
Next i

大文字小文字を区別しないキーが必要なら("AAPL" と "aapl" を同一に)、追加する前に dict.CompareMode = vbTextCompare を設定します。

Dictionary と Collection — どちらを使う

VBA には組み込みの Collection もあります。キーでアクセスしたいなら Dictionary、単純な順序付きリストなら Collection で十分です。

必要なこと Dictionary Collection
キーの存在確認 .Exists(key) なし — エラーを捕捉する
値をその場で更新 dict(key) = x 削除して再追加
全キー / 全値の取得 .Keys / .Items 不可
件数 .Count .Count
必要な準備 Scripting.Dictionary の参照設定 か CreateObject 組み込み、不要

よくある Dictionary のミス(と対処)

症状 原因 対処
「ユーザー定義型が定義されていません」 参照設定なしの As New Scripting.Dictionary 参照を追加、または実行時バインディング CreateObject(...)
「このキーは既に関連付けられています…」 既存キーへの .Add dict(key) = value で追加または更新
存在判定のたびに dict が増える If dict(key) <> "" Then がキーを作成している 代わりに dict.Exists(key) で判定
キーの Transpose が失敗/切れる 約65,536 キーを超えると Transpose の上限 キーをループして1件ずつ書く
"aapl" と "AAPL" が別々に数えられる 既定でキー比較が大文字小文字を区別 追加前に dict.CompareMode = vbTextCompare を設定

バインディングと定型処理を飛ばして、結果だけ頼む

Dictionary は重複削除とグループ化に最適な道具ですが、事前/実行時バインディング、.Exists のガード、Transpose の上限は、「一意の地域とその件数をちょうだい」というだけにしては儀式が多すぎます。ExcelMaster Agent なら自然な日本語でそのまま——「A 列の一意な地域と、その行数を一覧にして」——Dictionary もガードも出力も組み立てます。無料で試す →

関連記事

よくある質問

VBA の Dictionary とは? Dictionary(Scripting.Dictionary)はキー → 値のペアを格納し、ループなしでキーから任意の値を一瞬で取り出します。キーは一意なので、重複削除や集計・グループ化に最適です。

Excel VBA で Dictionary を作るには? 実行時バインディングは設定不要です: Dim dict As Object: Set dict = CreateObject("Scripting.Dictionary")。事前バインディングと IntelliSense を使うなら、ツール ▸ 参照設定で Microsoft Scripting Runtime にチェックし、Dim dict As New Scripting.Dictionary とします。

VBA の Dictionary と Collection の違いは? Dictionary は .Exists を持ち、値をその場で更新でき、.Keys.Items を提供します。Collection はより単純な組み込みの順序付きリストで、キーの存在確認もキーの読み取りもできません。キー検索が必要なら Dictionary を使います。

VBA の Dictionary でキーの存在を確認するには? dict.Exists(key) を使います。Dictionary を変えずに True/False を返します。If dict(key)… は避けてください——存在しないキーを読むと暗黙的に作成されます。

VBA の Dictionary で一意のリストを得るには? 元の範囲をループして dict(cell.Value) = 1 を代入します。重複キーは上書きされるので dict.Keys が重複削除済みリストになります——Range("D2").Resize(dict.Count).Value = Application.Transpose(dict.Keys) で書き戻します。