データリストから重複する項目を取り除き、ユニークな(一意の)リストを作成したい、という場面はデータ集計の基本です。Excelの「重複の削除」機能でも可能ですが、VBAを使えばこの処理をマクロに組み込めます。
Forループで1セルずつ比較する方法では、データが多いと非常に時間がかかります。しかし、VBAの**Collection
オブジェクトが持つ「キーは重複できない」**という特性を利用すると、この処理を極めて高速に行うことができます。
この記事では、その巧妙なテクニックを解説します。
完成したVBAコード
以下は、B2
セルから始まるデータ範囲から、重複しない項目の一覧を作成し、F列に書き出すVBAコードです。
Sub CreateUniqueListWithCollection()
' 変数を宣言します
Dim sourceRange As Range
Dim uniqueItems As Collection
Dim cell As Range
Dim i As Long
' --- 1. 準備 ---
' Collectionオブジェクトを新規作成
Set uniqueItems = New Collection
' 処理対象のデータ範囲を設定
Set sourceRange = ThisWorkbook.Worksheets("Sheet1").Range("B2", ThisWorkbook.Worksheets("Sheet1").Range("B2").End(xlDown))
' --- 2. Collectionにアイテムを追加して、重複を自動的に排除 ---
' 「キーの重複」エラーを意図的に無視する設定
On Error Resume Next
For Each cell In sourceRange
' アイテムの値そのものを「キー」として追加を試みる
uniqueItems.Add Item:=cell.Value, Key:=CStr(cell.Value)
Next cell
' エラー処理を通常モードに戻す
On Error GoTo 0
' --- 3. 抽出されたユニークなリストをシートに書き出す ---
For i = 1 To uniqueItems.Count
ThisWorkbook.Worksheets("Sheet1").Cells(i + 1, "F").Value = uniqueItems(i)
Next i
MsgBox "重複しないリストの作成が完了しました。"
End Sub
コードのポイント解説(「キー」を利用した重複排除の仕組み)
このテクニックの核心は、Collection
の.Add
メソッドとOn Error Resume Next
を組み合わせる点にあります。
1. On Error Resume Next
まず、この一行で「もし処理中にエラーが発生しても、マクロを停止せずに次の行へ進んでください」というモードに切り替えます。
2. uniqueItems.Add Item:=..., Key:=...
Collection
にアイテムを追加する際、.Add
メソッドにはKey
という引数を指定できます。このKey
には、コレクション内で一意でなければならないという厳格なルールがあります。
uniqueItems.Add Item:=cell.Value, Key:=CStr(cell.Value)
このコードでは、Item
(格納する値)とKey
(その値の索引キー)の両方に、セル自身の値を指定しています。Key
は文字列である必要があるため、CStr
関数で安全に文字列に変換しています。
このコードがループで実行されると、以下のようになります。
- 最初の「りんご」:
Key
=”りんご”はまだ存在しないので、正常に追加されます。 - 最初の「みかん」:
Key
=”みかん”はまだ存在しないので、正常に追加されます。 - 2回目の「りんご」:
Key
=”りんご”でアイテムを追加しようとします。しかし、このKey
は既にコレクション内に存在するため、VBAは**「キーが重複しています」というエラーを発生させます。** - ここで、最初に設定した
On Error Resume Next
が機能し、このエラーは無視され、何も追加されずに次のループに進みます。
この仕組みを繰り返すことで、結果的にuniqueItems
コレクションには重複のないリストだけが残る、というわけです。
【応用】さらに高速なDictionary
オブジェクト
同様の処理は、Scripting.Dictionary
オブジェクトを使うと、より高速でコードも分かりやすくなる場合があります。Dictionary
には.Exists
というメソッドがあり、「キーが既に存在するか?」をエラーに頼らずに直接判定できるためです。
'参照設定: Microsoft Scripting Runtime
Dim dict As New Scripting.Dictionary
For Each cell In sourceRange
If Not dict.Exists(cell.Value) Then
dict.Add cell.Value, ""
End If
Next cell
パフォーマンスを極限まで追求する場合は、Dictionary
の利用も検討してみてください。
まとめ
Collection
オブジェクトの「キーは重複できない」という性質と、On Error Resume Next
を組み合わせることで、高速な重複排除ロジックを簡単に実装できます。
On Error Resume Next
を宣言する。For Each
ループで元データを巡回する。myCollection.Add Item:=値, Key:=値
で、値自身をキーにして追加を試みる。- 処理が終わったら、
On Error GoTo 0
でエラー処理を元に戻す。
このテクニックは、VBAで大量のデータからユニークなリストを作成する際の、非常に強力で定番の手法です。