【Excel VBA】Scripting.Dictionaryの使いどころ3選【連想配列】

VBA

今回は業務効率化で使用していたScripting.Dictionaryの使いどころについて解説していこうと思います。

文字で説明してもわかりづらいと思うので、パート3までをシートごとに分けたマクロを作成しました。
実際に使用してもらえればなんとなく言いたいことがわかるかなと思います。
下記にファイルを乗せていますので、試していただければと思います。

スポンサーリンク

定数として値を使用したい場合

定数として使用したい場合はScripting.Dictionaryが使いやすいところもあります。

例)「リンゴ」100円、「みかん」110円、「ブドウ」400円、「マンゴー」500円

としたときに変数に格納するような形では変数が多くなってしまいます。
また、配列を使用して格納すれば変数は一つでいいですが、if文が多くなってしまってコード量が多くなってしまいます。
4つぐらいなら全然変数でも対応できますが、30以上種類があったりすると配列や、変数では対応できなくなります。

そんな時に使用します。
ダウンロードファイルのパート1がこの使い方に該当します。

ちなみにコードを下記に載せておきます。

Sub get_price()
    Dim ws As Worksheet
    Dim item_name As String
    Set ws = ThisWorkbook.Sheets(1)
    
    Dim item_lists As Object
    Set item_lists = CreateObject("Scripting.Dictionary")
    
    With ws
        For r = 2 To .Cells(Rows.Count, 1).End(xlUp).Row
            item_lists(.Cells(r, 1).Value) = .Cells(r, 2).Value
        Next r
    End With
    
    item_name = InputBox("価格を知りたい商品を入力して下さい。")
    If item_lists.Exists(item_name) Then
        MsgBox item_lists(item_name) & "円です"
    Else
        MsgBox "その商品は登録されていません。"
    End If
End Sub

カテゴリごとにいろんな情報を扱いたい場合

上記の内容を少し複雑化させた状態です。上記は価格だけを取り出したかったので、シンプルでしたが、次は「価格」、「大きさ(グラム)」、「個数」、「色」、「単位」の5つを知りたいとします。
こうなってくると2次元配列が使用できるかな?と思いますが、if文が多くなりすぎてメンテナンス性に欠けるような気がします。

こういう時はScripting.Dictionaryの中にScripting.Dictionaryを格納します。
私は実際に実務の効率化でこの使い方をしました。

ダウンロードファイルのパート2がこの使い方に該当します。

パート2のソースコードが下記になります。

Sub get_item_info()
    Dim ws As Worksheet
    Set ws = ThisWorkbook.Sheets(2)
    
    Dim item_lists As Object
    Dim item_name As String
    Set item_lists = CreateObject("Scripting.Dictionary")
    
    With ws
        For r = 2 To .Cells(Rows.Count, 1).End(xlUp).Row
            item_name = .Cells(r, 1).Value
            Set item_lists(item_name) = CreateObject("Scripting.Dictionary")
            For c = 2 To 6
                item_lists(item_name)(.Cells(1, c).Value) = .Cells(r, c).Value
            Next c
        Next r
    End With
    
    item_name = InputBox("価格を知りたい商品を入力して下さい。")
    If item_lists.Exists(item_name) Then
        For Each dic_key In item_lists(item_name).keys
            result = result & dic_key & ":" & item_lists(item_name)(dic_key) & vbCrLf
        Next dic_key
        MsgBox result
    Else
        MsgBox "その商品は登録されていません。"
    End If
End Sub

配列等の番号では管理がしづらいほど種類が多い場合

行も列も非常に多い場合に非常に役に立つと思います。この中身は正直カテゴリごとにいろんな情報を扱いたい場合と同じですが、どれほどコードがシンプルかを実感してもらいたく、紹介しました。

今回作成したプログラムは100×100の掛け算の結果です。
え?電卓でできる?データつくるの大変なので勘弁してください笑
100種類の商品名と一つの商品に対するカテゴリが100個あると思ってもらえたらと思います笑

ダウンロードのファイルのパート3がこの使い方に該当します。

パート3のソースコードは下記に載せておきます。

Sub get_result()
    Dim ws As Worksheet
    Set ws = ThisWorkbook.Sheets(3)
    
    Dim item_lists As Object
    Dim item_name As String
    Set item_lists = CreateObject("Scripting.Dictionary")
    
    With ws
        For r = 3 To .Cells(Rows.Count, 1).End(xlUp).Row
            item_name = .Cells(r, 2).Value
            Set item_lists(item_name) = CreateObject("Scripting.Dictionary")
            For c = 2 To .Cells(2, Columns.Count).End(xlToLeft).Column
                item_lists(item_name)(.Cells(2, c).Text) = .Cells(r, c).Value
            Next c
        Next r
    End With
    
    item_name = InputBox("1つ目の数字を入力して下さい(半角)")
    item_sub_name = InputBox("2つ目の数字を入力して下さい(半角)")
    If item_lists.Exists(item_name) Then
        MsgBox item_name & "×" & item_sub_name & "=" & item_lists(item_name)(item_sub_name)
    Else
        MsgBox "どちらも100以下で入力してください。"
    End If
End Sub

まとめ

いかがでしたでしょうか?3つともコード量はそれほど増えずにできることが増えているのが確認できたと思います。
最初はよく難しくて使いこなせないかもしれませんが、使いこなすことができれば、サクッと業務効率化に生かせるともいます。
ぜひScripting.Dictionaryを活用してみてください。

コメント

タイトルとURLをコピーしました