Paste into next empty row of another worksheet - excel

The below code, when a user logs an issue into a form, will log in the appropriate issue tab.
Once the team has completed the issue and marks it as "Complete & Verified", I want to move that issue (row) out of the current tab into the "5. Complete & Verified" tab.
The issue is, say there are 9 rows of data in the current tab, the macro is pasting the row into the 9th row of the "5. Complete & Verified" tab.
I am trying to paste one after the other starting in B2. I am also trying to Paste the tab name into column 1 (column A) as an identifier.
Sub Complete()
ActiveSheet.Activate
Dim objWS As Worksheet
Set objWS = ActiveSheet
Dim intLastRowSrc As Long
intLastRowSrc = ActiveSheet.Cells.Find("*", searchorder:=xlByRows, searchdirection:=xlPrevious).Row
ActiveSheet.Activate
Dim intLastRowSDes As Long
intLastRowSDes = ActiveSheet.Cells.Find("*", searchorder:=xlByRows, searchdirection:=xlPrevious).Row + 1
Dim r As Long
For r = 2 To intLastRowSrc
If objWS.Cells(r, "R") = "Complete & Verified" Then
Sheets("5. Complete & Verified").Range("B" & intLastRowSDes & ":T" & intLastRowSDes).Value = objWS.Range("A" & r & ":S" & r).Value
objWS.Rows(r).Delete
Sheets("5. Complete & Verified").Cells(intLastRowSDes, 1) = ws1.Name
intLastRowSrc = intLastRowSrc - 1
intLastRowSDes = intLastRowSDes + 1 'Issue - I need it to paste into next row with now data in 5. tab
End If
Next
Exit Sub

There are a few things that need adjusted to work as (I think) you want things to work.
Firstly, set references to the source and destination worksheets and use them directly rather than naming each time.
Secondly you don't need to Activate any of the worksheets, so let's remove those
Thirdly if you are looking to delete rows within a for loop, always start at the bottom of your data range and move up- otherwise when you delete row 21 and 22 moves up, your loop will completely ignore the fact that 22 moved up without getting checked and you will miss rows
Fourthly, just grab the destination row from inside the loop rather than try to increment the count
Fifthly, you are setting column 1 on your destination sheet to ws1.name but you never define it, so I've replaced that with a reference to the source worksheet name.
If any of this doesn't make sense, drop a comment below and I'll try to explain better.
Sub Complete()
Dim sourceWS As Worksheet
Set sourceWS = ActiveSheet
Dim destWS As Worksheet
Set destWS = ThisWorkbook.Worksheets("5. Complete & Verified")
Dim intLastRowSrc As Long
intLastRowSrc = sourceWS.Cells.Find("*", searchorder:=xlByRows, searchdirection:=xlPrevious).Row
Dim intLastRowSDes As Long
Dim r As Long
For r = intLastRowSrc to 2 Step -1
If sourceWS.Cells(r, "R") = "Complete & Verified" Then
intLastRowSDes = destWS.Cells.Find("*", searchorder:=xlByRows, searchdirection:=xlPrevious).Row + 1
destWS.Range("B" & intLastRowSDes & ":T" & intLastRowSDes).Value = sourceWS.Range("A" & r & ":S" & r).Value
sourceWS.Rows(r).Delete
destWS.Cells(intLastRowSDes, 1) = sourceWS.Name
End If
Next
Exit Sub

Michael,
Dave posted his answer while I was working on it. While it will work, if I'm not mistaken, and that may well be the case, the items will be copied in reverse order to the new destination sheet. If order is important you may what to try using a Do/Loop as follows:
Option Explicit
Sub Complete()
Dim lRow As Long
Dim shtWS As Worksheet
Dim shtDest As Worksheet
Dim lLastRowSDes As Long
'*** Don't use ActiveSheet rather specify the name
'*** If called from more than one sheet pass as parameter.
Set shtWS = WorkSheets("your sheet name here")
set shtDst = Worksheets("5.Complete & Verified")
lLastRowSDes = ActiveSheet.Cells.Find("*", _
searchorder:=xlByRows, _
searchdirection:=xlPrevious).Row + 1
lRow = 2 'Set Starting Row
Do
If shtWS.Cells(lRow, "R") = "Complete & Verified" Then
shtWS.Range("B" & lRow & ":T" & lRow).Copy
shtDst.Range("B" & lLastRowSDes).Paste
shtWS.Rows(lRow).Delete
'*** Note we don't increment counter as next row moves up to current lRow position!
shtDst.Cells(lLastRowSDes, 1) = shtWS.Name
lLastRowSDes = lLastRowSDes + 1
Else
lRow = lRow + 1 'Increment Row Counter
End If
Loop Until (shtWS.Cells(lRow,"B").Value = "")
You'll notice I used Copy/Paste as I've never seen the syntax of assigning one range to another like that, very neat! So you could just replace the copy/paste lines with that one.
FYI: code not tested!
HTH

Related

How to fix 'Run-time error '1004' PasteSpecial

I have a file (called original) that has partially information for each row. Each row has a file name column (from where information is to be captured from).
For each row I'd like to open up the file in the file name column, and grab information from certain rows.
In the file it is only one column, with rows "Supplier Number : _____", the location of this row is variable, so I'd like to iterate through each row in the file to copy this cell value and paste it into the original file in the corresponding row.
This is what I have so far:
Const FOLDER_PATH = "C:\Users\[user]\Downloads\"
Sub iterateThroughAll()
ScreenUpdating = False
Dim wks As Worksheet
Set wks = ActiveSheet
Dim source As String
Dim target As String
Dim update As String
Dim rowT As Integer
rowT = 2
rowTT = 1
Dim rowRange As Range
Dim colRange As Range
Dim rowRangeT As Range
Dim LastCol As Long
Dim LastRow As Long
Dim LastRowT As Long
LastRow = wks.Cells(wks.Rows.Count, "A").End(xlUp).Row
Set rowRange = wks.Range("A2:A" & LastRow)
'Loop through each row
For Each rrow In rowRange
source = FOLDER_PATH & wks.Cells(i, 18).Value 'the name of the file we want to grab info from in this Column, always populated
'if the cell is empty, search through the file for "Supplier Number : "
If IsEmpty(wks.Cells(rowT, 19)) Then
Set wb = Workbooks.Open(source)
wb.Activate
LastRowT = Cells.Find("*", searchorder:=xlByRows, searchdirection:=xlPrevious).Row
Set rowRangeT = wks.Range("A1:A" & LastRowT)
For Each i In rowRangeT
If InStr(i.Cells.Offset(rowTT), "Supplier") > 0 Then
Range("A" & rowTT).Select
Selection.Copy
Windows("Get Supplier Number.xlsm").Activate
Range("A" & rowT).Select
wks.Paste
Else
rowTT = rowTT + 1
End If
Next i
wb.Close
Next rrow
ScreenUpdating = True
End Sub
I get the pastespecial error 1004.
What is expected is that for each row in "Get Supplier Number.xlsm", the row's A column is updated with the information
Thank you for helping!
First of all you should get rid of Activate and Select methods. You don't have to use them and they give nothing to your code. Using them is not a good approach.
To avoid them you should use specific references. Which you are doing so, until a specific point. Inside the for loop, after setting the wb, replace everything with the following:
With wb.Worksheets(1)
LastRowT = .Cells.Find("*", searchorder:=xlByRows, searchdirection:=xlPrevious).Row
Set rowRangeT = .Range("A1:A" & LastRowT)
For Each i In rowRangeT
If InStr(i.Cells.Offset(rowTT), "Supplier") > 0 Then
.Range("A" & rowTT).Copy wks.Range("A" & rowT)
Else
rowTT = rowTT + 1
End If
Next i
wb.Close
End With
I think this should do the job for you.
PS: If you need just the value of the cell in the opened workbook, then you could replace the Copy line with a simple equality:
wks.Range("A" & rowT) = .Range("A" & rowTT)

Copy row of data based on criteria AND "label" that copied data in last column

I have working code that checks for a criteria in each row, and if met, copies that whole row of data over to a different workbook. But! I need to be able to add text to the last column of the copied data (Column S) that essentially labels what criteria was met that made the code copy it over because I will soon be expanding to check for multiple different criteria.
So for every row that meets the criteria and gets copied, I want to add "Criteria1" next to it in column S in the new workbook (it will always be column S that will be the first available column).
I have mangled this code together through inheritance and all of your help, so I don't really even know where to begin.
Private Sub Workbook_AfterSave(ByVal Success As Boolean)
Dim CoderBook As Workbook
Dim Referrals As Worksheet
Dim Review As Workbook
Dim Crit As Worksheet
Dim LastRow As Long
Dim NextRow As Long
Dim i As Long
Set CoderBook = Workbooks.Open("Coder Referrals.xlsx")
Set Referrals = CoderBook.Sheets("Sheet1")
Set Review = ThisWorkbook
Set Crit = Review.Sheets("Criteria")
'Search code
LastRow = Crit.Cells.Find(What:="*", After:=[A1], SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
Application.ScreenUpdating = False
'Loop search code
For i = 2 To LastRow
'Specialized Criteria1 Check
If Crit.Range("F" & i) <> Crit.Range("G" & i) Or _
Crit.Range("I" & i) <> Crit.Range("J" & i) Then
'If meets Criteria1 check, then copy appropriate rows to CoderBook Referrals sheet
Referrals.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).EntireRow.Value = Crit.Rows(i).Value
End If
Next i
'End loop code
CoderBook.Close SaveChanges:=True
Application.ScreenUpdating = True
End Sub
Split the or into two statements:
For i = 2 To LastRow
j = Referrals.Cells(Rows.Count, 1).End(xlUp).row + 1
'Specialized Criteria1 Check
If Crit.Range("F" & i) <> Crit.Range("G" & i) Then
'If meets Criteria1 check, then copy appropriate rows to CoderBook Referrals sheet
Referrals.Rows(j).EntireRow.Value = Crit.Rows(i).Value
Referrals.Range("S" & j).Value = "Criteria1"
End If
If Crit.Range("I" & i) <> Crit.Range("J" & i) Then
Referrals.Rows(j).EntireRow.Value = Crit.Rows(i).Value
if Referrals.Range("S" & j).value = vbNullString then
Referrals.Range("S" & j).Value = "Criteria2"
Else
Referrals.Range("S" & j).Value = Referrals.Range("S" & j).Value & ", " & "Criteria2"
End if
Next i

Fastest way to transfer large amounts of data between worksheets

I currently have 2 worksheets, for simplicity sake let's call them Sheet1 and Sheet2 in the explanations. In Sheet1 I have around 50k rows of data. I am trying to go through Sheet1 and find unique occurrences in the data set to then transfer across to Sheet2.
Below are the methods I have used so far and their rough estimates for time taken.
Method A - Iterate through Sheet1 with a For loop with the conditional check programmed in VBA, if condition is met - transfer a range of 8 cells on that row to Sheet2. This method completes 60% in 60 minutes.
Method B - I thought that removing the condition check in VBA could speed things up so I created a new column in Sheet1 with an IF statement that returns "Y" if the condition is met. I then iterate through this column and if there is a "Y" - transfer the occurrence across to Sheet2. This weirdly takes longer than method A, namely 50% in 60 mins.
Sub NewTTS()
Dim lRow1 As Long, lRow2 As Long
Dim i As Long
With wsOTS
lRow1 = .Range("E" & .Rows.Count).End(xlUp).Row
For i = lRow1 To 2 Step -1
If .Range("P" & i).Text = "Y" Then
lRow2 = wsTTS.Range("E" & wsTTS.Rows.Count).End(xlUp).Row + 1
wsTTS.Range("E" & lRow2, "AA" & lRow2).Value = .Range("E" & i, "AA" & i).Value
End If
Next i
End With
End Sub
Method C - I then read on another post that the .Find() method is quicker than using For loop method. As such I used a .Find() in the column that returns the "Y" and then transfer event across to Sheet2. This is the fastest method so far but still only completes 75% in 60 mins.
Sub SearchOTS()
Application.ScreenUpdating = False
Dim startNumber As Long
Dim lRow1 As Long, lRow2 As Long
Dim i As Long
Dim startTime As Double
startTime = Time
lRow1 = wsOTS.Range("E" & wsOTS.Rows.Count).End(xlUp).Row
Columns("P:P").Select
Selection.Find(What:="Y", After:=ActiveCell, LookIn:=xlValues, LookAt:= _
xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False _
, SearchFormat:=False).Activate
startNumber = ActiveCell.Row
lRow2 = wsTTS.Range("E" & wsTTS.Rows.Count).End(xlUp).Row + 1
wsTTS.Range("E" & lRow2, "AA" & lRow2).Value = wsOTS.Range("E" & ActiveCell.Row, "AA" & ActiveCell.Row).Value
For i = 1 To lRow1
Selection.FindNext(After:=ActiveCell).Activate
If ActiveCell.Row = startNumber Then GoTo ProcessComplete
lRow2 = wsTTS.Range("E" & wsTTS.Rows.Count).End(xlUp).Row + 1
wsTTS.Range("E" & lRow2, "AA" & lRow2).Value = wsOTS.Range("E" & ActiveCell.Row, "AA" & ActiveCell.Row).Value
wsOTS.Range("B18").Value = i / lRow1
Next i
ProcessComplete:
Application.ScreenUpdating = True
MsgBox "Complete! Time taken: " & Format(Time - startTime, "hh:mm:ss")
End Sub
Method D - I then read another post saying that the fastest way would be to build an array and then loop through the array. Instead of an array I used a collection (dynamic), and I iterate through Sheet1 and store the row numbers for the occurences. I then loop through the collection and transfer the events across to Sheet2. This method returns 50% in 60 mins.
Sub PleaseWork()
Dim i As Long
Dim lRow1 As Long, lRow2 As Long
Dim myCol As New Collection
lRow1 = wsOTS.Range("E" & wsOTS.Rows.Count).End(xlUp).Row
'build collection of row numbers
For i = 1 To lRow1
If wsOTS.Range("P" & i).Text = "Y" Then
myCol.Add i
End If
Next i
'now go through collection and build TTS
For i = 1 To myCol.Count
lRow2 = wsTTS.Range("E" & wsTTS.Rows.Count).End(xlUp).Row + 1
wsTTS.Range("E" & lRow2, "N" & lRow2).Value = wsOTS.Range("E" & myCol(i), "N" & myCol(i)).Value
Next i
Set myCol = New Collection
End Sub
I am trying to find the fastest way to complete this task but all the methods I have tried are yielding greater than an hour to complete.
Is there anything I am missing here? Is there a faster method?
Accessing a range is abysmally slow, and the cause for your long runtime. If you already know that you are going to read 1000 rows, do not read them one at a time. Instead, pull the whole range in a buffer, then work only with that buffer. Same goes for writing. If you do not know in advance how much you will write, make chunks of e.g. 100 rows length.
(Untested) example:
Sub PleaseWork()
Dim i As Long, j as long
Dim lRow1 As Long, lRow2 As Long
Dim myCol As New Collection
Dim column_p() as variant
dim inbuffer() as Variant
dim outbuffer() as variant
lRow1 = wsOTS.Range("E" & wsOTS.Rows.Count).End(xlUp).Row
' Get whole Column P at once
column_p = wsOTS.Range("P1").Resize(lRow1, 1).Value
'build collection of row numbers
For i = 1 To lRow1
If column_p(i, 1) = "Y" Then
myCol.Add i
End If
Next i
'now go through collection and build TTS
lRow2 = myCol.Count 'Number of required rows
' get whole input range
inbuffer = wsOTS.Range("E1").Resize(lRow1, 10).Value
' prepare output
ReDim outbuffer(1 to lRow2, 1 to 10)
For i = 1 To myCol.Count
' write into outbuffer
for j = 1 to 10
outbuffer(i, j) = inbuffer(myCol(i), j)
Next
Next i
' Set whole output at once
wsTTS.Range("E1").Resize(lRow2, 10).Value = outbuffer
Set myCol = New Collection
End Sub
did you consider using Remove Duplicates.
Steps:
Copy entire data to a new sheet
On Data tab, choose Remove duplicates
You can record this as a macro as well.

Transferring Cell Values Between Worksheets | Str Looper

Intended Result
If a row in a table contains any of the listed strings in column L on Sheet1, Then copy the entire row from Sheet1 and paste the row into a duplicate table on Sheet2 (which would be blank at the beginning).
(UNINTERESTED, UNRELATED, UNDECIDED, etc...)
Then delete the entire row that was transferred from sheet 1.
After macro runs, the new transfers should not reset table on Sheet2, rather add rows on the pre-existing lines. This document would be utilized over months.
Variables
Sheet1 is named Pipeline_Input
Sheet2 is named Closed_Sheet
Sheet1 table is named tblData
Sheet2 table is named tblClosed
Images
Image 1 is the code with error
Image 2 is Sheet 1 with some picture explanation
Image 3 is Sheet 2 with some picture explanation
Current Result
Run-time error '1004':
Application-defined or object-defined error
Sub closedsheet()
Application.ScreenUpdating = False
Dim Pipeline_input As Worksheet 'where is the data copied from
Dim Closed_Sheet As Worksheet 'where is the data pasted to
Dim strPhase() As String
Dim i As Integer
Dim intPhaseMax As Integer
Dim lngLstRow As Long
Dim rngCell As Range
Dim finalrow As Integer
Dim lr As Long 'row counter
Dim Looper As Integer
intPhaseMax = 6
ReDim strPhase(1 To intPhaseMax)
strPhase(1) = "LOST"
strPhase(2) = "BAD"
strPhase(3) = "UNINTERESTED"
strPhase(4) = "UNRELATED"
strPhase(5) = "UNDECIDED"
strPhase(6) = "BUDGET"
'set variables
Set Pipeline_input = Sheet1
Set Closed_Sheet = Sheet2
lr = Range("A" & Rows.Count).End(xlUp).Row
For Looper = LBound(strPhase) To UBound(strPhase)
For i = lr To 6 Step -1
Next
If Not Sheet1.Range("L9:L300" & lngLstRow).Find(strPhase(Looper), lookat:=xlWhole) Is Nothing Then
Range(Cells(i, 1), Cells(i, 20)).Copy
Sheet2.Range("A" & Rows.Count).End(3)(2).PasteSpecial xlPasteValues
Range(Cells(i, 1), Cells(i, 20)).Delete
End If
Next
Sheet2.Select
Sheet2.columns.AutoFit
Application.CutCopyMode = False
Application.ScreenUpdating = True
End Sub
Okay, there were a plethora of issues with the code you posted, but I decided to help you out here - Notice a few things - There's no copying and pasting here - we're just transferring data.
Secondly, use easy to understand variables. lr and lngLastRow can't be distinguished from one another, so classify them by which worksheet you're getting that value from.
We create an array in one fell swoop here - Just declare a variant and place our values in. ARRAYS (TYPICALLY) START AT ZERO, NOT ONE, so our loop starts at 0 :). Again, this is what's known as best practice...
I swapped out Looper for j. Again, keep. it. simple!
EDIT: I tested this code out on a simulated workbook and it worked fine - should run into no issues for you either.
EDIT2: Also, always use Option Explicit!
Option Explicit
Sub closedsheet()
Application.ScreenUpdating = False
Dim Pipeline_Input As Worksheet 'source sheet
Dim Closed_Sheet As Worksheet 'destination sheet
Dim i As Long, j As Long, CSlastrow As Long, PIlastrow As Long
Dim strPhase As Variant
'Here we create our array
strPhase = Array("LOST", "BAD", "UNINTERESTED", "UNRELATED", "UNDECIDED", "BUDGET")
'Assign worksheets
Set Pipeline_Input = ActiveWorkbook.Worksheets("Pipeline_Input")
Set Closed_Sheet = ActiveWorkbook.Worksheets("Closed_Sheet")
PIlastrow = Pipeline_Input.Range("A" & Rows.Count).End(xlUp).Row
For j = 0 To UBound(strPhase)
For i = PIlastrow To 6 Step -1
If Pipeline_Input.Range("L" & i).Value = strPhase(j) Then
'Refresh lastrow value
CSlastrow = Closed_Sheet.Range("A" & Rows.Count).End(xlUp).Row
'Transfer data
Closed_Sheet.Range("A" & CSlastrow + 1 & ":S" & CSlastrow + 1).Value = _
Pipeline_Input.Range("A" & i & ":S" & i).Value
'Delete the line
Pipeline_Input.Range("A" & i & ":S" & i).EntireRow.Delete
End If
Next i
Next j
Closed_Sheet.Select
Closed_Sheet.Columns.AutoFit
Application.ScreenUpdating = True
End Sub

How can i prevent duplicates from being created

I've created an excel spreadsheet which will be tracking faulty assets that have been sent back from our external agents, I have two tabs that will be the main focus of this spreadsheet. Tab 1 will be the tested assets tab and Tab 2 will be awaiting testing. So once any asset that gets sent back will be manually logged on the awaiting testing tab, but once it's been tested I've created a vba code that will export anything that's been marked with a "Y" meaning it's been tested on to the Tested assets tab.
But the problem i have here is that one asset can come in to testing and be sent back out to the field to our engineers more than once, so if it comes back to be tested again and gets logged on the awaiting testing and once it's been tested and exported to the tested assets tab it duplicates what already is on the tested asset tab and i get two cells with the same data. Is there anyway i can put in another line of code that will prompt me on a duplicate before it exports it. See code below;
Sub automove()
Dim SerialNo As String
Dim AwaitTestLastRow, PasteToRow As Long
Sheets("Awaiting Testing").Select
AwaitTestLastRow = Range("a1000000").End(xlUp).Row
For x = AwaitTestLastRow To 3 Step -1
If Range("c" & x).Value = "Y" Or Range("c" & x).Value = "y" Then
SerialNo = Range("a" & x).Value
Rows(x).Delete
Sheets("Tested Assets").Select
Range("a1000000").End(xlUp).Offset(1, 0).Value = SerialNo
Range("e1000000").End(xlUp).Offset(1, 0).Value = SerialNo
PasteToRow = Range("a1000000").End(xlUp).Row
Range("b3:d3").Select
Selection.Copy
Range("b" & PasteToRow & ":d" & PasteToRow).Select
ActiveSheet.Paste
Range("f3").Select
Selection.Copy
Range("f" & PasteToRow & ":f" & PasteToRow).Select
ActiveSheet.Paste
Sheets("Awaiting Testing").Select
End If
Next x
There are many different ways of checking for duplicates. In the code below, I've used a .Find function on the "Tested Assets" worksheet. If the return object is Nothing then it's a new item, if it's a Range then we know the address of your duplicate. It's not necessarily the quickest way (a Collection might be quicker, for example), but the .Find function is still pretty snappy and as, you'll see in my next comment, I wanted to have the range address.
I've put some code below that instead of prompting you for a duplicate, records the frequency with which the same item is returning to the test lab - might be of some use to you for tracking a repeat offender. However, if you don't want that then delete the 4 lines and replace with MsgBox asset(1, 1) & " is a duplicate."
I've adjusted your code slightly to speed it up, and watch out for declaring two variables on the same line as each variable must have its own declaration type. In your line: Dim AwaitTestLastRow, PasteToRow As Long, the AwaitTestLastRow variable isn't a Long (it's actually not typed ie a Variant).
Sub AutoMove_v2()
Dim awaitingRange As Range
Dim testedRange As Range
Dim flaggedRange As Range
Dim newRow As Range
Dim dupCell As Range
Dim testFlag As String
Dim asset As Variant
Dim cell As Range
Dim frq As Long
'Initialise the parameters
With ThisWorkbook.Worksheets("Awaiting Testing")
Set awaitingRange = .Range("A3", _
.Cells(.Rows.Count, "A").End(xlUp))
End With
With ThisWorkbook.Worksheets("Tested Assets")
Set testedRange = .Range("A1", _
.Cells(.Rows.Count, "A").End(xlUp))
End With
'Loop through the awaiting sheet to find assets for transferral
For Each cell In awaitingRange
testFlag = UCase(cell.Offset(, 2).value)
If testFlag = "Y" Then
If flaggedRange Is Nothing Then
Set flaggedRange = cell
Else
Set flaggedRange = Union(flaggedRange, cell)
End If
End If
Next
'Identify duplicates or transfer new assets
For Each cell In flaggedRange
asset = cell.Resize(, 4).value
Set dupCell = testedRange.Cells.Find(What:=asset(1, 1), _
After:=testedRange.Cells(1), _
LookIn:=xlFormulas, _
LookAt:=xlWhole, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=True)
If dupCell Is Nothing Then
'It's a new entry so transfer the values
Set newRow = testedRange.Cells(testedRange.Cells.Count).Offset(1)
Set testedRange = Union(testedRange, newRow)
newRow.Resize(, 4) = asset
Else
'It's a duplicate so increment the frequency counter
frq = dupCell.Offset(, 5).value
If frq = 0 Then frq = 1
frq = frq + 1
dupCell.Offset(, 5) = frq
End If
Next
'Delete the transferred rows
flaggedRange.EntireRow.Delete
End Sub

Resources