目次
はじめに
VBAで辞書(Dictionary)を使った集計処理を書く際、「キーが存在するか確認してから値を更新する」というコードをよく見かけます。しかし、辞書には便利な仕様があり、単純な数値カウントの場合はもっとシンプルに書けます。
辞書とは
辞書は「キーと値をセットで管理できる入れ物」です。商品名をキーにして個数を管理したり、社員名をキーにして売上を集計したりする際に便利です。
辞書を使うには参照設定が必要です。設定方法は以下の記事で詳しく解説しています。
参照設定を追加すると、以下のように辞書を宣言できます。
Dim dict As New Scripting.Dictionary
一般的な書き方と問題点
商品の個数をカウントする処理を書くとき、以下のようにExistsとAddを使うコードをよく見かけます。
If dict.Exists("商品A") Then
dict("商品A") = dict("商品A") + 1
Else
dict.Add "商品A", 1
End If
このコードは正しく動作しますが、キーが存在する場合と存在しない場合で処理を分けているため、少し冗長(長くて読みにくい)です。
辞書の便利な仕様
実は、辞書には「存在しないキーに値を代入すると、その場で自動的に新規作成してくれる」という仕様があります。
dict("商品A") = dict("商品A") + 1
この1行だけで、以下の処理が自動的に行われます。
- 初回(キーが存在しない場合)は
dict("商品A")がEmptyとして扱われ、数値演算では0として計算される -
0 + 1 = 1が新しいキーとして辞書に追加される - 2回目以降は既存の値に加算される
この仕様を知らないと、毎回If~Exists~Addを書くことになり、コードが冗長になってしまいます。単純なカウント処理では積極的に活用していきたいテクニックです。
実際に試してみる
実際に動作を確認できるコードを用意しました。空白のExcelブックを開き、以下の手順で試してみてください。
- 新しいExcelブックを開く
-
Alt + F11でVBエディタを開く - 「ツール」→「参照設定」から「Microsoft Scripting Runtime」にチェックを入れる
- 「挿入」→「標準モジュール」で新しいモジュールを追加
- 以下のコードを貼り付けて実行
【基本例】辞書の自動追加を確認する
Sub TestDictionaryAutoAdd()
' 辞書を作成
Dim dict As New Scripting.Dictionary
' If~Exists~Addを使わずにカウント
dict("商品A") = dict("商品A") + 1
dict("商品A") = dict("商品A") + 1
dict("商品B") = dict("商品B") + 1
dict("商品C") = dict("商品C") + 1
dict("商品A") = dict("商品A") + 1
' 結果をメッセージボックスで表示
Dim msg As String
msg = "カウント結果" & vbCrLf & vbCrLf
msg = msg & "商品A: " & dict("商品A") & "個" & vbCrLf
msg = msg & "商品B: " & dict("商品B") & "個" & vbCrLf
msg = msg & "商品C: " & dict("商品C") & "個"
MsgBox msg, vbInformation
End Sub
実行すると、以下の結果が表示されます。
カウント結果
商品A: 3個
商品B: 1個
商品C: 1個
【応用例】サンプルデータを自動生成してカウントする
シートにデータを入力する手間を省くため、サンプルデータの生成からカウント、結果表示まで全て自動で行うコードです。
Sub CountValuesWithAutoData()
' シートをクリア
Cells.Clear
' A列にサンプルデータを生成
Range("A1").Value = "りんご"
Range("A2").Value = "みかん"
Range("A3").Value = "りんご"
Range("A4").Value = "バナナ"
Range("A5").Value = "みかん"
Range("A6").Value = "りんご"
Range("A7").Value = "バナナ"
Range("A8").Value = "みかん"
Range("A9").Value = "りんご"
Range("A10").Value = "みかん"
' 辞書を作成
Dim dict As New Scripting.Dictionary
Dim cell As Range
' A1:A10の値をカウント
For Each cell In Range("A1:A10")
If cell.Value <> "" Then
dict(cell.Value) = dict(cell.Value) + 1
End If
Next cell
' C列に見出しを設定
Range("C1").Value = "商品名"
Range("D1").Value = "個数"
' 結果をC列以降に出力
Dim key As Variant
Dim i As Long: i = 2
For Each key In dict.Keys
Cells(i, 3).Value = key
Cells(i, 4).Value = dict(key)
i = i + 1
Next key
' 列幅を自動調整
Columns("A:D").AutoFit
MsgBox "カウントが完了しました" & vbCrLf & _
"A列: 元データ" & vbCrLf & _
"C-D列: 集計結果", vbInformation
End Sub
このコードを実行すると、自動的にサンプルデータが生成され、カウント結果がC-D列に出力されます。空白のブックから始めて、コピペして実行するだけで動作を確認できます。
実行後のシートは以下のようになります。
| A列(元データ) | B列(空白) | C列(商品名) | D列(個数) |
|---|---|---|---|
| りんご | 商品名 | 個数 | |
| みかん | りんご | 4 | |
| りんご | みかん | 4 | |
| バナナ | バナナ | 2 | |
| みかん | |||
| りんご | |||
| バナナ | |||
| みかん | |||
| りんご | |||
| みかん |
まとめ
辞書は「存在しないキーに代入すると自動的に新規作成してくれる」という便利な仕様があります。単純な数値のカウント処理では、If~Exists~Addを使わずに1行で書けるため、コードがすっきりします。ぜひ活用してみてください。