UNIQUE化
重複でぐちゃっとした表を、すっきり「一意(ユニーク)」に整えるテンプレをまとめました。壊さずに抽出する安全版から、爆速で処理する実務版まで、初心者でも迷わないように段階別で解説します。
目的別の選び方
- 最短で消して整える: RemoveDuplicates(元表を書き換える、先頭を残す)
- 元表を残して抽出したい: Dictionaryでユニーク行を別シートへ
- Excel 365/2021なら超手軽: WorksheetFunction.Uniqueで一瞬抽出
- 複合キーでユニーク化: コード×日付など複数列の組み合わせで重複排除
最短テンプレ:標準機能でUNIQUE化(元表を整える)
「見出しありの表」を対象に、指定列で重複を削除します。先にある行を残します。
Sub Unique_ByBuiltIn()
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.Calculation = xlCalculationManual
With Worksheets("Data").Range("A1").CurrentRegion
' 単一列(A列=1)でユニーク化
.RemoveDuplicates Columns:=1, Header:=xlYes
' 複合キー(AとBでユニーク化する例)
' .RemoveDuplicates Columns:=Array(1, 2), Header:=xlYes
End With
Application.Calculation = xlCalculationAutomatic
Application.EnableEvents = True
Application.ScreenUpdating = True
MsgBox "RemoveDuplicatesでユニーク化が完了(先頭行を残す)"
End Sub
VB- 向いている場面: 元表を書き換えてOK、列が確定している、最速で終わらせたいとき。
- 注意点: 「先頭を残す」挙動。残すルールを変えたいなら次のテンプレへ。
安全テンプレ:元表は触らずユニーク抽出(Dictionary)
基準列でユニーク行だけを別シートに出力します。元表はそのまま。
Sub Unique_Extract_SingleKey()
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.Calculation = xlCalculationManual
Dim rg As Range: Set rg = Worksheets("Data").Range("A1").CurrentRegion
Dim v As Variant: v = rg.Value
Dim dict As Object: Set dict = CreateObject("Scripting.Dictionary")
Dim wsOut As Worksheet: Set wsOut = EnsureSheet("ユニーク一覧", True)
' ヘッダー
wsOut.Range("A1").Resize(1, UBound(v, 2)).Value = Application.Index(v, 1, 0)
Dim outRow As Long: outRow = 2
Dim r As Long, k As String
For r = 2 To UBound(v, 1)
k = UCase$(Trim$(CStr(v(r, 1)))) ' 基準:1列目(必要なら見出し検索に変更)
If Len(k) = 0 Then GoTo cont
If Not dict.Exists(k) Then
wsOut.Range("A" & outRow).Resize(1, UBound(v, 2)).Value = Application.Index(v, r, 0)
dict(k) = True
outRow = outRow + 1
End If
cont:
Next
wsOut.Columns.AutoFit
Application.Calculation = xlCalculationAutomatic
Application.EnableEvents = True
Application.ScreenUpdating = True
MsgBox "ユニーク抽出(単一キー)が完了。件数: " & outRow - 2
End Sub
Private Function EnsureSheet(ByVal name As String, Optional ByVal clear As Boolean = True) As Worksheet
Dim ws As Worksheet
On Error Resume Next
Set ws = Worksheets(name)
On Error GoTo 0
If ws Is Nothing Then
Set ws = Worksheets.Add(After:=Worksheets(Worksheets.Count))
ws.Name = name
End If
If clear Then ws.Cells.Clear
Set EnsureSheet = ws
End Function
VB- 向いている場面: 元表を壊したくない、後工程にユニーク一覧を渡したい。
- 拡張: 見出し名から列特定にすると、列順変更に強い。
複合キーのUNIQUE化(コード×日付など)
複数列の組み合わせで「同一」を判定し、ユニーク行だけ抽出します。
Private Function BuildCompositeKey(ByVal code As Variant, ByVal ymd As Variant) As String
Dim m As String
If IsDate(ymd) Then m = Format$(CDate(ymd), "yyyy-mm-dd") Else m = CStr(ymd)
BuildCompositeKey = UCase$(Trim$(CStr(code))) & "|" & UCase$(Trim$(m))
End Function
Sub Unique_Extract_MultiKey()
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.Calculation = xlCalculationManual
Dim rg As Range: Set rg = Worksheets("Data").Range("A1").CurrentRegion
Dim v As Variant: v = rg.Value
Dim dict As Object: Set dict = CreateObject("Scripting.Dictionary")
Dim wsOut As Worksheet: Set wsOut = EnsureSheet("ユニーク複合", True)
' ヘッダー
wsOut.Range("A1").Resize(1, UBound(v, 2)).Value = Application.Index(v, 1, 0)
Dim outRow As Long: outRow = 2
Dim r As Long, key As String
For r = 2 To UBound(v, 1)
key = BuildCompositeKey(v(r, 1), v(r, 2)) ' 例:A=コード、B=日付
If Len(key) = 0 Then GoTo cont
If Not dict.Exists(key) Then
wsOut.Range("A" & outRow).Resize(1, UBound(v, 2)).Value = Application.Index(v, r, 0)
dict(key) = True
outRow = outRow + 1
End If
cont:
Next
wsOut.Columns.AutoFit
Application.Calculation = xlCalculationAutomatic
Application.EnableEvents = True
Application.ScreenUpdating = True
MsgBox "ユニーク抽出(複合キー)が完了。件数: " & outRow - 2
End Sub
VB- 向いている場面: 「コードが同じでも日付が違えば別扱い」など、現場のルールに合わせたいとき。
- コツ: 区切り文字は「|」など安全な文字を使い、日付は yyyy-mm-dd に統一。
Excel 365/2021限定:UNIQUE関数をVBAから呼ぶ
動的配列対応の環境なら、ワンライナーでユニーク抽出が可能です。
Sub Unique_WithWorksheetFunction()
Dim src As Range: Set src = Worksheets("Data").Range("A2:A1000") ' 抽出元
Dim arr As Variant
arr = WorksheetFunction.Unique(src) ' UNIQUEの戻りは配列になる(365/2021+)
' 出力
Dim wsOut As Worksheet: Set wsOut = EnsureSheet("UNIQUE関数", True)
wsOut.Range("A1").Resize(UBound(arr, 1), UBound(arr, 2)).Value = arr
MsgBox "WorksheetFunction.Uniqueで抽出完了"
End Sub
VB- 向いている場面: 最新環境で、とにかく楽に・早く終わらせたい。
- 注意点: 旧Excelでは使えない。環境要件の確認が必要。
例題で練習
'例1:元表を直接ユニーク化(最短)
Sub Example_BuiltIn()
Unique_ByBuiltIn
End Sub
'例2:単一キーでユニーク一覧を抽出(安全)
Sub Example_ExtractSingle()
Unique_Extract_SingleKey
End Sub
'例3:複合キーでユニーク一覧を抽出
Sub Example_ExtractMulti()
Unique_Extract_MultiKey
End Sub
'例4:UNIQUE関数で一瞬抽出(365/2021)
Sub Example_UniqueFunc()
Unique_WithWorksheetFunction
End Sub
VB実務の落とし穴と対策
- 表記揺れで別物扱いになる
- 対策: キーは必ず正規化(Trim+大文字化、必要なら半角化)。
- 日付の形式違いで重複扱いがズレる
- 対策: 比較前に
Format(CDate(値),"yyyy-mm-dd")へ統一。
- 対策: 比較前に
- 列順が変わると壊れる
- 対策: 見出し名から列特定(Find)を使う。ハードコードを避ける。
- 「どれを残すか」ルールが曖昧
- 対策: 先頭/最新/最大など運用ルールを決める。必要なら「プレビュー→適用」の2段階に分ける。
- 大量データで遅い
- 対策: Range→配列化、Dictionary、画面/イベント/計算の停止で高速化。
