【VBAリファレンス】Excel VBAで重複しないリストを爆速で生成する:実務で差がつくコレクションと辞書オブジェクトの活用術

スポンサーリンク

概要:重複排除はデータ処理の基本にして最大の難所

Excel業務において、膨大なデータから「ユニークな項目(重複しないリスト)」を抽出する作業は、日常茶飯事と言っても過言ではありません。フィルター機能や「重複の削除」ボタンを使えば手作業でも可能ですが、データ量が増大したり、毎日決まったフォーマットで処理を繰り返す必要がある場合、手作業は非効率かつミスの温床となります。

VBAを活用すれば、この作業を瞬時に、かつ正確に自動化できます。本記事では、VBAで重複しないリストを作成するための、最も効率的かつプロフェッショナルな手法である「Dictionaryオブジェクト」を用いたアプローチを中心に、その仕組みから応用テクニックまでを網羅的に解説します。

詳細解説:なぜDictionaryオブジェクトが最適なのか

VBAで重複を判定する方法には、大きく分けて「ループ処理による比較」「CountIf関数を使う方法」「コレクション(Collection)オブジェクト」「辞書(Scripting.Dictionary)オブジェクト」の4種類があります。

この中で、実務において圧倒的なパフォーマンスと保守性を誇るのが「Dictionaryオブジェクト」です。このオブジェクトは、キー(Key)と値(Item)のペアでデータを保持します。最大の特徴は、キーが重複できないという性質を持っている点です。つまり、リストにデータを追加しようとする際、すでに存在するキーであれば無視される(あるいは上書きされる)ため、わざわざ「既存のリストに同じ値があるか」を検索するコードを書く必要がありません。

Dictionaryオブジェクトを利用するには、「Microsoft Scripting Runtime」を参照設定するか、あるいは実行時に「CreateObject」で生成します。後者はコードの配布時に参照設定のズレを気にする必要がないため、汎用性が高く推奨されます。

サンプルコード:Dictionaryオブジェクトによる高速抽出

以下に、列Aにある重複を含んだリストから、列Cへ重複しないリストを書き出す標準的なコードを示します。


Sub CreateUniqueList()
    Dim ws As Worksheet
    Dim lastRow As Long
    Dim dataRange As Variant
    Dim dict As Object
    Dim i As Long
    Dim result As Variant
    
    ' ワークシートの設定
    Set ws = ThisWorkbook.Sheets("Sheet1")
    
    ' 最終行を取得してデータを配列に取り込む(高速化の鉄則)
    lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
    If lastRow < 2 Then Exit Sub
    dataRange = ws.Range("A2:A" & lastRow).Value
    
    ' Dictionaryオブジェクトの生成
    Set dict = CreateObject("Scripting.Dictionary")
    
    ' 辞書にデータを格納(重複は自動的に排除される)
    For i = 1 To UBound(dataRange, 1)
        If Not IsEmpty(dataRange(i, 1)) Then
            If Not dict.Exists(dataRange(i, 1)) Then
                dict.Add dataRange(i, 1), Nothing
            End If
        End If
    Next i
    
    ' 結果をシートに出力
    ws.Range("C2:C" & ws.Rows.Count).ClearContents
    If dict.Count > 0 Then
        result = Application.Transpose(dict.Keys)
        ws.Range("C2").Resize(UBound(result, 1)).Value = result
    End If
    
    ' メモリの解放
    Set dict = Nothing
    MsgBox "重複しないリストを作成しました!", vbInformation
End Sub

このコードのポイントは、セルへのアクセス回数を最小限に抑えるために「配列(Variant)」を使用している点です。セルを一つずつループで読み書きすると、データ量が増えるにつれて処理時間が指数関数的に増加しますが、配列を用いれば数万行のデータであっても一瞬で処理が完了します。

実務アドバイス:更なる高みを目指すためのテクニック

コードが書けるようになるだけでは、ベテランの域には達しません。現場で活用する際には、以下の観点を持つことが重要です。

1. 大文字・小文字の区別を考慮する
Dictionaryオブジェクトはデフォルトで大文字と小文字を区別しません(”Apple”と”apple”は同一とみなされる)。もし区別したい場合は、比較モードを変更する必要があります。
`dict.CompareMode = vbBinaryCompare` をオブジェクト作成直後に記述することで、厳密な判定が可能になります。

2. 空白セルの処理
実務データには必ずと言っていいほど「空白」が混入します。これをリストに含めたくない場合は、`If Not IsEmpty(dataRange(i, 1)) Then` のように、値の存在チェックを必ず行いましょう。

3. 複数列のユニーク抽出
単一列だけでなく「商品名」と「担当者」の組み合わせでユニークにしたい場合、キーを結合するというテクニックが有効です。
`key = dataRange(i, 1) & “_” & dataRange(i, 2)` のように、区切り文字を挟んでキーを生成すれば、複合キーとして管理することができます。

4. データのソート
Dictionaryには並び替え機能がありません。リスト抽出後にソートが必要な場合は、抽出した結果をワークシートに書き出した後、Range.Sortメソッドを利用して並び替えるのが最も効率的です。

まとめ:VBAの力で非効率な事務作業を根絶する

「重複しないリストを作る」という作業は、Excel業務の自動化における登竜門です。今回紹介したDictionaryオブジェクトを用いた手法は、一度習得すれば、データのクレンジング、カテゴリ分け、マスタ管理など、あらゆる場面で応用が効く強力な武器となります。

VBAの真価は、単に「手作業を置き換える」ことではなく、「人間がやるにはあまりにも膨大で複雑な処理を、一瞬で終わらせる」ことにあります。ぜひ、今回紹介したコードをコピーするだけでなく、自身の業務データに当てはめて動かしてみてください。最初はわずか数秒の短縮かもしれませんが、その積み重ねが、あなた自身の時間を生み出し、よりクリエイティブな業務に注力するための大きな礎となるはずです。

もしコードが動かない場合は、まずはシンプルなデータでデバッグを行うことから始めてください。VBAのエラーは、あなたの成長を促す貴重なヒントです。プロのExcelエンジニアを目指し、今日から自動化の世界をさらに深掘りしていきましょう。

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