連想配列(Scripting.Dictionaryオブジェクト)というものを使ってみた

初めての連想配列

連想配列」とか、「Dictionary」という言葉は見たことがあったけれど、使ったこともなく、詳しく知ることもなかった。

自作クラスのエラーメッセージを管理するのがメンドクサイなーと思って、「そういえば……」とちょっと調べてみると、

便利かも

と思ったので、ちょいとやってみた。

Scripting.Dictionaryオブジェクトを使う

CreateObject関数がちょっと嫌いというか、New演算子が好きなので(←意味不明)、VBEの[ツール]→[参照設定]で、

Microsoft Scripting Runtime

にチェックを入れる。

f:id:akashi_keirin:20171217110225j:plain

ひとまず、準備はこれでおk。

Dictionaryオブジェクトの作成

今のところイメージしている使いどころとしては、文字通りの「辞書」みたいな使い方なので、

静的に定義したDictionaryオブジェクトを返すFunction

というイメージでやってみる。

リスト1 標準モジュール
Public Function createMessageDictionary() As Scripting.Dictionary    '……(1)'
  Dim messageDictionary As Scripting.Dictionary    '……(2)'
  Set messageDictionary = New Scripting.Dictionary
  With messageDictionary    '……(3)'
    .Add Key:=10001, _
         Item:="ち~んw"    '……(*)'
    .Add Key:=10002, _
         Item:="プヒー!"
    .Add Key:=10003, _
         Item:="( ´,_ゝ`)プッ"
    .Add Key:=10004, _
         Item:="( ´_ゝ`)フーン"
  End With
  Set createMessageDictionary = messageDictionary    '……(4)'
End Function

まず、(1)の

Public Function createMessageDictionary() As Scripting.Dictionary

静的に定義したDictionaryを返す、という体なので、引数はなし。参照設定済みなので、返り値の型には「Scripting.Dictionary型」を指定。「Object型」とかはあんまり使いたくないなあ。

(2)からの2行

Dim messageDictionary As Scripting.Dictionary
Set messageDictionary = New Scripting.Dictionary

Scripting.Dictionary型の変数messageDictionaryを宣言し、インスタンス化。

やっぱり、Newを使う方が「インスタンス化したった」感が出て好きだなあ。

(3)からの10行(実質6行)

With messageDictionary
  .Add Key:=10001, _
       Item:="ち~んw"    '……(*)'
  .Add Key:=10002, _
       Item:="プヒー!"
  .Add Key:=10003, _
       Item:="( ´,_ゝ`)プッ"
  .Add Key:=10004, _
       Item:="( ´_ゝ`)フーン"
End With

では、DictionaryオブジェクトのAddメソッドを用いて要素を追加。

KeyとItemをセットで追加している。

このあたり、Collectionオブジェクトとか、VBAだとユーザーフォームのリストボックスなんかの扱いに似ているので、脱初級ぐらいのレベルで十分理解可能ですね。

あとは、(4)の

Set createMessageDictionary = messageDictionary

で、できあがったDictionaryオブジェクト(messageDictionary)を返り値にセットしておしまい。

使用実験

標準モジュールに次のコードを書いて使ってみる。

スト2 標準モジュール
Public Sub testmessageDictionary()
  Dim msgDic As Scripting.Dictionary    '……(1)'
  Set msgDic = createMessageDictionary()
  Dim i As Integer
  For i = 10001 To 10004    '……(2)'
    Debug.Print msgDic.Item(i)
  Next
End Sub

(1)からの

Dim msgDic As Scripting.Dictionary
Set msgDic = createMessageDictionary()

では、Scripting.Dictionaryオブジェクトのインスタンス用の変数msgDicを宣言して、createMessageDictionaryメソッドを用いてインスタンスを作成し、ぶち込んでいる。

あとは、(2)からの3行

For i = 10001 To 10004
  Debug.Print msgDic.Item(i)
Next

でForループを用いてイミディエイト・ウインドウに出力する。

実行結果

f:id:akashi_keirin:20171217110252j:plain

こんなふうに、無事取得できた。

おわりに

これはこれで、使いようによっては便利だと思うので、研究したいね。

Excelの場合は、ワークシートをDictionaryのように使う方が圧倒的にラクなので、ついそれに甘えてしまうけれど、通常のプログラミングのことを考えたら、こういういろいろなデータ構造の扱い方を覚えていかないとなー。

@akashi_keirin on Twitter