検証環境: 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) で書き戻します。
