Pattrick
asked on
Copying Unique Records to Another Sheet.
I am currently working on a project where I need to compare two sheets ( Sheet1 and Sheet2 ) . Records from Sheet2 to need be compared to sheet1 . Records which do have a match in sheet2 should be copied to new sheet ( Sheet3) . Each Sheet has around 15 columns ( Each Sheets starts from A2 ) , so I wanted to use VBScript Dictionaries mainly to increase the execution time , I want to avoid copy and paste functions . If that was achievable , it could great but I am open to using other options in excl vba to achieve the results .If experts could help in achieving results . It would be greatly helpful.
ASKER
Thanks for your efforts . I have attached a sample with this comment . I request to see the sample and request you to provide give me the best code to execute them in fastest manner .
It should basically compare the two sheets ( sheet1 and sheet2 ) . The unmatched records available in sheet2 ( highlighted for the reference ) should be copied to sheet3 .
Sample.xlsx
It should basically compare the two sheets ( sheet1 and sheet2 ) . The unmatched records available in sheet2 ( highlighted for the reference ) should be copied to sheet3 .
Sample.xlsx
Sub MoveDupes()
Application.ScreenUpdating = False
With ThisWorkbook
FindDupes .Worksheets("Sheet1"), .Worksheets("Sheet2"), .Worksheets("Sheet3")
End With
End Sub
Sub FindDupes(ws1 As Worksheet, ws2 As Worksheet, wsDest As Worksheet)
'Look for records in ws2 that isn't in ws1. Copy those rows to wsDest.
Dim frmla As String
Dim rgCopy As Range, rg1 As Range, rg2 As Range, rgTest As Range
Dim n As Long, nCols As Long, nRows As Long
Set rg2 = ws2.Range("A1").CurrentRegion
nCols = rg2.Columns.Count
nRows = rg2.Rows.Count
Set rg2 = Range(rg2.Cells(2, 1), rg2.Cells(nRows, nCols))
Set rg1 = ws1.UsedRange
Set rg1 = Range(rg1.Cells(2, 1), rg1.Cells(rg1.Rows.Count, nCols))
Set rgTest = rg2.Columns(nCols + 1)
frmla = FormulaBuilder(rg1, rg2)
rgTest.Cells(1).Formula = frmla
rgTest.FillDown
rgTest.Formula = rgTest.Value
Sorter rgTest
n = Application.CountIf(rgTest, "Unique")
If n > 0 Then
Set rgCopy = Range(rg2.Cells(1, 1), rg2.Cells(n, nCols))
wsDest.Cells(2, 1).Resize(n, nCols).Value = rgCopy.Value
End If
rgTest.EntireColumn.Delete
End Sub
Function FormulaBuilder(rg1 As Range, rg2 As Range)
Dim addr1 As String, addr2 As String, frmla As String
Dim i As Long, nCols As Long
nCols = rg2.Columns.Count
frmla = "=IF(COUNTIFS("
addr1 = "'" & rg1.Worksheet.Name & "'!"
For i = 1 To nCols
frmla = frmla & addr1 & rg1.Columns(i).Address(ReferenceStyle:=xlR1C1) & ",""="" &RC" & i & ","
Next
FormulaBuilder = Left(frmla, Len(frmla) - 1) & ")=0,""Unique"","""")"
End Function
Sub Sorter(SortColumn As Range)
'Sort target worksheet by SortColumn in alphabetical order
Dim SortRange As Range
Set SortRange = SortColumn.CurrentRegion
With SortColumn.Worksheet
.Sort.SortFields.Clear
.Sort.SortFields.Add2 Key:=SortColumn, SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
With .Sort
.SetRange SortRange
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
End With
End Sub
SampleQ29143857.xlsm
ASKER
It works perfectly . I have changed selection of the columns and rows as I needed to add labels and buttons . I have attached the sample below . I tried to run the code , the sheets does not any unique records , still I see records are shown in sheet3 and also I don't want to see " Unique ". One more thing , existing data in sheet3 should be deleted , when next operation is performed . Again thanks for your effort .
SampleQ29143857.xlsm
SampleQ29143857.xlsm
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Nailed it .
How is the speed on your real problem?
ASKER
It really does the job but takes literally around 3 to 4 min to execute . It needs to compare around 3000 rows each time. I have one suggestion , if compare just three columns D,E,F ( from sheet 1 ) and B,C,D ( from sheet 2 ) . Based on results we can copy the select the record and copy it to sheet3. Can It increase the execution time.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Yeah . Now it executes within seconds . Thanks .
ASKER
Hi , I face one problem . The code executes in exceptionally well in my Computer . I am using Excel 2019 . When I tried running this function in my colleague computer which is using Excel 2010 . It shows object error during Execution. Is there any problem , when executed in older versions.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thanks . It Works
Instead, consider adding a COUNTIFS formula to Sheet2 that tests whether there is a match on Sheet1. Sort Sheet2 by the results of this formula, then do a single copy & paste to Sheet3. Your question title implied copying values that weren't found on Sheet1 over to Sheet3, but the body of the question suggested the opposite.
The slow part in moving data from one worksheet to another is looping through the rows and moving them one at a time. The sorting operation has been optimized in Excel, and will be very fast. So merely by adding a sort step, you should get a large improvement in speed.
If you don't need to copy over the formatting, it is faster to use the .Value property of the sorted range to transfer just the values. I have been told, but cannot verify from personal experience, that the .Value2 property is even faster than .Value.
Open in new window