Delete Matching Rows
Efficiency
- Using a sample of 20,000 rows in the source (read unique) and 200,000 records in the destination (delete matches) and 20 columns in both worksheets, this solution used between 5 and 15 seconds for 7167 unique 5-char strings and 85,036 deleted rows.
Module1
Option Explicit
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Purpose: In a column of a worksheet, compares the value of each cell
' with all values in a column of a worksheet in another workbook.
' If there is a match, the entire row of the first mentioned
' cell is deleted.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Calls:
' DeleteMatchingRows
' DictUniqueColumnFromThisWorkbook or DictUniqueColumnFromClosedWorkbook
' RefColumn
' GetColumnRange
' DictUniqueColumn
' RefTableRangeInThisWorkbook or RefTableRangeInClosedWorkbook
' RefCurrentRegionBottomRight
' ReplaceColumnDataMatchingInDict
' GetColumnRange
' ReplaceDataColumnMatchingInDict
' AutoFilterDeleteEntireRows
' GetColumnOfIntegers
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Sub DeleteMatchingRows()
Const ProcName As String = "DeleteMatchingRows"
Dim IsSuccess As Boolean
On Error GoTo ClearError
' Time Passed
Dim tt As Double: tt = Timer ' Total Time
Dim t As Double: t = tt ' Time Per Operation
Dim tf As String: tf = "0.0000" ' Time Format
Dim tc As Double
' Source
Const sFilePath As String = "C:\Test\2021\70269924\FileA.xlsx"
Const swsName As String = "Sheet1" ' "Sheet2"
Const sfCellAddress As String = "H2"
Const sDictItem As Variant = Empty
Dim sDictCompareMode As VbCompareMethod: sDictCompareMode = vbTextCompare
' Note that if 'dIsThisWB = False' and 'sIsThisWb = True',
' the source workbook remains open regardlessly. 'sIsThisWb = True' is used
' for testing purposes or if both workbooks are 'ThisWorkbook'.
' In the latter case, don't forget to check that the worksheet names
' are different.
Const sIsThisWB As Boolean = False ' if 'True', 'sDoCloseWB' has no effect
Const sDoCloseWB As Boolean = True ' regardlessly changes will not be saved
' Destination
Const dFilePath As String = "C:\Test\2021\70269924\FileB.xlsx"
Const dwsName As String = "Sheet1"
Const dtrgFirstCellAddress As String = "A1"
Const dCriteriaCol As Long = 7 ' range column in this case 'G'
Const dFirstReplacementRow As Long = 2
' Be careful with the following three constants, there is no undo.
Const dIsThisWB As Boolean = False
Const dDoSaveWB As Boolean = False
Const dDoCloseWB As Boolean = False
' Other
Const Replacement As String = "!"
Debug.Print "Start '" & ProcName & "'... "
' 1.
Dim dict As Object
If sIsThisWB Then
Set dict = DictUniqueColumnFromThisWorkbook( _
swsName, sfCellAddress, sDictItem, sDictCompareMode)
tc = Timer
Debug.Print "1. DictUniqueColumnFromThisWorkbook... " _
& Format(tc - t, tf) & "(" & Format(tc - tt, tf) & ")": t = tc
Else
Set dict = DictUniqueColumnFromClosedWorkbook(sFilePath, swsName, _
sfCellAddress, sDictItem, sDictCompareMode, sDoCloseWB)
tc = Timer
Debug.Print "1. DictUniqueColumnFromClosedWorkbook... " _
& Format(tc - t, tf) & "(" & Format(tc - tt, tf) & ")": t = tc
End If
Debug.Print " Found " & dict.Count & " unique values."
' 2.
' Creates a reference to the destination workbook. If the destination
' workbook is the workbook containing this code then you have to set
' the constant 'dIsThisWB' to 'True'. If the destination workbook
' is a closed workbook, you have to set the constant to 'False' and
' appropriately set the 'dFilePath' constant for the workbook to open.
' Creates a reference to the destination table range.
Dim dtrg As Range
If dIsThisWB Then
Set dtrg = RefTableRangeInThisWorkbook(dwsName, dtrgFirstCellAddress)
tc = Timer
Debug.Print "2. RefTableRangeInThisWorkbook... " _
& Format(tc - t, tf) & "(" & Format(tc - tt, tf) & ")": t = tc
Else
Set dtrg = RefTableRangeInClosedWorkbook( _
dFilePath, dwsName, dtrgFirstCellAddress)
tc = Timer
Debug.Print "2. RefTableRangeInClosedWorkbook... " _
& Format(tc - t, tf) & "(" & Format(tc - tt, tf) & ")": t = tc
End If
Debug.Print " Created a reference to the table range '" _
& dtrg.Address(0, 0) & "'" & vbLf & " in the worksheet '" _
& dwsName & "' of the workbook '" _
& dtrg.Worksheet.Parent.Name & "'" & vbLf & " in the folder '" _
& dtrg.Worksheet.Parent.Path & "'."
' 3.
Dim dcrrg As Range: Set dcrrg = dtrg.Columns(dCriteriaCol)
ReplaceColumnDataMatchingInDict _
dcrrg, dict, Replacement, dFirstReplacementRow
Set dict = Nothing
Dim dcrCount As Long: dcrCount = Application.CountIf(dcrrg, Replacement)
tc = Timer
Debug.Print "3. ReplaceColumnDataMatchingInDict... " _
& Format(tc - t, tf) & "(" & Format(tc - tt, tf) & ")": t = tc
Debug.Print " Replaced cell values with '" & Replacement & "' in " _
& dcrCount & " rows."
If dcrCount = 0 Then ' already deleted
IsSuccess = True
GoTo ProcExit
End If
' 4.
AutoFilterDeleteEntireRows dtrg, Replacement, dCriteriaCol
tc = Timer
Debug.Print "4. AutoFilterDeleteEntireRows... " _
& Format(tc - t, tf) & "(" & Format(tc - tt, tf) & ")": t = tc
Debug.Print " Deleted " & dcrCount & " matching rows."
Dim dwb As Workbook: Set dwb = dtrg.Worksheet.Parent
' To close easily when testing, don't wanna delete for now
dwb.Saved = True
' When done testing, out-comment the previous line and adjust
' the 'dIsThisWB', 'dDoCloseWB' and 'dDoSaveWB' constants.
If Not dDoCloseWB Then ' save before 'IsSuccess' if not to be closed
If dDoSaveWB Then dwb.Save
End If
IsSuccess = True
ProcExit:
On Error GoTo ClearExitError
If IsSuccess Then
If Not dIsThisWB Then ' close before the message
If dDoCloseWB Then
dwb.Close SaveChanges:=dDoSaveWB
End If
End If
MsgBox "Rows deleted: " & dcrCount, vbInformation, ProcName
' If you close 'ThisWorkbook' before the message, you won't see it.
If dIsThisWB Then ' close after the message
If dDoCloseWB Then
dwb.Close SaveChanges:=dDoSaveWB
End If
End If
Else
MsgBox "Something went wrong." & vbLf _
& "See the message in the VBE Immediate window (Ctrl+G).", _
vbCritical, ProcName
End If
Debug.Print "End '" & ProcName & "'... "
FinalExit:
Exit Sub
ClearError:
Debug.Print "'" & ProcName & "': Unexpected Error!" & vbLf _
& " " & "Run-time error '" & Err.Number & "':" & vbLf _
& " " & Err.Description
Resume ProcExit
ClearExitError:
Debug.Print "'" & ProcName & "': Unexpected Error!" & vbLf _
& " " & "Run-time error '" & Err.Number & "':" & vbLf _
& " " & Err.Description
Resume FinalExit
End Sub
Module2
Option Explicit
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Purpose: Returns the unique values, from a column range in the worksheet
' of a closed workbook, in the keys of a dictionary.
' Remarks: The default dictionary item ('DictItem') is 'Empty'.
' The default dictionary compare mode ('DictCompareMode')
' is 'vbTextCompare' i.e. 'A = a'.
' By default, closes the workbook not saving changes.
' Removes any filters, being relevant if the workboook stays open.
' Remarks: By default, closes the workbook not saving changes.
' Calls: 'RefColumn','GetColumnRange', and 'DictUniqueColumn'.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function DictUniqueColumnFromClosedWorkbook( _
ByVal FilePath As String, _
ByVal WorksheetName As String, _
Optional ByVal FirstCellAddress As String = "A1", _
Optional ByVal DictItem As Variant = Empty, _
Optional ByVal DictCompareMode As VbCompareMethod = vbTextCompare, _
Optional ByVal DoCloseWorkbook As Boolean = True) _
As Object
Const ProcName As String = "DictUniqueColumnFromClosedWorkbook"
On Error GoTo ClearError
Dim wb As Workbook: Set wb = Workbooks.Open(FilePath)
Dim ws As Worksheet: Set ws = wb.Worksheets(WorksheetName)
If ws.AutoFilterMode Then ws.AutoFilterMode = False
Dim fCell As Range: Set fCell = ws.Range(FirstCellAddress)
Dim Data As Variant: Data = GetColumnRange(RefColumn(fCell))
Set DictUniqueColumnFromClosedWorkbook _
= DictUniqueColumn(Data, 1, DictItem, DictCompareMode)
If DoCloseWorkbook Then wb.Close SaveChanges:=False
ProcExit:
Exit Function
ClearError:
Debug.Print "'" & ProcName & "': Unexpected Error!" & vbLf _
& " " & "Run-time error '" & Err.Number & "':" & vbLf _
& " " & Err.Description
Resume ProcExit
End Function
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Purpose: Returns the unique values, from a column range in a worksheet
' of the workbook containing this code, 'Thisworkbook',
' in the keys of a dictionary.
' Remarks: The default dictionary item ('DictItem') is 'Empty'.
' The default dictionary compare mode ('DictCompareMode')
' is 'vbTextCompare' i.e. 'A = a'.
' Removes any filters.
' Calls: 'RefColumn','GetColumnRange', and 'DictUniqueColumn'.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function DictUniqueColumnFromThisWorkbook( _
ByVal WorksheetName As String, _
Optional ByVal FirstCellAddress As String = "A1", _
Optional ByVal DictItem As Variant = Empty, _
Optional ByVal DictCompareMode As VbCompareMethod = vbTextCompare) _
As Object
Const ProcName As String = "DictUniqueColumnFromThisWorkbook"
On Error GoTo ClearError
Dim ws As Worksheet: Set ws = ThisWorkbook.Worksheets(WorksheetName)
If ws.AutoFilterMode Then ws.AutoFilterMode = False
Dim fCell As Range: Set fCell = ws.Range(FirstCellAddress)
Dim Data As Variant: Data = GetColumnRange(RefColumn(fCell))
Set DictUniqueColumnFromThisWorkbook _
= DictUniqueColumn(Data, 1, DictItem, DictCompareMode)
ProcExit:
Exit Function
ClearError:
Debug.Print "'" & ProcName & "': Unexpected Error!" & vbLf _
& " " & "Run-time error '" & Err.Number & "':" & vbLf _
& " " & Err.Description
Resume ProcExit
End Function
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Purpose: Opens a workbook and for one of its worksheets,
' creates a reference to a table range (headers).
' Remarks: The workbook stays open and it can be referenced e.g. with
' ' Dim wb As Workbook: Set wb = rg.Worksheet.Parent'.
' Removes any filters.
' Calls: 'RefCurrentRegionBottomRight'.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function RefTableRangeInClosedWorkbook( _
ByVal FilePath As String, _
ByVal WorksheetName As String, _
Optional ByVal FirstCellAddress As String = "A1") _
As Range
Const ProcName As String = "RefTableRangeInClosedWorkbook"
On Error GoTo ClearError
Dim wb As Workbook: Set wb = Workbooks.Open(FilePath)
Dim ws As Worksheet: Set ws = wb.Worksheets(WorksheetName)
If ws.AutoFilterMode Then ws.AutoFilterMode = False
Dim fCell As Range: Set fCell = ws.Range(FirstCellAddress)
Set RefTableRangeInClosedWorkbook = RefCurrentRegionBottomRight(fCell)
ProcExit:
Exit Function
ClearError:
Debug.Print "'" & ProcName & "': Unexpected Error!" & vbLf _
& " " & "Run-time error '" & Err.Number & "':" & vbLf _
& " " & Err.Description
Resume ProcExit
End Function
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Purpose: In the workbook containing this code ('Thisworkbook'),
' for one of its worksheets, creates a reference
' to a table range (headers).
' Remarks: Removes any filters.
' Calls: 'RefCurrentRegionBottomRight'.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function RefTableRangeInThisWorkbook( _
ByVal WorksheetName As String, _
Optional ByVal FirstCellAddress As String = "A1") _
As Range
Const ProcName As String = "RefTableRangeInThisWorkbook"
On Error GoTo ClearError
Dim ws As Worksheet: Set ws = ThisWorkbook.Worksheets(WorksheetName)
If ws.AutoFilterMode Then ws.AutoFilterMode = False
Dim fCell As Range: Set fCell = ws.Range(FirstCellAddress)
Set RefTableRangeInThisWorkbook = RefCurrentRegionBottomRight(fCell)
ProcExit:
Exit Function
ClearError:
Debug.Print "'" & ProcName & "': Unexpected Error!" & vbLf _
& " " & "Run-time error '" & Err.Number & "':" & vbLf _
& " " & Err.Description
Resume ProcExit
End Function
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Purpose: Replaces the values in a column of a range, found
' in the keys of a dictionary, with a string.
' Remarks: Formulas in the column will be converted to values.
' Calls: 'GetColumnRange','ReplaceDataColumnMatchingInDict'.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Sub ReplaceColumnDataMatchingInDict( _
ByRef rg As Range, _
ByVal dict As Object, _
ByVal Replacement As String, _
Optional ByVal FirstReplacementRow As Long = 1, _
Optional ByVal ColumnNumber As Long = 1)
Const ProcName As String = "ReplaceColumnDataMatchingInDict"
On Error GoTo ClearError
Dim crg As Range: Set crg = rg.Columns(ColumnNumber)
Dim cData As Variant: cData = GetColumnRange(crg)
ReplaceDataColumnMatchingInDict _
cData, dict, Replacement, FirstReplacementRow
crg.Value = cData
ProcExit:
Exit Sub
ClearError:
Debug.Print "'" & ProcName & "': Unexpected Error!" & vbLf _
& " " & "Run-time error '" & Err.Number & "':" & vbLf _
& " " & Err.Description
Resume ProcExit
End Sub
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Purpose: Filters a range on a string and deletes the entire rows
' of the filtered (visible) cells.
' Remarks: Removes any filters.
' Calls: 'GetColumnOfIntegers'.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Sub AutoFilterDeleteEntireRows( _
ByVal TableRange As Range, _
ByVal FilterString As String, _
Optional ByVal FilterField As Long = 1)
Const ProcName As String = "AutoFilterDeleteEntireRows"
On Error GoTo ClearError
Dim ws As Worksheet: Set ws = TableRange.Worksheet
If ws.AutoFilterMode Then ws.AutoFilterMode = False
Dim trrCount As Long: trrCount = TableRange.Rows.Count
Dim ntrcCount As Long: ntrcCount = TableRange.Columns.Count + 1 ' new
' Increase the table range by a column and create a reference to it.
Dim NewTableRange As Range
Set NewTableRange = TableRange.Resize(, ntrcCount)
' Write incrementing numbers to the new column.
With NewTableRange
With .Columns(ntrcCount) ' new last column
.Cells(1).Value = "C!!!" ' header
.Resize(trrCount - 1).Offset(1).Value _
= GetColumnOfIntegers(1, trrCount - 1) ' sequence of numbers
End With
' Sort the criteria column ascending to get all criteria strings
' one after the other to increase the effieciency of deleting rows
' since there will be only one range area i.e. a contiguous range.
.Sort .Columns(FilterField), xlAscending, , , , , , xlYes
' Create a reference to the data range, the new table range
' without headers. Do it before the auto-filtering.
Dim DataRange As Range: Set DataRange = .Resize(trrCount - 1).Offset(1)
.AutoFilter FilterField, FilterString ' with headers
' Create a reference to the filtered 'entire-row-range'
' ('DataVisibleRows') and delete it.
Dim DataVisibleRows As Range
On Error Resume Next
Set DataVisibleRows = DataRange _
.SpecialCells(xlCellTypeVisible).EntireRow
On Error GoTo ClearError
If Not DataVisibleRows Is Nothing Then DataVisibleRows.Delete
ws.AutoFilterMode = False
' Sort the new table range by its last column and clear it.
.Sort .Columns(ntrcCount), xlAscending, , , , , , xlYes
.Columns(ntrcCount).Clear
End With
ProcExit:
Exit Sub
ClearError:
Debug.Print "'" & ProcName & "': Unexpected Error!" & vbLf _
& " " & "Run-time error '" & Err.Number & "':" & vbLf _
& " " & Err.Description
Resume ProcExit
End Sub
Module3
Option Explicit
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Purpose: Creates a reference to the one-column range from the first cell
' of a range ('FirstCell') to the bottom-most non-empty cell
' of the first cell's worksheet column.
' Remarks: It is not safe to use it with merged cells and in filtered
' worksheets. Hidden rows or columns are allowed.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function RefColumn( _
ByVal FirstCell As Range) _
As Range
Const ProcName As String = "RefColumn"
On Error GoTo ClearError
With FirstCell.Cells(1)
Dim lCell As Range
Set lCell = .Resize(.Worksheet.Rows.Count - .Row + 1) _
.Find("*", , xlFormulas, , , xlPrevious)
Set RefColumn = .Resize(lCell.Row - .Row + 1)
End With
ProcExit:
Exit Function
ClearError:
Debug.Print "'" & ProcName & "': Unexpected Error!" & vbLf _
& " " & "Run-time error '" & Err.Number & "':" & vbLf _
& " " & Err.Description
Resume ProcExit
End Function
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Purpose: Writes the values from a column ('ColumnNumber')
' of a range ('rg') to a 2D one-based one-column array.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function GetColumnRange( _
ByVal rg As Range, _
Optional ByVal ColumnNumber As Long = 1) _
As Variant
Const ProcName As String = "GetColumnRange"
On Error GoTo ClearError
With rg.Columns(ColumnNumber)
If rg.Rows.Count = 1 Then
Dim Data As Variant: ReDim Data(1 To 1, 1 To 1): Data(1, 1) = .Value
GetColumnRange = Data
Else
GetColumnRange = .Value
End If
End With
ProcExit:
Exit Function
ClearError:
Debug.Print "'" & ProcName & "': Unexpected Error!" & vbLf _
& " " & "Run-time error '" & Err.Number & "':" & vbLf _
& " " & Err.Description
Resume ProcExit
End Function
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Purpose: Returns the unique values, from a column ('ColumnIndex')
' of a 2D one-based array ('Data'), in the keys of a dictionary.
' The default dictionary item ('DictItem') is 'Empty'
' The default dictionary compare method ('DictCompareMethod')
' is 'vbTextCompare' i.e. 'A=a'.
' Remarks: Error and empty values are excluded.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function DictUniqueColumn( _
ByVal Data As Variant, _
Optional ByVal ColumnIndex As Long = 1, _
Optional ByVal DictItem As Variant = Empty, _
Optional ByVal DictCompareMode As VbCompareMethod = vbTextCompare) _
As Object
Const ProcName As String = "DictUniqueColumn"
On Error GoTo ClearError
Dim dict As Object: Set dict = CreateObject("Scripting.Dictionary")
dict.CompareMode = DictCompareMode
Dim Key As Variant
Dim r As Long
For r = 1 To UBound(Data, 1)
Key = Data(r, ColumnIndex)
If Not IsError(Key) Then ' exclude error values
If Not IsEmpty(Key) Then ' exclude empty values
dict(Key) = DictItem
End If
End If
Next r
Set DictUniqueColumn = dict
ProcExit:
Exit Function
ClearError:
Debug.Print "'" & ProcName & "': Unexpected Error!" & vbLf _
& " " & "Run-time error '" & Err.Number & "':" & vbLf _
& " " & Err.Description
Resume ProcExit
End Function
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Purpose: Returns a reference to the range from a cell ('FirstCell')
' to the last cell of its current region.
' Remarks: Useful when there is data (e.g. a title) adjacent
' to the top or to the left of a table range
' (obviously not allowed in an Excel table range).
' If the first cell is cell 'A1' or there is no adjacent data,
' it references the current region.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function RefCurrentRegionBottomRight( _
ByVal FirstCell As Range) _
As Range
Const ProcName As String = "RefCurrentRegionBottomRight"
On Error GoTo ClearError
With FirstCell.Cells(1).CurrentRegion
Set RefCurrentRegionBottomRight = _
FirstCell.Resize(.Row + .Rows.Count - FirstCell.Row, _
.Column + .Columns.Count - FirstCell.Column)
End With
ProcExit:
Exit Function
ClearError:
Debug.Print "'" & ProcName & "': Unexpected Error!" & vbLf _
& " " & "Run-time error '" & Err.Number & "':" & vbLf _
& " " & Err.Description
Resume ProcExit
End Function
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Purpose: Compares the values in a column of a 2D one-based array ('Data')
' with the values in the keys of a dictionary ('dict')
' and replaces any matching values in the array,
' with a string ('Replacement').
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Sub ReplaceDataColumnMatchingInDict( _
ByRef Data As Variant, _
ByVal dict As Object, _
ByVal Replacement As String, _
Optional ByVal FirstReplacementRow As Long = 1, _
Optional ByVal DataColumn As Long = 1)
Const ProcName As String = "ReplaceDataColumnMatchingInDict"
On Error GoTo ClearError
Dim Key As Variant
Dim dr As Long
For dr = FirstReplacementRow To UBound(Data, 1)
Key = Data(dr, DataColumn)
If Not IsError(Key) Then
If Len(Key) > 0 Then
If dict.Exists(Key) Then
Data(dr, DataColumn) = Replacement
End If
End If
End If
Next dr
ProcExit:
Exit Sub
ClearError:
Debug.Print "'" & ProcName & "': Unexpected Error!" & vbLf _
& " " & "Run-time error '" & Err.Number & "':" & vbLf _
& " " & Err.Description
Resume ProcExit
End Sub
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Purpose: Returns a sequence of integers
' in a 2D one-base one-column array.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function GetColumnOfIntegers( _
ByVal StartInteger As Long, _
ByVal EndInteger As Long, _
Optional ByVal StepInteger As Long = 1) _
As Variant
Const ProcName As String = "GetColumnOfIntegers"
On Error GoTo ClearError
Dim IsStepPositive As Boolean: IsStepPositive = (StartInteger <= EndInteger)
Dim siCount As Long
Dim drCount As Long
If IsStepPositive Then
siCount = EndInteger - StartInteger + 1
Else
siCount = StartInteger - EndInteger + 1
End If
Dim siStep As Long: siStep = Abs(StepInteger)
drCount = Int(siCount / siStep)
If siCount Mod siStep > 0 Then
drCount = drCount + 1
End If
If Not IsStepPositive Then
siStep = -siStep
End If
Dim dData() As Long: ReDim dData(1 To drCount, 1 To 1)
Dim si As Long
Dim dr As Long
For si = StartInteger To EndInteger Step siStep
dr = dr + 1
dData(dr, 1) = si
Next si
GetColumnOfIntegers = dData
ProcExit:
Exit Function
ClearError:
Debug.Print "'" & ProcName & "': Unexpected Error!" & vbLf _
& " " & "Run-time error '" & Err.Number & "':" & vbLf _
& " " & Err.Description
Resume ProcExit
End Function
Sheet12. Store the above data in an array 3. Store Col G from 2nd File in an array 4. Search 1st array in 2nd array and if found replace value by say "DELME" 5. Write the 2nd array back to the worksheet 6. Autofilter column G on "DELME" and delete all rows in 1 go.Exists- that should be pretty fast. When there's a match, add a cell from that row to a Collection. When done, loop over the collection and build a Union'ed range of rows to be deleted, deleting maybe 500 at a time (union get progressively slower as you add more and more cells).