VBA

Dictionaryオブジェクトを使ったダブりのないリストの作成

記事内に商品プロモーションを含む場合があります

このページでわかること

重複していないユニークなリストを作成することができます

覚えること

  1. Dictionaryオブジェクトは重複したキーを格納できない
    この性質を利用して重複しないリストを作る
  2. On Error Resume Next文により、以降のコードでエラーが発生した箇所を無視する

  • Dictionaryオブジェクトは重複したキーを格納
  • できない

    Dictionaryオブジェクトには同じキーを入れることはできません。
    エラーになります

    試してみましょう。
    リンゴをキーとし、二回入れてみます。

    Sub ダブりのないdictionary()
    
    'Dictionaryオブジェクトの宣言
    Dim dic As New dictionary
    
    'Dictionaryオブジェクトにリンゴを二回入れます。
    dic.Add "リンゴ", "青森"
    dic.Add "リンゴ", "フィリピン"
    dic.Add "メロン", "北海道"
    
    '全てのキーとアイテムを取り出す方法
    Dim str As String
    Dim l As Variant
    For Each l In dic
        str = str & l & ":" & dic.Item(l) & vbCrLf
    Next
    MsgBox (str)
    End Sub
    エラーが発生しました。同じキーは入れることが出来ません。

    このようにDictionaryは絶対にダブりはダメです。

    On Error Resume Next文を使おう!

    On Error Resume Nextと入力すると、
    エラーが生じたコードは無視してくれます。

    次のコードは
    7行目に On Error Resume Next
    11行目にOn Error GoTo 0
    を加筆しています。他は一緒です。

    Sub ダブりのないDictionary()
    
    'Dictionaryオブジェクトの宣言
    Dim dic As New dictionary
    
    'Dictionaryオブジェクトにリンゴを二回入れます。
    On Error Resume Next
    dic.Add "リンゴ", "青森"
    dic.Add "リンゴ", "フィリピン"
    dic.Add "メロン", "北海道"
    On Error GoTo 0
    
    '全てのキーとアイテムを取り出す方法
    Dim str As String
    Dim l As Variant
    For Each l In dic
        str = str & l & ":" & dic.Item(l) & vbCrLf
    Next
    MsgBox (str)
    End Sub
    二回目のリンゴ:フィリピンは無視され、入っていません。

    何が起きているか

    重複が発生
    →エラーが生じる
    →On Error Resume Next文 のおかげでそのコードは無視することになる
    →次のコードに移る
    →重複のないユニーク(ダブりのない)なキーのみ格納される
    →For each 文でユニークなキーをぶん回す!!

    注意
    Dictionaryオブジェクトに入れ終わったら、
    On Error GoTo 0を入れてください。
    これを入れないと以降でエラーが発生したときも無視し続けます。
    とんでもないことになります。。

    エクセルの表からユニークなリストを作成する方法(ここをコピペ!)

    エクセルの表からユニークな表を作るコードを掲載しておきます。
    実務で使えます!
    よかったら、使えるところ使ってください。

    Sub ユニークなリスト作成_コピペOK()
    
    '=================================================
    'Range用の変数の用意と格納範囲をセット
    'Rngsの範囲はご希望の範囲に変更してください
    '=================================================
    Dim r As Range
    Dim Rngs As Range
    Set Rngs = ThisWorkbook.Worksheets(1).Range("A2:A15") 'レンジコレクションのセット
    
    'Dictionary用の変数とDictionaryオブジェクト
    Dim l As Variant
    Dim dic As New Dictionary
    
    'Dictionaryオブジェクトに格納
    For Each r In Rngs
        On Error Resume Next
            dic.Add r.Value, r.Value
        On Error GoTo 0
    Next
    
    '=================================================================
    'リストを取り出す
    'イミディエイトウインドウに記載するためです。実務では不要です。
    '代わりにここでやりたい処理を入れてください
    '=================================================================
    For Each l In dic
        Debug.Print l
    Next
    End Sub

    ここはコピペしてもらえると嬉しいです。
    僕は基本この型で処理します。
    弊社でのプログラムも基本これです。
    問題なく動いてます。

    Rangeの範囲はベタ打ちじゃなくて、テーブルでとるとか、
    フィルタリングした後のデータのリストをとるとか
    ひと手間ありますが。。

    まとめ

    いかがでしょうか。

    ダブりのないリストって実務では絶対必要だと思います。
    多分マクロを使う上での必須項目です。

    リストの作り方は色々あります。
    例えばRemoveDuplicatesとかも使えるテクニックなのですが(どこかでご紹介したいです)
    これはデータタブの重複の削除の機能のことを指します。
    実際にエクセルのシート上で重複削除の処理をするので、わかりやすいのですが、
    シートを用意したりしないといけないので結構面倒です。

    また、Dictionaryオブジェクトと同じ要領で作れる
    Collectionオブジェクトというのもあるのですが、
    こちらは文字列のみとなり、数値は入れることができないので注意が必要です。

    ですので、お勧めはDictionaryオブジェクトで
    余裕が出てきたら別の手法も勉強していくといいと思います。
    なんでもそうですが、知っておくというのはとても大事です。
    状況により最適手法は変わることもあるからです。

    ではでは