'Code for working double loop working but very slow : Better way?
I'm fairly new to VBA, and I've written a piece of code that is technicly working, however it takes ages, and I'm fairly sure a more elegant solution is possible.
What I'm trying to do : 1 main Excel database exists (Sheets "Doc1"). Every week a new bunch data is sent (sheetsDoc3), with a few new lines added randomly among the old data (can't change that).
I needed to find a solution to check for each row of the new data if it was already in the main database or not. If it is, nothing happens, else copy/paste at the end of the Main database the row in question.
I used 2 For loop to achieve that result, but since those are 2000 rows long sheets, it almost kills the computer which is a basic notebook.
Below is the existing code, and I'm open to suggestions to better it :
Sub Copypaste()
Dim NotFound As Boolean, LNCHR As Integer, Ligne As Integer, NBVAL As Integer
'NBCL is the number of rows in Doc 3
'NBTR is the number of rows in DOC 1
'NBVAL is the number of value in DOC1
NBCL = WorksheetFunction.CountA(Sheets("Doc3").Range("F:F"))
NBTR = WorksheetFunction.CountA(Sheets("Doc1").Range("I:I"))
NBVAL = WorksheetFunction.CountA(Sheets("Doc1").Range("I:I")) + 1
For LNCHR = 2 To NBCL
For Ligne = 2 To NBTR
NBVAL = WorksheetFunction.CountA(Sheets("Doc1").Range("I:I")) + 1
If Sheets("Doc3").Cells(LNCHR, 1) Like Sheets("Doc1").Cells(Ligne, 1) _
And Sheets("Doc3").Cells(LNCHR, 2) Like Sheets("Doc1").Cells(Ligne, 2) _
And Sheets("Doc3").Cells(LNCHR, 3) Like Sheets("Doc1").Cells(Ligne, 3) _
And Sheets("Doc3").Cells(LNCHR, 4) Like Sheets("Doc1").Cells(Ligne, 4) _
And Sheets("Doc3").Cells(LNCHR, 5) Like Sheets("Doc1").Cells(Ligne, 5) _
And Sheets("Doc3").Cells(LNCHR, 6) Like Sheets("Doc1").Cells(Ligne, 6) _
And Sheets("Doc3").Cells(LNCHR, 7) Like Sheets("Doc1").Cells(Ligne, 7) _
And Sheets("Doc3").Cells(LNCHR, 8) Like Sheets("Doc1").Cells(Ligne, 8) _
And Sheets("Doc3").Cells(LNCHR, 9) Like Sheets("Doc1").Cells(Ligne, 9) _
Then
Else
NotFound = True
End If
Next Ligne
If NotFound = True Then
Sheets("Doc1").Cells(NBVAL, 1) = Sheets("Doc3").Cells(LNCHR, 1)
Sheets("Doc1").Cells(NBVAL, 2) = Sheets("Doc3").Cells(LNCHR, 2)
Sheets("Doc1").Cells(NBVAL, 3) = Sheets("Doc3").Cells(LNCHR, 3)
Sheets("Doc1").Cells(NBVAL, 4) = Sheets("Doc3").Cells(LNCHR, 4)
Sheets("Doc1").Cells(NBVAL, 5) = Sheets("Doc3").Cells(LNCHR, 5)
Sheets("Doc1").Cells(NBVAL, 6) = Sheets("Doc3").Cells(LNCHR, 6)
Sheets("Doc1").Cells(NBVAL, 7) = Sheets("Doc3").Cells(LNCHR, 7)
Sheets("Doc1").Cells(NBVAL, 8) = Sheets("Doc3").Cells(LNCHR, 8)
Sheets("Doc1").Cells(NBVAL, 9) = Sheets("Doc3").Cells(LNCHR, 9)
NBVAL = NBVAL + 1
End If
Next LNCHR
End Sub
Solution 1:[1]
Using RemoveDuplicates
- It is assumed that the data (tables: one row of headers) starts with cell
A1on both worksheets. - It will copy the data from
Doc3toDoc1and remove duplicated rows. - I'm not sure how this will behave with many rows hence your feedback is appreciated.
Option Explicit
Sub copyRemoveDuplicates()
' Constants
Const dName As String = "Doc1"
Const sName As String = "Doc3"
Const Cols As String = "A:I"
' Workbook
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
' Destination
' Destination Columns Range
Dim dws As Worksheet: Set dws = wb.Worksheets(dName)
Dim dcrg As Range: Set dcrg = dws.Columns(Cols)
' Columns Array (For 'RemoveDuplicates').
Dim cUpper As Long: cUpper = dcrg.Columns.Count - 1
Dim ColsArray As Variant: ReDim ColsArray(0 To cUpper)
Dim n As Long
For n = 0 To cUpper
ColsArray(n) = n + 1
Next n
' Destination Last Non-Empty Cell
Dim dlCell As Range
Set dlCell = dcrg.Find("*", , xlFormulas, , xlByRows, xlPrevious)
If dlCell Is Nothing Then Exit Sub
' Destination First Empty Row (Range)
Dim derg As Range: Set derg = dcrg.Rows(dlCell.Row).Offset(1)
' Source
' Source Range
Dim sws As Worksheet: Set sws = wb.Worksheets(sName)
' Use another way if this doesn't work for your data.
Dim srg As Range
With sws.Range("A1").CurrentRegion
Set srg = .Columns(Cols).Resize(.Rows.Count - 1).Offset(1)
End With
' Copy / Remove Duplicates
Application.ScreenUpdating = False
' Copy
srg.Copy derg
' Destination Range (after copying Source Range)
Dim drg As Range
Set drg = dcrg.Resize(dlCell.Row + srg.Rows.Count)
' Remove Duplicates
drg.RemoveDuplicates (ColsArray), xlYes
Application.ScreenUpdating = True
End Sub
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | VBasic2008 |
