マクロ講座VBA Dictionaryの使い方
マクロ 94回
連想配列を学ぶ必要がある理由
Dictionaryは vba を高速化したい場合にかなり威力を発揮します。
そして具体的なメリットとしては辞書の検索と存在の確認が高速にできるということです。
連想配列、Dictionaryを学ぶ、必要な知識も学習
- 連想配列を学ぶ必要がある理由
- Dictionaryの検索と存在確認が高速にできる
- MicrosoftのScripting Runtimeを参照設定する
- CreateObject関数を使った場合のDictionaryの使い方
- Scripting Runtimeを参照設定した場合、Dictionaryを宣言する方法
- Scripting Runtimeを参照設定した場合のコードで実行
- dictionaryのキーに対して短縮した書き方ができる
- シート上の既存データを連想配列に取り込む方法
- dictionaryからセルに書き出す方法
このページからは、VBAを使ったdictionaryの基本的な使い方を学ぶことができます。
Dictionaryの検索と存在確認が高速にできることや、Scripting Runtimeを参照設定する方法、シート上の既存データを連想配列に取り込む方法、dictionaryからセルに書き出す方法などが学べます。
また、dictionaryのキーに対して短縮した書き方もできることも学べます。
(練習ファイルは、こちらから
マクロ94回練習ファイル)
動画 VBA Dictionary 連想配列で重複を削除したリストの作成!
Microsoft の Scripting Runtimeを参照設定する
もう一度手順を確認しましょう。 Visual Basic Editor のメニューからツールを選択、そして参照設定をクリックします。
すると参照設定ダイアログが表示されるので 、Microsoft Scripting Runtime にチェックを入れます。
OK をクリックしてウィンドウを閉じます。これで dictionary が使えるようになりますクリエイトオブジェクト関数を使う場合には、以下のような使い方をします。まず、with 構文の中でクリエイトオブジェクト関数を使っている例です。
こちらは変数を宣言して、その変数に対して CreateObjec関数を利用して辞書設定しています。
dictionary オブジェクトの変数dicに対してAddメソッドを使ってKey,Itemの順番で指定します。以下のように
Dim dic As Dictionary
Set dic = New Dictionary のように宣言します。
Dim dic As New Scripting.Dictionary と1行で書くこともできます。
そしてKeyの"peaches" に関して、そのアイテムを取得したい場合は
dic.Item("peaches") と書きます。メッセージボックスで表示させています。Sub dict01_b() Dim dic As New Scripting.Dictionary dic.Add "peaches", "50" dic.Add "apricots", "80" dic.Add "watermelons", "20" MsgBox dic.Item("peaches") Set dic = Nothing ' おきまり End Sub
Set dic = Nothingで最後に、Dictionaryを解放しています。
変数はそのプロシージャが終了したタイミングで、参照が解除されます。
同一プロシージャ内で、同じ変数名を使い、別の用途の取得を繰り返す場合は、書いた方がいいでしょう。一回しか取得しないのであれば不要と私は考えています。
実際には書かなくても動作しますが、習慣で書いてると言えるかもしれません。
CreateObject関数を使った場合のDictionaryの使い方
Scripting Runtimeを参照設定した場合
Scripting Runtimeを参照設定した場合のコードで実行
Microsoft の scripting runtime を参照設定した場合のDictionaryの設定の方がすっきりとして見えますね。
実行してアイテムを取得しましょう。
結果アイテムの50が表示されました。
dictionary は一つのKeyに対して一つのItemが原則ですから、
わざわざ dic.Item("peaches")のような書き方をしなくても、dic("watermelons")だけで意味が通じてしまいます。このような短縮した書き方もできるということです。連想配列に取得したいデータがシート状に既にある場合は、いっぺんにシートから取り込んでしまうことができます。
Dim Data
Data = Range("A2:B13")
と範囲を指定するだけで、すでにDataという配列にシート状の範囲 A2セルから B13セルまでのデータが取り込まれています。配列に範囲を取り入れてしまえば、連想配列を取り込む指定は簡単です。 For文で回す際に、 For i = 1 To UBound(Data)
と記述するだけで取得した全部のデータを一つずつ、このように連想配列に入れて行くことができます。
シート上の既存データを連想配列に取り込む
dictionary からセルに書き出す方法 For文を使って書き出す
Dictionaryにはこの3行で追加することができました。
For i = 1 To UBound(Data)
dic.Add Data(i, 1), Data(i, 2)
Next
ですから、シートに書き出すのも簡単に書き出すことができます。
dictionary の開始値は0です。そして dictionary の個数を数えるにはCountが使えます。For i = 0 To dic.Count - 1
Cells(i + 1, 1).Value = dic.Keys(i)
Cells(i + 1, 2).Value = dic.Items(i)
Next
開始値は0で終了値はdic.Count - 1となります。
マクロを実行すると、シート上に取得した dictionary の key とアイテムを転記することができました。
全く同じ内容となっています。Sub dict01_c() Dim dic As New Scripting.Dictionary Dim Data, i As Long Data = Range("A2:B13") For i = 1 To UBound(Data) dic.Add Data(i, 1), Data(i, 2) Next For i = 0 To dic.Count - 1 Cells(i + 1, 1).Value = dic.Keys(i) Cells(i + 1, 2).Value = dic.Items(i) Next Set dic = Nothing End Sub
取得した dictionary を書き出す場合にはこのようなResizeを使った書き方もできます。
この書き方の場合、キーを B 列に、そしてアイテムをD 列に書き出すということでコードが2行になっています。Sub dict01_d() Dim dic As New Scripting.Dictionary Dim data, i As Long, Member data = Range("A2:B13") For i = 1 To UBound(data) dic.Add data(i, 1), data(i, 2) Next 'dicのキーをセルに出力 Range("D2").Resize(dic.Count) = WorksheetFunction.Transpose(dic.Keys) 'dicのアイテムを入力 Range("E2").Resize(dic.Count) = WorksheetFunction.Transpose(dic.Items) Set dic = Nothing End Sub
辞書オブジェクトには、今回利用したItem、Keysの他に以下のような主なプロパティもあります。
- Item
- 指定したキーを持つ要素の値を取得または設定します。
- Keys
- 辞書内のすべてのキーを配列で返します。
- Items
- 辞書内のすべての値を配列で返します。
- UCount
- 辞書内の要素の数を取得します。
- CompareMode
- 辞書内のキーの比較方法を設定します。
いかがだったでしょうか。 dictionary 連想配列という名前の響きから、とても難解なものと敬遠されがちなdictionary ですけれども、こうやってひとつずつ見ていくと、意外と簡単だということがお分かり頂けたと思います。
次はデータが重複していた場合の処理について説明します。