Removing duplicate data is one of the most common Excel automation tasks for UK businesses processing large datasets. Whether you're cleaning customer records, consolidating sales data, or preparing reports, duplicate entries can cause significant problems in data analysis and decision-making.
This comprehensive guide presents 5 production-ready VBA methods to remove duplicates in Excel, from simple single-column solutions to advanced multi-criteria approaches used by UK enterprises.
Why Use VBA for Removing Duplicates?
While Excel offers built-in duplicate removal tools, VBA provides several critical advantages for business automation:
- Automation: Run duplicate removal as part of larger data processing workflows
- Custom logic: Choose which duplicates to keep (first, last, or specific criteria)
- Multiple sheets: Process entire workbooks automatically
- Scheduled execution: Integrate with Windows Task Scheduler for regular data cleaning
- Complex criteria: Remove duplicates based on multiple columns with custom matching rules
Method 1: Remove Duplicates Using RemoveDuplicates Method (Fastest)
Best For: Simple, fast duplicate removal on single or multiple columns
Excel 2007+ includes a built-in RemoveDuplicates method that's the fastest way to remove duplicates via VBA:
Sub RemoveDuplicatesMethod1()
Dim ws As Worksheet
Dim lastRow As Long
Dim dataRange As Range
' Set worksheet
Set ws = ThisWorkbook.Sheets("Sheet1")
' Find last row with data
lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
' Define data range (including headers)
Set dataRange = ws.Range("A1:C" & lastRow)
' Remove duplicates based on columns 1, 2, and 3
' Header:=xlYes means row 1 contains headers
dataRange.RemoveDuplicates Columns:=Array(1, 2, 3), Header:=xlYes
MsgBox "Duplicates removed successfully!", vbInformation
End Sub
Key Features:
- Preserves first occurrence of each unique row
- Fastest method for large datasets (100,000+ rows)
- Works with multiple columns
- Respects header rows
Method 2: Remove Duplicates from Single Column with Dictionary
Best For: Case-sensitive matching, keeping track of removed items
Using a Dictionary object provides more control and is ideal when you need case-sensitive duplicate detection:
Sub RemoveDuplicatesSingleColumn()
Dim ws As Worksheet
Dim dict As Object
Dim cell As Range
Dim lastRow As Long
Dim i As Long
Dim duplicatesRemoved As Long
' Set worksheet
Set ws = ThisWorkbook.Sheets("Sheet1")
' Create dictionary for tracking unique values
Set dict = CreateObject("Scripting.Dictionary")
dict.CompareMode = vbBinaryCompare ' Case-sensitive
' Find last row
lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
' Disable screen updating for performance
Application.ScreenUpdating = False
' Loop through data from bottom to top (safer for deletion)
For i = lastRow To 2 Step -1 ' Start from row 2 to skip header
If dict.Exists(ws.Cells(i, 1).Value) Then
' Duplicate found - delete entire row
ws.Rows(i).Delete
duplicatesRemoved = duplicatesRemoved + 1
Else
' Add to dictionary
dict.Add ws.Cells(i, 1).Value, True
End If
Next i
' Restore settings
Application.ScreenUpdating = True
MsgBox duplicatesRemoved & " duplicate rows removed.", vbInformation
End Sub
When to Use This Method:
- You need case-sensitive duplicate detection ("Apple" ≠ "apple")
- You want to count removed duplicates
- You're working with a single column of data
- You need to preserve specific duplicate occurrences
Method 3: Remove Duplicates Based on Multiple Columns
Best For: Customer records, transactions, multi-criteria matching
Many UK businesses need to identify duplicates based on multiple fields (e.g., Name + Email + Postcode):
Sub RemoveDuplicatesMultipleColumns()
Dim ws As Worksheet
Dim dict As Object
Dim lastRow As Long
Dim i As Long
Dim uniqueKey As String
Dim duplicatesRemoved As Long
' Set worksheet
Set ws = ThisWorkbook.Sheets("CustomerData")
' Create dictionary
Set dict = CreateObject("Scripting.Dictionary")
' Find last row
lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
Application.ScreenUpdating = False
' Loop from bottom to top
For i = lastRow To 2 Step -1
' Create unique key from multiple columns (Name & Email & Postcode)
uniqueKey = ws.Cells(i, 1).Value & "|" & _
ws.Cells(i, 2).Value & "|" & _
ws.Cells(i, 3).Value
If dict.Exists(uniqueKey) Then
' Duplicate - delete row
ws.Rows(i).Delete
duplicatesRemoved = duplicatesRemoved + 1
Else
' Unique - add to dictionary
dict.Add uniqueKey, True
End If
Next i
Application.ScreenUpdating = True
MsgBox "Removed " & duplicatesRemoved & " duplicate records based on Name, Email, and Postcode.", vbInformation
End Sub
Real-World Use Cases:
- CRM data cleaning (Name + Email + Phone)
- Financial transactions (Date + Amount + Reference)
- Inventory management (Product Code + Location + Batch)
Method 4: Keep Last Occurrence Instead of First
Best For: Time-series data, keeping most recent records
By default, most methods keep the first duplicate. This method keeps the most recent (last) occurrence:
Sub RemoveDuplicatesKeepLast()
Dim ws As Worksheet
Dim dict As Object
Dim lastRow As Long
Dim i As Long
Dim uniqueKey As String
Set ws = ThisWorkbook.Sheets("Sheet1")
Set dict = CreateObject("Scripting.Dictionary")
lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
Application.ScreenUpdating = False
' Loop from TOP to BOTTOM (reverse of usual)
For i = 2 To lastRow ' Start after header
uniqueKey = ws.Cells(i, 1).Value ' Adjust column as needed
If dict.Exists(uniqueKey) Then
' Delete the EARLIER occurrence (stored in dictionary)
ws.Rows(dict(uniqueKey)).Delete
lastRow = lastRow - 1 ' Adjust row count
dict(uniqueKey) = i - 1 ' Update with current row position (shifted)
Else
dict.Add uniqueKey, i
End If
Next i
Application.ScreenUpdating = True
MsgBox "Duplicates removed. Latest occurrences preserved.", vbInformation
End Sub
Perfect For:
- Customer contact records (keep latest email/phone)
- Price lists (keep most recent pricing)
- Status updates (keep latest status)
Method 5: Advanced Filter to Copy Unique Records
Best For: Preserving original data, creating clean copy
This method creates a new sheet with unique records, leaving your original data untouched:
Sub CopyUniqueRecordsToNewSheet()
Dim wsSource As Worksheet
Dim wsDestination As Worksheet
Dim lastRow As Long
Dim dataRange As Range
' Set source worksheet
Set wsSource = ThisWorkbook.Sheets("RawData")
' Create new worksheet for unique records
On Error Resume Next
Set wsDestination = ThisWorkbook.Sheets("UniqueData")
On Error GoTo 0
If wsDestination Is Nothing Then
Set wsDestination = ThisWorkbook.Sheets.Add(After:=wsSource)
wsDestination.Name = "UniqueData"
Else
wsDestination.Cells.Clear ' Clear existing data
End If
' Find last row
lastRow = wsSource.Cells(wsSource.Rows.Count, "A").End(xlUp).Row
' Define data range
Set dataRange = wsSource.Range("A1:C" & lastRow)
' Use Advanced Filter to copy unique records
dataRange.AdvancedFilter Action:=xlFilterCopy, _
CopyToRange:=wsDestination.Range("A1"), _
Unique:=True
' Auto-fit columns
wsDestination.Columns("A:C").AutoFit
MsgBox "Unique records copied to 'UniqueData' sheet.", vbInformation
End Sub
Advantages:
- Original data remains untouched
- Easy to compare before/after
- Can be run multiple times safely
- Creates audit trail
Performance Comparison: Which Method is Fastest?
Performance benchmarks for different dataset sizes:
Method 1: RemoveDuplicates
- 10K Rows: 0.2s | 100K Rows: 2s
- Best for: Large datasets
Method 2: Dictionary (Single Column)
- 10K Rows: 0.5s | 100K Rows: 8s
- Best for: Case-sensitive matching
Method 3: Dictionary (Multiple Columns)
- 10K Rows: 0.7s | 100K Rows: 12s
- Best for: Multi-criteria matching
Method 4: Keep Last Occurrence
- 10K Rows: 0.6s | 100K Rows: 10s
- Best for: Latest records only
Method 5: Advanced Filter
- 10K Rows: 0.3s | 100K Rows: 4s
- Best for: Preserve original data
Common Pitfalls and How to Avoid Them
1. Not Handling Blank Cells
Blank cells can be treated as duplicates. Add this check:
If ws.Cells(i, 1).Value <> "" Then
' Your duplicate checking code
End If
2. Forgetting to Disable Screen Updating
Always disable screen updating when deleting rows:
Application.ScreenUpdating = False
' Your code
Application.ScreenUpdating = True
3. Deleting Rows from Top to Bottom
Always loop from bottom to top when deleting rows:
For i = lastRow To 2 Step -1 ' Correct
' Not: For i = 2 To lastRow ' Wrong!
Complete Production-Ready Solution
Here's a robust, error-handled version suitable for UK business use:
Sub RemoveDuplicates_Production()
On Error GoTo ErrorHandler
Dim ws As Worksheet
Dim lastRow As Long
Dim dataRange As Range
Dim startTime As Double
Dim duplicatesRemoved As Long
' Start timer
startTime = Timer
' Set worksheet
Set ws = ThisWorkbook.Sheets("Sheet1")
' Validate data exists
If ws.Cells(2, 1).Value = "" Then
MsgBox "No data found to process.", vbExclamation
Exit Sub
End If
' Find last row
lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
' Store original count
duplicatesRemoved = lastRow - 1 ' Minus header
' Define data range
Set dataRange = ws.Range("A1:C" & lastRow)
' Performance optimisation
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Application.EnableEvents = False
' Remove duplicates
dataRange.RemoveDuplicates Columns:=Array(1, 2, 3), Header:=xlYes
' Calculate removed count
lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
duplicatesRemoved = duplicatesRemoved - (lastRow - 1)
' Restore settings
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
Application.EnableEvents = True
' Report results
MsgBox duplicatesRemoved & " duplicates removed in " & _
Format(Timer - startTime, "0.00") & " seconds.", vbInformation
Exit Sub
ErrorHandler:
' Restore settings on error
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
Application.EnableEvents = True
MsgBox "Error: " & Err.Description, vbCritical
End Sub
Frequently Asked Questions
Can I remove duplicates from multiple sheets at once?
Yes! Wrap any of the methods above in a loop through worksheets:
Dim ws As Worksheet
For Each ws In ThisWorkbook.Worksheets
' Your duplicate removal code here
Next ws
How do I remove duplicates but keep a summary count?
Use the Dictionary method and add a counter to track occurrences before deletion.
Can I undo duplicate removal?
VBA deletions cannot be undone with Ctrl+Z. Always create a backup or use Method 5 (Advanced Filter) to preserve original data.
What about case-insensitive matching?
Change the Dictionary CompareMode:
dict.CompareMode = vbTextCompare ' Case-insensitive
' vs
dict.CompareMode = vbBinaryCompare ' Case-sensitive
Ready to Automate Your Duplicate Removal?
These 5 methods cover every common duplicate removal scenario for UK businesses. Whether you're processing customer data, financial records, or inventory lists, one of these solutions will fit your needs.
Next Steps:
- Download the complete code examples as a ready-to-use Excel workbook
- Need a custom duplicate removal solution? Try our AI VBA Code Generator
- Browse our VBA template library for more data cleaning solutions
Last updated: January 2025