大体でIT

-ちょっと使えるネタを紹介-

大体でIT

Excel VBAで、「Dictionary」を使って重複しないリストを作成する方法について、ご紹介します。「Dictionary」を使えば、VBAコードをシンプルにして、高速化することができます。うまく「Dictionary」を使いこなしていきましょう。

はじめに

この記事では、「Dictionary」を使って重複しないリストを作成する方法について、ご紹介します。

「Dictionary」で重複しないリストを作成するメリットは、以下のものがあります。

  • VBAコードが簡単になる
  • 高速化できる
  • 複数列で重複しないリストも作成できる

という感じで、「Dictionary」をうまく使いこなせるとメリットがたくさんあります。

高速化したい場合や、VBAコードを簡素化したい場合などに、「Dictionary」を使っていきましょう。

では、「Dictionary」を使って重複しないリストを作成する方法について、解説していきます。

この記事で紹介すること

  • 「Dictionary」を使って重複しないリストを作成する方法

目次から見たい項目へ移動すると便利ですよ。

目次

ForとIfを使って重複しないリストを作成する

ForとIfを使って重複しないリストを作成してみます。

「ForとIf」を使って頑張って重複しないリストを作成する方法です。

重複しないリストを作成する

「ForとIf」をつかって重複しないリストを作成してみます。

VBAコードは、こんな感じになります。

Sub TEST1()
    
    Dim A, B
    A = Range("A2:A10") '値を配列に入力
    ReDim B(1 To UBound(A, 1), 1 To 1) '空の配列を作成する(重複しないリスト用)
    
    Dim Flag
    
    '値をループする
    For i = 1 To UBound(A, 1)
        Flag = 0
        '重複しないリストの配列をループ
        For j = 1 To UBound(B, 1)
            '空白の場合ループ終了
            If IsEmpty(B(j, 1)) Then Exit For
            '値が一致した場合
            If A(i, 1) = B(j, 1) Then
                Flag = 1 'フラグを立てる
                Exit For 'ループを終了
            End If
        Next
        'フラグがオフの場合
        If Flag = 0 Then
            m = m + 1 'カウントアップ
            B(m, 1) = A(i, 1) '重複しないリストに登録
        End If
    Next
    
    '配列をセルに入力
    Range("C2").Resize(UBound(B, 1)) = B
    
End Sub

手順としては、

  • 商品を配列に入力
  • 商品をループする
  • 商品が登録されているかを確認
  • 登録されていなければ新しくリストに登録
  • 配列をセルに入力

という感じです。

「商品が登録されているか」の確認に結構時間がかかってしまいます。

重複したリストを用意しておきます。

重複したリストを用意

重複したリストを用意

VBAコードの手順をみてみます。

重複しないリストに登録されているかを確認します。

登録されているかを確認する

登録されているかを確認する

商品をループして登録されていない場合は登録していきます。

登録されていない場合は登録する

商品をループして登録されていない場合は登録する

すべての商品をループして、重複しないリストが作成されます。

重複しないリストをセルに入力します。

配列をセルに入力

配列をセルに入力

これで、重複しないリストを作成できます。

重複しないリストを作成できた

重複しないリストを作成できた

重複しないリストを作成できました。

大量のデータで実行してみる

大量のデータで実行してみます。

Sub TEST2()
    
    t = Timer
    
    Dim A, B
    A = Range("A2:A50001") '値を配列に入力
    ReDim B(1 To UBound(A, 1), 1 To 1) '空の配列を作成する(重複しないリスト用)
    
    Dim Flag
    
    '値をループする
    For i = 1 To UBound(A, 1)
        Flag = 0
        '重複しないリストの配列をループ
        For j = 1 To UBound(B, 1)
            '空白の場合ループ終了
            If IsEmpty(B(j, 1)) Then Exit For
            '値が一致した場合
            If A(i, 1) = B(j, 1) Then
                Flag = 1 'フラグを立てる
                Exit For 'ループを終了
            End If
        Next
        'フラグがオフの場合
        If Flag = 0 Then
            m = m + 1 'カウントアップ
            B(m, 1) = A(i, 1) '重複しないリストに登録
        End If
    Next
    
    '配列をセルに入力
    Range("C2").Resize(UBound(B, 1)) = B
    
    Debug.Print Timer - t & " 秒"
    
End Sub

「50,001」行のデータを用意しました。

「50,001」行のデータを用意

「50,001」行のデータを用意

では、VBAコードを実行してみます。

重複しないリストを作成できた

重複しないリストを作成できた

重複しないリストを作成できました。

かかった時間

かかった時間は、「81.23438 秒」です。

まぁ時間がかかりますね。

重複しないリストを力技でやろうとすると、時間がかかってしまいます。

Dictionaryを使って重複しないリストを作成する

「Dictionary」を使って重複しないリストを作成してみます。

重複しないリストを作成する

「Dictionary」を使って重複しないリストを作成するVBAコードです。

手順は、

  • 値を配列に入力
  • 商品をループする
  • 商品が登録されていなければ登録
  • 「キー」をセルに入力

という感じです。

Sub TEST3()
    
    Dim A
    '辞書を作成
    Set A = CreateObject("Scripting.Dictionary")
    
    Dim B
    '値を配列に入力
    B = Range("A2:A10")
    
    '値をループ
    For i = 1 To UBound(B, 1)
        '登録されていない場合
        If A.exists(B(i, 1)) = False Then
            A.Add B(i, 1), 0 '辞書に登録する
        End If
    Next
    
    'セルに値を入力
    Range("C2").Resize(A.Count) = WorksheetFunction.Transpose(A.keys)
        
End Sub

登録されているかの確認を「A.Exists(キー)」でできるのがポイントです。

まずは、簡単なデータで動きを確認してみます。

重複するリストを用意しておきます。

重複するリストを用意

重複するリストを用意

では、順を追って実行結果をみてみます。

商品をループして、辞書に登録されていない場合は登録していきます。

商品をループして辞書に登録されていない場合は登録

商品をループして辞書に登録されていない場合は登録

登録の確認が「A.Exists(キー)」で簡単にできるので、便利です。

すべての商品をループしたら、セルに「キー」だけを入力します。

辞書のキーをセルに入力

辞書のキーをセルに入力

これで、重複しないリストが完成できます。

重複しないリストを作成できた

重複しないリストを作成できた

重複しないリストを作成できました。

VBAコードもシンプルになっていますね。

大量のデータで実行してみる

では、大量のデータで「Dictionary」を使って実行してみます。

Sub TEST4()
    
    t = Timer
    
    Dim A
    '辞書を作成
    Set A = CreateObject("Scripting.Dictionary")
    
    Dim B
    '値を配列に入力
    B = Range("A2:A50001")
    
    '値をループ
    For i = 1 To UBound(B, 1)
        '登録されていない場合
        If A.exists(B(i, 1)) = False Then
            A.Add B(i, 1), 0 '辞書に登録する
        End If
    Next
    
    'セルに値を入力
    Range("C2").Resize(A.Count) = WorksheetFunction.Transpose(A.keys)
    
    Debug.Print Timer - t & " 秒"
    
End Sub

「50,001」行のデータを用意しておきます。

「50,001」行のデータを用意

「50,001」行のデータを用意

では、VBAコードを実行してみます。

重複しないリストを作成できた

重複しないリストを作成できた

重複しないリストを作成できました。

かかった時間

かかった時間は、「0.125 秒」です。

これなら実務でも使えるレベルですね。

何回も実行するようなVBAコードだと、なおさら速いに越したことはないです。

Dictionaryを使って複数列で重複しないリストを作成する

Dictionaryを使って「複数列」で重複しないリストを作成することもできます。

うまく「Dictionary」を使えば、自由自在に重複しないリストが作成できます。

複数列で重複しないリストを作成

「複数列」で重複しないリストを作成してみます。

ポイントは、複数列の値を「区切り文字」で結合して登録する、というところです。

区切り文字は、データの中で使わない文字を使います。

手順としては、

  • 値を配列に入力
  • 配列をループ
  • 「商品」+「/」+「支店」で登録されているかを確認
  • 登録されていなければ、「商品」+「/」+「支店」を登録
  • 区切り文字で分割して「商品」と「支店」を配列に入力
  • 「商品」と「支店」の配列をセルに入力

という感じです。

Sub TEST5()
    
    Dim A
    '辞書を作成
    Set A = CreateObject("Scripting.Dictionary")
    
    Dim B
    '値を配列に入力
    B = Range("A2:B10")
    
    '配列をループする
    For i = 1 To UBound(B, 1)
        '登録されていない場合
        If A.exists(B(i, 1) & "/" & B(i, 2)) = False Then
            A.Add B(i, 1) & "/" & B(i, 2), 0 '辞書に登録
        End If
    Next
        
    'キーを配列に入力
    Dim C
    C = A.keys
    
    Dim D
    '空の配列を作成
    ReDim D(A.Count, 1)
    '辞書を要素分だけループする
    For i = 0 To A.Count - 1
        D(i, 0) = Split(C(i), "/")(0) '分割した1つ目の値
        D(i, 1) = Split(C(i), "/")(1) '分割した2つ目の値
    Next
    
    '配列をセルに入力
    Range("D2").Resize(A.Count, 2) = D
      
End Sub

区切り文字で結合したデータは、最後に「Split」を使って分割します。

まずは、簡単なデータで試してみます。

重複するリストを用意

重複するリストを用意

では、順を追って実行結果をみてみます。

「商品+支店」のデータで、登録されていない場合は、登録していきます。

商品+支店をループして登録されていない場合は登録

商品+支店をループして登録されていない場合は登録

「商品+支店」を最後までループすると、区切り文字で結合した重複しないリストが作成されます。

このままでは、使えないので、区切り文字で分割して配列に入力します。

区切り文字で分割して配列に入力

区切り文字で分割して配列に入力

最後に配列をセルに入力したら完了です。

配列をセルに入力

配列をセルに入力

これで、複数列で重複しないリストを作成できます。

複数列で重複しないリストを作成できた

複数列で重複しないリストを作成できた

「複数列」で重複しないリストを作成できました。

大量のデータで実行してみる

複数列の場合で大量のデータを使って実行してみます。

複数列の場合でも「Dictionary」を使えば、高速で実行することができます。

Sub TEST6()
    
    t = Timer
    
    Dim A
    '辞書を作成
    Set A = CreateObject("Scripting.Dictionary")
    
    Dim B
    '値を配列に入力
    B = Range("A2:B50001")
    
    '配列をループする
    For i = 1 To UBound(B, 1)
        '登録されていない場合
        If A.exists(B(i, 1) & "/" & B(i, 2)) = False Then
            A.Add B(i, 1) & "/" & B(i, 2), 0 '辞書に登録
        End If
    Next
        
    'キーを配列に入力
    Dim C
    C = A.keys
    
    Dim D
    '空の配列を作成
    ReDim D(A.Count, 1)
    '辞書を要素分だけループする
    For i = 0 To A.Count - 1
        D(i, 0) = Split(C(i), "/")(0) '分割した1つ目の値
        D(i, 1) = Split(C(i), "/")(1) '分割した2つ目の値
    Next
    
    '配列をセルに入力
    Range("D2").Resize(A.Count, 2) = D
       
    Debug.Print Timer - t & " 秒"
      
End Sub

「50,001」行のデータを用意しました。

「50,001」行のデータを用意

「50,001」行のデータを用意

では、実行してみます。

複数列で重複しないリストを作成できた

複数列で重複しないリストを作成できた

「複数列」で重複しないリストを作成できました。

かかった時間

かかった時間は、「0.21875 秒」となりました。

「50,001」行でこの時間なので、十分速いですね。

実務でも使えるレベルです。

おわりに

この記事では、「Dictionary」を使って重複しないリストを作成する方法について、ご紹介しました。

「Dictionary」で重複しないリストを作成するメリットは、以下のものがあります。

  • VBAコードが簡単になる
  • 高速化できる
  • 複数列で重複しないリストも作成できる

という感じで、「Dictionary」をうまく使いこなせるとメリットがたくさんあります。

高速化したい場合や、VBAコードを簡素化したい場合などに、「Dictionary」を使っていきましょう。

参考になればと思います。最後までご覧くださいまして、ありがとうございました。

関連する記事から探す

カテゴリから探す

カテゴリから見たい項目を探すと便利ですよ。

アーカイブから探す