Find data and move to prior cell and find again using active cell value - problems faced - excel

Its update to my prior question for which i missed to add point saying that column 3 Header data might start with space or at the end or any additional text in it hence we should try it with contains.
Count results should be shown in a new sheet for all filter entities like 3 (Index) 3(Level) AIUH (Entity Name) 3(Count) with additional column to the end of the table and rows will not be
I apologize for my bad etiquette and wasting experts time on this to work again.
Here is the previous code for reference:
Sub xferAscendingFiltered()
Dim cnt As Long, rHDR As Range, rDELs As Range, vFLTRs As Variant
'fill this array with your 40-50 Header values
vFLTRs = Array("AIS", "BBS", "AIUH", _
"XXX", "YYY", "ZZZ")
With Worksheets("Sheet2")
If .AutoFilterMode Then .AutoFilterMode = False
With .Cells(1, 1).CurrentRegion
'filter on all the values in the array
.AutoFilter Field:=3, Criteria1:=vFLTRs, Operator:=xlFilterValues
'walk through the visible rows
With .Resize(.Rows.Count - 1, 1).Offset(0, 2)
Set rHDR = .Find(What:=Chr(42), After:=.Cells(1, 1), _
SearchOrder:=xlByRows, SearchDirection:=xlNext)
'seed the rows to delete so Union can be used later
If rHDR.Row > 1 Then _
Set rDELs = rHDR
Do While rHDR.Row > 1
cnt = 0
'increase cnt by both visible and hidden cells
Do
cnt = cnt + 1
Loop While rHDR.Offset(cnt, -1).Value2 > rHDR.Offset(cnt - 1, -1).Value2 And _
Intersect(rHDR.Offset(cnt, 0), .SpecialCells(xlCellTypeVisible)) Is Nothing
'transfer the values and clear the original(s)
With .Cells(rHDR.Row, 1).Resize(cnt, 3).Offset(0, -2)
'transfer the values
Worksheets("Sheet3").Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Resize(.Rows.Count, .Columns.Count) = .Value
'set teh count
Worksheets("Sheet3").Cells(Rows.Count, 1).End(xlUp).Offset(1 - cnt, 3) = cnt
Set rDELs = Union(rDELs, .Cells)
rHDR.Clear
End With
'get next visible Header in column C
Set rHDR = .FindNext(After:=.Cells(1, 1))
Loop
.AutoFilter
End With
End With
'remove the rows
rDELs.EntireRow.Delete
End With
End Sub
Prior question link:
Thanks experts

Wildcards in your filter code.
To use contains using a variable, this should work as the criteria to find:
This will loop through the array and place a 1 beside a match, then filter column D for 1
Sub xferAscendingFiltered()
Dim cnt As Long, rHDR As Range, rDELs As Range, vFLTRs As Variant
'-------------
Dim rng As Range, cel As Range, LstRw As Long, sh As Worksheet, i '<<<<<
Set sh = Sheets("Sheet2") '<<<<<<<<
'---------------
'fill this array with your 40-50 Header values
vFLTRs = Array("AIUH", "ASC", "ABB", "BBS", "YYY", "ZZZ")
'vFLTRs = Array("*BBS*", "*ABB*", "*ASC*", "*AIUH*")
With sh
'-----------------------------------<<<<<<
LstRw = .Cells(.Rows.Count, "C").End(xlUp).Row
Set rng = Range("C2:C" & LstRw)
'----Loop Through Array-----
For i = LBound(vFLTRs) To UBound(vFLTRs)
For Each cel In rng.Cells
If cel Like "*" & vFLTRs(i) & "*" Then
cel.Offset(, 1) = 1
End If
Next cel
Next i
With .Cells(1, 1).CurrentRegion
'filter on all the values in the array
.AutoFilter Field:=4, Criteria1:=1
'-----------------------------------<<<<<<<<<
'walk through the visible rows
With .Resize(.Rows.Count - 1, 1).Offset(0, 2)
Set rHDR = .Find(What:=Chr(42), After:=.Cells(1, 1), SearchOrder:=xlByRows, SearchDirection:=xlNext)
'seed the rows to delete so Union can be used later
If rHDR.Row > 1 Then Set rDELs = rHDR
Do While rHDR.Row > 1
cnt = 0
'increase cnt by both visible and hidden cells
Do
cnt = cnt + 1
Loop While rHDR.Offset(cnt, -1).Value2 > rHDR.Offset(cnt - 1, -1).Value2 And _
Intersect(rHDR.Offset(cnt, 0), .SpecialCells(xlCellTypeVisible)) Is Nothing
'transfer the values and clear the original(s)
With .Cells(rHDR.Row, 1).Resize(cnt, 3).Offset(0, -2)
Worksheets("Sheet3").Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Resize(.Rows.Count, .Columns.Count) = .Value
Set rDELs = Union(rDELs, .Cells)
rHDR.Clear
End With
'get next visible Header in column C
Set rHDR = .FindNext(After:=.Cells(1, 1))
Loop
.AutoFilter
End With
End With
'remove the rows
rDELs.EntireRow.DELETE
End With
End Sub

Related

Issue with inserting / arranging columns using VBA

I have an excel worksheeet which has a number of columns, typically from A to AZ. I've written something in VBA which is supposed to arrange and clean this worksheet by calling other subroutines, each which perform an individual task such as formatting, deleting rows, inserting new columns and moving and renaming existing ones.
I'm very new to VBA, so a lot of what I have written is what I've managed to find on here or google. I'm not sure whether the way I have written this is the best way of performing the task.
The problem I have is that the first part one of the subs (arrangeColumns) which is supposed to insert a new column at A somtimes works. The other times it appears to copy the entire worksheet and duplicate it so that my columns now go from A - AZ and are duplicated again from BA - CZ.
From what what little knowledge I have I've managed to find out that when I run this sub on its own it does work, however when this sub is called from my main part it doesnt peform as it should.
Apart from the very first column not being inserted correctly the rest of the code seems to work. Any help or suggestions welcome! thanks
Sub ArrangeColumns()
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets("test")
'inserts Index column at A. This is the part that seems to fail and duplicates the worksheet
ws.Range("A1").EntireColumn.Insert
ws.Range("A1").Value = "Index"
'identifies last column
Dim lastColumn As Long
lastColumn = ws.Cells.Find("*", SearchOrder:=xlByColumns, SearchDirection:=xlPrevious).column
'Finds the column Timestamp: Time and moves to B, renames to Date
Dim column As Range
For Each column In ws.Range("A1:" & Split(ws.Cells(1, lastColumn).Address, "$")(1) & "1").Cells
If column.Value = "Timestamp: Time" Then
column.EntireColumn.Cut
ws.Range("B1").Insert shift:=xlToRight
ws.Range("B1").Value = "Date"
Exit For
End If
Next column
'inserts Time column at C
ws.Range("C1").EntireColumn.Insert
ws.Range("C1").Value = "Time"
'inserts blank column at D
ws.Range("D1").EntireColumn.Insert
ws.Range("D1").Value = "Blank"
'finds the column Body and moves to E
For Each column In ws.Range("A1:" & Split(ws.Cells(1, lastColumn).Address, "$")(1) & "1").Cells
If column.Value = "Body" Then
column.EntireColumn.Cut
ws.Range("E1").Insert shift:=xlToRight
Exit For
End If
Next column
'find the From column and moves to F
For Each column In ws.Range("A1:" & Split(ws.Cells(1, lastColumn).Address, "$")(1) & "1").Cells
If column.Value = "From" Then
column.EntireColumn.Cut
ws.Range("F1").Insert shift:=xlToRight
ws.Range("F1").Value = "From User"
Exit For
End If
Next column
'inserts From Attributed column at G
ws.Range("G1").EntireColumn.Insert
ws.Range("G1").Value = "From Attributed"
'find th To column and moves to H, renames to To User
For Each column In ws.Range("A1:" & Split(ws.Cells(1, lastColumn).Address, "$")(1) & "1").Cells
If column.Value = "To" Then
column.EntireColumn.Cut
ws.Range("H1").Insert shift:=xlToRight
ws.Range("H1").Value = "To User"
Exit For
End If
Next column
'inserts To Attributed at I
ws.Range("I1").EntireColumn.Insert
ws.Range("I1").Value = "To Attributed"
'finds Participants column and moves to J
For Each column In ws.Range("A1:" & Split(ws.Cells(1, lastColumn).Address, "$")(1) & "1").Cells
If column.Value = "Participants" Then
column.EntireColumn.Cut
ws.Range("J1").Insert shift:=xlToRight
Exit For
End If
Next column
'Finds Source column and moves to K
For Each column In ws.Range("A1:" & Split(ws.Cells(1, lastColumn).Address, "$")(1) & "1").Cells
If column.Value = "Source" Then
column.EntireColumn.Cut
ws.Range("K1").Insert shift:=xlToRight
Exit For
End If
Next column
End Sub
Sub deleteFirstRow()
'deletes the first row of the worksheet
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets("test")
ws.Rows(1).Delete
End Sub
Sub convertToRange()
'loops throught the worksheet to find all tables and converts to range
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets("test")
Dim table As ListObject
For Each table In ws.ListObjects
table.Range.Copy
table.Unlist
Next table
End Sub
Sub clearFilter()
'removes all filters on activesheet
On Error Resume Next
ActiveSheet.ShowAllData
End Sub
Sub formatting()
'if this sub is called after cleaning the columns, then the index will be blank. This uses the column titled '#' to find the lastrow
Dim lastRow As Long
Dim lastColumn As Long
Dim col As Range
Set col = Rows(1).Find("#", LookIn:=xlValues, lookat:=xlWhole)
lastRow = Cells(Rows.Count, col.column).End(xlUp).Row
lastColumn = Cells(1, columns.Count).End(xlToLeft).column
Dim rngAll As Range
Set rngAll = Range(Cells(1, 1), Cells(lastRow, lastColumn))
Dim rngTopRow As Range
Set rngTopRow = Range(Cells(1, 1), Cells(1, lastColumn))
Dim rngSecondRowDown As Range
Set rngSecondRowDown = Range(Cells(2, 1), Cells(lastRow, lastColumn))
With rngAll
.Borders.LineStyle = xlContinuous
.Borders.Weight = xlThin
.Borders.ColorIndex = xlAutomatic
.HorizontalAlignment = xlCenter
.VerticalAlignment = xlCenter
.Borders(xlInsideHorizontal).LineStyle = xlContinuous
.Borders(xlInsideHorizontal).Weight = xlThin
.Borders(xlInsideHorizontal).ColorIndex = xlAutomatic
.Borders(xlInsideVertical).LineStyle = xlContinuous
.Borders(xlInsideVertical).Weight = xlThin
.Borders(xlInsideVertical).ColorIndex = xlAutomatic
End With
'sets the colour, font and row size of the first row
With rngTopRow
.Interior.Color = RGB(48, 84, 150)
.Font.Color = vbWhite
.Font.Bold = True
.RowHeight = 40
End With
'sets colour, borders and row size of rows 2 to lastrow
With rngSecondRowDown
.Interior.Color = RGB(255, 255, 255)
.RowHeight = 50
End With
End Sub
Sub splitDateTime()
'if this sub is called after cleaning the columns, then the index will be blank. This uses the column titled '#' to find the lastrow
'Splits the values in column B from 'dd/mm/yyyy hh:mm:ss' by space and moves 'hh:mm:ss' to column c
Dim lastRow As Long
Dim col As Range
Set col = Rows(1).Find("#", LookIn:=xlValues, lookat:=xlWhole)
lastRow = Cells(Rows.Count, col.column).End(xlUp).Row
For i = 2 To lastRow
Cells(i, 3).Value = Mid(Cells(i, 2).Value, 12, 16)
Cells(i, 2).Value = Left(Cells(i, 2).Value, 10)
Next i
End Sub
Sub columnWidth()
columns("a").columnWidth = 15
columns("b").columnWidth = 11
columns("c:d").columnWidth = 15
columns("e").columnWidth = 30
columns("f:i").columnWidth = 22
columns("j").columnWidth = 40
End Sub
Sub applyFilter()
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets("test")
Dim rngAll As Range
Dim lastRow As Long
Dim lastColumn As Long
Dim col As Range
Set col = Rows(1).Find("#", LookIn:=xlValues, lookat:=xlWhole)
lastRow = Cells(Rows.Count, col.column).End(xlUp).Row
lastColumn = Cells(1, columns.Count).End(xlToLeft).column
Set rngAll = Range(Cells(1, 1), Cells(lastRow, lastColumn))
rngAll.AutoFilter
End Sub
Sub arrangeWorksheet()
Call clearFilter
Call deleteFirstRow
Call convertToRange
Call ArrangeColumns
Call formatting
Call splitDateTime
Call columnWidth
Call applyFilter
End Sub
There is a bunch of repeated logic/steps in your ArrangeColumns which could be pushed out into a separate reusable method.
For example:
Sub arrangeWorksheet()
Call ArrangeColumns
End Sub
Sub ArrangeColumns()
Dim ws As Worksheet, rwHeaders As Range
Set ws = ThisWorkbook.Sheets("test")
Set rwHeaders = ws.Rows(1) 'headers are here
MoveOrAddColumn rwHeaders, "", "Index", "A"
MoveOrAddColumn rwHeaders, "Timestamp: Time", "Date", "B"
MoveOrAddColumn rwHeaders, "", "Time", "C"
MoveOrAddColumn rwHeaders, "", "Blank", "D"
MoveOrAddColumn rwHeaders, "Body", "", "E"
MoveOrAddColumn rwHeaders, "From", "From User", "F"
MoveOrAddColumn rwHeaders, "", "From Attributed", "G"
MoveOrAddColumn rwHeaders, "To", "To User", "H"
MoveOrAddColumn rwHeaders, "", "To Attributed", "I"
MoveOrAddColumn rwHeaders, "Participants", "", "J"
MoveOrAddColumn rwHeaders, "Source", "", "K"
End Sub
'With all headers in range `rwHeaders`...
'Move a column named `existingColName` to `destColLetter` (if existingColName is supplied)
'Otherwise insert a new column at position `destColLetter`
'Moved/inserted column is given header `newColName` (if supplied)
Sub MoveOrAddColumn(rwHeaders As Range, existingColName, newColName, destColLetter)
Dim m, colRng As Range, f As Range, cDest As Range, moving
Set cDest = rwHeaders.Columns(destColLetter) 'destination if moving, or new column
moving = Len(existingColName) > 0
If moving Then 'moving an existing column?
Set f = rwHeaders.Find(what:=existingColName, lookat:=xlWhole)
If f Is Nothing Then
MsgBox "Column header '" & existingColName & "' not found!"
Exit Sub
Else
If f.column <> cDest.column Then 'check if already in the requested postion
cDest.EntireColumn.Insert shift:=xlToRight
Set cDest = cDest.Offset(0, -1) 're-point reference
f.EntireColumn.Copy cDest
f.EntireColumn.Delete
End If
End If
Else
cDest.EntireColumn.Insert shift:=xlToRight
Set cDest = cDest.Offset(0, -1) 're-point reference
End If
If Len(newColName) > 0 Then cDest.Value = newColName
End Sub

Select only first 5 values of a column after applying a filter to a particular column on a particular condition,without duplicates

i have applied autofilter to the column,that part pf the code is running properly ,but on that condition there are suppose 20 values in that column but i want only 5 ,any particular code would help
Dim rFirstFilteredRow As Range
With Worksheets("Sheet1")
With .Cells(1, 1).CurrentRegion
ActiveSheet.Range("$A$1:$D$6").AutoFilter Field:=4, Criteria1:="1"
With .Resize(.Rows.Count - 1, .Rows.Count).Offset(1, 0)
If CBool(Application.Subtotal(103, .Cells)) Then
Set rFirstFilteredRow = _
.SpecialCells(xlCellTypeVisible).Columns(2).Cells
rFirstFilteredRow.Copy
Range("G16").Select
ActiveSheet.Paste
End If
End With
End With
End With
End Sub
this helps in getting first column after filter but not the first five
Just add .Resize(5) when setting the width of rFirstFilteredRow to resize the selection to 5 rows high.
Example below (I shortened the code a lot):
Sub Answer()
Dim rFirstFilteredRow As Range
ActiveSheet.Range("$A$1:$D$6").AutoFilter Field:=4, Criteria1:="1"
With Worksheets("Sheet1").Cells(1, 1).CurrentRegion
With .Resize(.Rows.Count - 1, .Rows.Count).Offset(1, 0)
If CBool(Application.Subtotal(103, .Cells)) Then
' Select first 5 columns starting at column 2
Set rFirstFilteredRow = _
.SpecialCells(xlCellTypeVisible).Columns(2).Resize(5)
rFirstFilteredRow.Copy
Range("G16").Select
ActiveSheet.Paste
End If
End With
End With
End Sub
Sub macro2()
Const MAXROWS = 5
Dim ws As Worksheet, rng As Range
Dim i As Long, c As Range
Set ws = ThisWorkbook.Worksheets("Sheet1")
ws.Range("$A$1:$D$6").AutoFilter Field:=4, Criteria1:="1"
With ws.Cells(1, 1).CurrentRegion.Columns(2)
Set rng = .Cells.SpecialCells(xlCellTypeVisible)
End With
i = 0
For Each c In rng.Cells
If i > 0 Then ' skip header
ws.Range("G16").Offset(i - 1) = c.Value2
End If
i = i + 1
If i > MAXROWS Then Exit For
Next
End Sub

Auto filtering to exclude specific month

I have a loop that is deleting rows based on the month within the date
Dim k As Long
For k = FindLastRow(.Sheets(NewSheet)) To 2 Step -1
If Not Month(.Sheets(NewSheet).Cells(k, 1).Value) = NewMonth Then
.Sheets(NewSheet).Rows(k).EntireRow.Delete
End If
Next k
This is very slow and I have code that I've used elsewhere for doing this quicker, this example is based on deleting 0 values:
Dim rngDataBlock As Range
Set rngDataBlock = .Range(.Cells(1, 1), .Cells(8, 8))
With rngDataBlock
.AutoFilter Field:=1, Criteria1:=0
.Offset(1, 0).Resize(.Rows.Count - 1).SpecialCells(xlCellTypeVisible).Rows.Delete
End With
.AutoFilterMode = False
What I can't figure out is how to apply this to my 1st case where I'm deleting based on the month of the date. I tried:
.AutoFilter Field:=1, Criteria1:="<>" & Month(NewMonth)
but this doesn't work, I guess as the filter is actually loking at whole dates rather than months. Can anyone help?
You can use the second criteria and operator parameters to delete using autofilter.
Dim rngDataBlock As Range
Set rngDataBlock = .Range(.Cells(1, 1), .Cells(16, 2))
With rngDataBlock
.AutoFilter Field:=2, Criteria1:=">=" & DateSerial(2021, Month(newmonth), 1), _
Operator:=xlAnd, Criteria2:="<=" & DateSerial(2021, Month(newmonth) + 1, -1)
.Offset(1, 0).Resize(.Rows.Count - 1).SpecialCells(xlCellTypeVisible).Rows.Delete
End With
.AutoFilterMode = False
You can also speed up your original example by unionizing the rows you want to delete and then deleting in one go.
Dim k As Long
Dim delrng As Range
For k = FindLastRow(.Sheets(NewSheet)) To 2 Step -1
If Not Month(.Sheets(NewSheet).Cells(k, 1).Value) = newmonth Then
If delrng Is Nothing Then
Set delrng = .Sheets(NewSheet).Rows(k).EntireRow
Else
Set delrng = Union(delrng, .Sheets(NewSheet).Rows(k).EntireRow)
End If
End If
Next k
delrng.Delete

VBA: Looping a condition through a range that compares values from other columns until the list ends

Public Sub MainTOfomat()
Dim ShippingQty As Range
Dim ReceivedQty As Range
ActiveSheet.Columns("A:P").AutoFit
ActiveSheet.Range("A:P").AutoFilter Field:=13, Criteria1:="No"
ActiveSheet.Range("K:L").AutoFilter Field:=2, Criteria1:="<>"
Set ShippingQty = Range("K2")
Set ReceivedQty = ShippingQty.Offset(0, 1)
ShippingQty.Select
Do Until IsEmpty(ActiveCell)
If ShippingQty.Value = 0 Then
ShippingQty.Offset(0, 5) = "Needs Fulfillment"
ElseIf ShippingQty.Value > ReceivedQty.Value Then
ShippingQty.Offset(0, 5) = "Needs Receipt"
End If
ActiveCell.Offset(1, 0).Select
Loop
End Sub
The code is program is supposed to loop though each row in the column and fill in the statement based on the result of the condition for values in two other columns. The problem is that the loop goes through, but only the first line actually changes, and the auto filter code before the loop gets skipped.
Here is your macro fixed up.
As mentioned before your ShippingQty range and ReceivedQty do not change with the activecell. When moving to the next cell, that is the activecell. The filter range need to be the same. A:P is filtered, when changing to K:L ,field 2 actually becomes column B, so if you want to filter out non-blanks in column L you need the field 12.
Sub YourMacro()
Dim ShippingQty As Range
Dim ReceivedQty As Range
ActiveSheet.Columns("A:P").AutoFit
With ActiveSheet.Range("A:P")
.AutoFilter Field:=13, Criteria1:="No"
.AutoFilter Field:=12, Criteria1:="<>"
End With
Set ShippingQty = Range("K2")
Set ReceivedQty = ShippingQty.Offset(0, 1)
ShippingQty.Select
Do Until IsEmpty(ActiveCell)
If ActiveCell.Rows.Hidden = False Then
If ActiveCell.Value = 0 Then
ActiveCell.Offset(0, 5) = "Needs Fulfillment"
ElseIf ActiveCell.Value > ActiveCell.Offset(, 1).Value Then
ActiveCell.Offset(0, 5) = "Needs Receipt"
End If
End If
ActiveCell.Offset(1, 0).Select
Loop
ActiveSheet.AutoFilterMode = 0
End Sub
You can use this option as well without using selects.
Sub Option1()
Dim rng As Range, c As Range
Dim ws As Worksheet
Set ws = ActiveSheet
Application.ScreenUpdating = 0
With ws
Set rng = .Range("K2:K" & .Cells(.Rows.Count, "K").End(xlUp).Row)
With .Range("A:P")
.AutoFilter Field:=13, Criteria1:="No"
.AutoFilter Field:=12, Criteria1:="<>"
End With
For Each c In rng.SpecialCells(xlCellTypeVisible)
If c = 0 Then c.Offset(, 5) = "Needs Fulfillments"
If c > c.Offset(, 1) Then c.Offset(, 5) = "Needs Receipts"
Next c
.AutoFilterMode = False
End With
End Sub

how to fix Object variable or with block variable not set

Am newbie to VBA and trying to find dupliactes on column A and copy Column A, G and I to another sheet and used below code
Dim wstSource As Worksheet, _
wstOutput As Worksheet
Dim rngMyData As Range, _
helperRng As Range, _
unionRng As Range
Dim i As Long, iOld As Long
Set wstSource = Worksheets("Final Product List")
Set wstOutput = Worksheets("INN Working")
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
With wstSource
Set rngMyData = .Range("A2:A" & .Range("A" & .Rows.Count).End(xlUp).Row)
End With
With rngMyData
Set helperRng = .Offset(, rngMyData.Columns.Count - 1).Resize(, 1)
Set unionRng = .Cells(1000, 1000) 'set a "helper" cell to be used with Union method, to prevent it from failing the first time
End With
With helperRng
.FormulaR1C1 = "=row()" 'mark rows with ad ascending number (its own row number)
.Value = .Value
End With
With rngMyData.Resize(, rngMyData.Columns.Count + 1) 'enclose "helper" column
.Sort key1:=.Columns(1), Order1:=xlAscending, Orientation:=xlTopToBottom, Header:=xlNo ' sort data to have all same columnA values grouped one after another
i = .Rows(1).Row 'start loop from data first row
Do While i < .Rows(.Rows.Count).Row
iOld = i 'set current row as starting row
Do While .Cells(iOld + 1, 1) = .Cells(iOld, 1) 'loop till first cell with different value
iOld = iOld + 1
Loop
If iOld - i > 0 Then Set unionRng = Union(unionRng, .Cells(i, 1).Resize(iOld - i + 1)) 'if more than one cell found with "current" value, then add them to "UnionRng" range
i = iOld + 1
Loop
Intersect(unionRng, rngMyData).EntireRow.Copy Destination:=wstOutput.Cells(1, 1) 'get rid of the "helper" cell via Intersect method
wstOutput.Columns(helperRng.Column).Clear 'delete "Helper" column pasted in wstOutput sheet
.Sort key1:=.Columns(4), Order1:=xlAscending, Orientation:=xlTopToBottom, Header:=xlNo ' sort data in wstSource back
End With
helperRng.Clear 'delete "helper" column, not needed anymore
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
The above code is throwing RunTime error '91'
Object variable or with block variable not set
If iOld - i > 0 Then Set unionRng = Union(unionRng, .Cells(i, 1).Resize(iOld - i + 1)) 'if more than one cell found with "current" value, then add them to "UnionRng" range
i = iOld + 1
End If
The End If was missing and VBA gives a poor message.

Resources