【VBA入門】Dictionaryオブジェクト(連想配列)の使い方を解説

  • 2024.11.29
       
【VBA入門】Dictionaryオブジェクト(連想配列)の使い方を解説

皆さんは、VBAにおけるDictionaryオブジェクト(連想配列)をご存知でしょうか?

連想配列はPythonやJavaScript、PHPなど様々なプログラミング言語で用いられており、VBAではDictionaryオブジェクトとして実装されている機能です。キーで配列内のデータを指定して参照することができるので、商品名と値段など、結び付けて管理したいデータを扱うのに便利です。

今回は、VBAでDictionaryオブジェクトを使用してみたいけどよく分からない…といった方のために、基礎的な内容から応用方法について詳しく解説していきたいと思います!

Dictionaryオブジェクトとは?

VBAではDictionaryオブジェクトというデータ型で連想配列を使うことができます。連想配列とは、Key(キーワード)Item(データ)で構成される配列のことです。Dictionaryという名が指すように、連想配列を辞書と呼ぶ場合もあります。

通常の配列では、順に割り振られたインデックス番号をもとにデータを取り出しますが、Dictionaryオブジェクトでは任意に指定したKeyにもとづいて取得します。

配列と連想配列の違いを図式化すると以下のようになります。

配列と連想配列

DictionaryオブジェクトのKeyには一般に整数や文字列を指定しますが、配列以外の他のデータ型も使用することが可能です。ただし、Keyは一意に定まる値でなければならないため、別々のItemでKeyを重複させることはできません。

Dictionaryオブジェクトの使い方

Dictionaryオブジェクトを使用する際は、以下の一覧にあるメソッドやプロパティを利用して、値の追加や削除、または格納したデータの取得や変更などを行います。

【メソッド一覧】

メソッド 内容
Add Dictionary オブジェクトに新しいキー/アイテムのペアを追加する
Exists 指定したキーが存在するかどうかをブール値で返す
Items Dictionary オブジェクト内のすべてのアイテムの配列を返す
Keys Dictionary オブジェクト内のすべてのキーの配列を返す
Remove Dictionary オブジェクトから指定したキー/アイテムのペアを削除する
RemoveAll Dictionary オブジェクト内のすべてのキー/アイテムのペアを削除する

【プロパティ一覧】

プロパティ 内容
CompareMode Dictionary オブジェクト内のキーの比較モードの設定値を返すか、新たに設定する
Count Dictionary オブジェクト内のキー/アイテムのペアの数を返す
Item Dictionary オブジェクト内のアイテムの値を返すか、新たに設定する
Key Dictionary オブジェクト内の既存のキー値に対して新しいキー値を設定

CompareModeに関しては、要素が既に含まれているDictionaryオブジェクトで設定を変更しようとすると、エラーが発生するので注意が必要です。比較モードを変えたい場合は、値を追加する前に変更する必要があります。

続けて、具体的な使用方法についても見ていきましょう。

Dictionaryを宣言・初期化・追加・参照する

DictionaryオブジェクトはExcel VBAの標準機能ではないため、使用する際は外部ライブラリを参照する必要があります。

以下のように、CreateObject関数を使ってオブジェクト型の変数に代入することで、Dictionaryオブジェクトが使えるようになります。

【基本構文】

Dim 連想配列名 As Object
Set 連想配列名 = CreateObject(“Scripting.Dictionary”)

オブジェクト型の変数に格納する際は、いずれもSetステートメントが必要です。
宣言後の初期化や要素の追加を行うには、Addメソッドを使用します。

【サンプルコード】

Sub sampleAdd()

 'Dictionaryオブジェクトの宣言
 Dim sampleDic As Object
 Set sampleDic = CreateObject("Scripting.Dictionary")
    
 'Dictionaryオブジェクトの初期化、要素の追加
 sampleDic.Add "りんご", 150
 sampleDic.Add "ぶどう", 200
 sampleDic.Add "パイナップル", 350
    
 Dim str As String, num As Integer
 Dim Keys() As Variant, Items() As Variant

 'オブジェクト内の全てのキーとアイテムを、それぞれ配列として取得
 Keys = sampleDic.Keys
 Items = sampleDic.Items

 '格納したデータを参照
 For num = 0 To 2
  str = str & Keys(num) & " : " & Items(num) & vbCrLf
 Next num
    
 MsgBox str

End Sub

【実行結果】

データを参照する方法はいくつかありますが、今回はループ処理を使って参照するために、一旦全てのキーとアイテムを配列として変数に代入しています。

Dictionaryオブジェクトの場合、アイテムに紐づくキーが連続する数値で設定されているとは限りません。ループ回数をそのままキーとして使用してしまうと、不具合が発生するので注意が必要です。

For Eachを使ってDictionaryを参照する

ループ処理でデータを参照する方法として、For Each文を使うケースも存在します。
先ほどのコードでは、ループ回数をそのまま添え字として扱うために、一旦全てのキーとアイテムを配列として取得していました。一方で、この方法を使う場合、事前にキーとアイテムを取得しておく必要が無くなるため、より簡潔に記述することができます。
サンプルコードを見てみましょう。

【サンプルコード】

Sub sampleForEach()

 Dim sampleDic As Object
 Set sampleDic = CreateObject("Scripting.Dictionary")
    
 sampleDic.Add "りんご", 150
 sampleDic.Add "ぶどう", 200
 sampleDic.Add "パイナップル", 350

 Dim str As String

 '格納したデータを参照
 For Each dicKey In sampleDic
  str = str & dicKey & " : " & sampleDic.Item(dicKey) & vbCrLf
 Next dicKey
    
 MsgBox str

End Sub

【実行結果】

先ほどのコードの一部を、For Each文に書き換えてみました。ループ処理の際に指定した変数「dicKey」にキーが順に代入されていくので、その変数を使ってアイテムを引き出しています。

事前に配列を用意しておく手間が無くなったため、より手短に記述できていることが分かるかと思います。

RemoveでDisctionaryから要素を削除する

続いて、Dictionaryオブジェクトに追加した要素を削除する方法について解説していきます。
オブジェクト内の要素を消したい場合は、Removeメソッドを使用します。サンプルコードで確認していきましょう。

【サンプルコード】

Sub sampleRemove()

 Dim sampleDic As Object
 Set sampleDic = CreateObject("Scripting.Dictionary")
    
 sampleDic.Add "りんご", 150
 sampleDic.Add "ぶどう", 200
 sampleDic.Add "パイナップル", 350

 'オブジェクト内の要素を削除
    sampleDic.Remove "ぶどう"
 Dim str As String

 '格納したデータを参照
 For Each dicKey In sampleDic
  str = str & dicKey & " : " & sampleDic.Item(dicKey) & vbCrLf
 Next dicKey

 MsgBox str

End Sub

【実行結果】

Removeメソッドを使って、「ぶどう」のキーで格納していたデータを削除することに成功しました。

このサンプルコードについては、格納済みのキーを事前に把握することができるため問題はありませんが、場合によっては指定するキーがオブジェクト内に存在するか分からないケースもあります。

オブジェクト内に無いキーを指定するとエラーが起きてしまうため、実際にRemoveメソッドを使用する際は、指定するキーが存在するか否かを確認してから削除することをおすすめします。

キーの有無を確認する場合は、Existsメソッドを使用します。

【サンプルコード】

Sub sampleExists()

 Dim sampleDic As Object
 Set sampleDic = CreateObject("Scripting.Dictionary")
    
 sampleDic.Add "りんご", 150
 sampleDic.Add "ぶどう", 200
 sampleDic.Add "パイナップル", 350

 'キーが存在するか確認
 If sampleDic.Exists("ぶどう") Then
  MsgBox "使用中のキーです"
 Else
  MsgBox "このキーは存在しません"
 End If

End Sub

【実行結果】

DictionaryをKeyでソートする方法

Dictionaryオブジェクトそのものには、残念ながらソートするためのメソッドは実装されていません。そのため、比較や並び替えを行うコードを自前で記述する必要があります。

一般的な比較方法としては、バブルソートやクイックソートなどが挙げられますが、内容によっては処理が複雑になり、管理にも手間がかかってしまいます。

そこで今回は、シート上のセルを使用して、RangeオブジェクトのSortメソッドで並び替えを行う方法を紹介します。

具体的な使い方について、サンプルコードで確認してみましょう。

【サンプルコード】

Sub sampleSort()

 Dim sampleDic As Object
 Set sampleDic = CreateObject("Scripting.Dictionary")
    
 sampleDic.Add "りんご", 150
 sampleDic.Add "ぶどう", 200
 sampleDic.Add "パイナップル", 350
    
 Dim num As Integer
 num = 1

 'オブジェクト内の要素をセルにセット
 For Each dicKey In sampleDic
  Cells(num, 1).Value = dicKey
  Cells(num, 2).Value = sampleDic.Item(dicKey)
  num = num + 1
 Next dicKey
    
 'RangeオブジェクトのSortメソッドを使用
 Range("A1:B" & sampleDic.Count).Sort key1:=Range("A1")
    
 Dim str As String

 'Sort前の内容と比較
 For Each dicKey In sampleDic
  str = str & dicKey & " : " & sampleDic.Item(dicKey) & vbCrLf
 Next dicKey
    
 MsgBox str

End Sub

【実行結果】

このコードでは、まず初めにDictionaryオブジェクトに要素を追加してから、その内容をシート上のセルに反映させています。

Sortメソッドで値を入力した範囲を指定し、キーを基準に設定することでソートが完了しました。ソート前の内容を表示したダイアログと、シート上の順番が入れ替わっているのが画像からも分かると思います。

ソートし終えた内容をDictionaryオブジェクトに反映させたい時は、例えば以下のようなコードで、セルの内容をオブジェクトに入れ直します。

【サンプルコード】

 Dim count As Integer
 count = sampleDic.count
  
 sampleDic.RemoveAll

 For i = 1 To count
  sampleDic.Add Cells(i, 1).Value, Cells(i, 2).Value
 Next i

【実行結果】

キーの書き換えをする際、要素を残したまま行おうとすると重複でエラーが発生してしまうため、事前に全て削除してから値を入れ直しています。

参照設定でDictionaryオブジェクトを使うには?

「Dicotnaryオブジェクトを使うには外部ライブラリを参照する必要がある」と先ほど説明しましたが、この方法には2通りのやり方があります。

1つは既に紹介した「CreateObject」を使う方法で、実行時バインディングと呼ばれています。

もう1つは、参照設定を行ってDictionaryオブジェクトを使えるようにする「事前バインディング」と呼ばれる方法です。この方法について、詳しい使い方を解説していきたいと思います。

参照設定を行う場合、コードを記述する前に必要な作業があります。
まず、Microsoft Visual Basic for Applicationsの「ツール」メニューから「参照設定」をクリックします。

「参照可能なライブラリファイル」から「Microsoft Scripting Runtime」にチェックします。

OKボタンをクリックし、「参照設定」ダイアログを閉じます。
設定が完了したら、以下のように宣言することで、Dicotnaryオブジェクトを変数に代入することができます。

Dim 連想配列名 As New Scripting.Dictionary

または

Dim 連想配列名 As Scripting.Dictionary
連想配列名 = New Scripting.Dictionary

まとめ

Dictionaryオブジェクトの使い方については理解できたでしょうか?

VBAで扱うケースはかなり多くなるかと思うので、ぜひこの記事を参考にしながら、Dictionaryオブジェクトを使いこなせるように頑張ってくださいね!

関連記事

VBAの勉強方法は?

書籍やインターネットで学習する方法があります。昨今では、YouTubeなどの動画サイトやエンジニアのコミュニティサイトなども充実していて多くの情報が手に入ります。
そして、より効率的に知識・スキルを習得するには、知識をつけながら実際に手を動かしてみるなど、インプットとアウトプットを繰り返していくことが重要です。特に独学の場合は、有識者に質問ができたりフィードバックをもらえるような環境があると、理解度が深まるでしょう。

ただ、VBAに限らず、ITスキルを身につける際、どうしても課題にぶつかってしまうことはありますよね。特に独学だと、わからない部分をプロに質問できる機会を確保しにくく、モチベーションが続きにくいという側面があります。独学でモチベーションを維持する自信がない人にはプログラミングスクールという手もあります。費用は掛かりますが、その分スキルを身につけやすいです。しっかりと知識・スキルを習得して実践に活かしたいという人はプログラミングスクールがおすすめです。

プログラミングスクールならテックマニアがおすすめ!

ITスキル需要の高まりとともにプログラミングスクールも増えました。しかし、どのスクールに通うべきか迷ってしまう人もいるでしょう。そんな方にはテックマニアをおすすめします!これまで多くのITエンジニアを育成・輩出してきたテックマニアでもプログラミングスクールを開講しています。

<テックマニアの特徴>
・たしかな育成実績と親身な教育 ~セカンドキャリアを全力支援~
・講師が現役エンジニア ~“本当”の開発ノウハウを直に学べる~
・専属講師が学習を徹底サポート ~「わからない」を徹底解決~
・実務ベースでスキルを習得 ~実践的な凝縮カリキュラム~

このような特徴を持つテックマニアはITエンジニアのスタートラインとして最適です。
話を聞きたい・詳しく知りたいという方はこちらからお気軽にお問い合わせください。

     

Otherカテゴリの最新記事