Search code examples
excelvbacopy-paste

Search for a match, copy entire row, and paste to corresponding


Col B on "Sheet2" contains 370 rows of data. Starting with "Sheet2" Cell B1, I want to search for a matching value in Col B on "Sheet1" (it could be located anywhere in the first 300 rows of "Sheet1" Col B). If a match is found, copy the entire row from "Sheet1" and paste to Row1 on "Sheet2". Then, move to "Sheet2" Cell B2 and repeat the search, this time pasting the entire row from "Sheet1" to Row2 on "Sheet2". Continue moving thru the entire column of data on "Sheet2", searching for each cell's value on "Sheet1". If a search doesn't return a match, then do not paste anything to that row on "Sheet2" and just proceed to search for the next cell on "Sheet2". (For example, if Sheet1 Col B doesn't contain a match for Sheet2 Cell B3, then nothing gets pasted in Sheet2 Row3.)

I have found the following example, which starts to help me, but it specifies the search value and doesn't loop thru the entire column of values like I am attempting to do.

Sub CopyYes()
    Dim c As Range
    Dim j As Integer
    Dim Source As Worksheet
    Dim Target As Worksheet

    ' Change worksheet designations as needed
    Set Source = ActiveWorkbook.Worksheets("Sheet1")
    Set Target = ActiveWorkbook.Worksheets("Sheet2")

    J = 1     ' Start copying to row 1 in target sheet
    For Each c In Source.Range("E1:E1000")   ' Do 1000 rows
        If c = "yes" Then
           Source.Rows(c.Row).Copy Target.Rows(j)
           j = j + 1
        End If
    Next c
End Sub

Solution

  • This should do the trick, and do it fast:

    Option Explicit
    Sub CopyYes()
    
        'You need Microsoft Scripting Runtime library under Tools-References for this
        Dim arrPaste As Variant: arrPaste = Sheet2.UsedRange.Value
        Dim arrCopy As Variant: arrCopy = Sheet1.UsedRange.Value
        Dim MyMatches As New Dictionary: Set MyMatches = CreateDictionary(arrCopy)
        Dim i As Long
        For i = 1 To UBound(arrPaste)
            If arrPaste(i, 2) = vbNullString Then Exit For
            If MyMatches.Exists(arrPaste(i, 2)) Then PasteData arrPaste, arrCopy, i, MyMatches(arrPaste(i, 2))
        Next i
        Sheet2.UsedRange.Value = arrPaste
        Erase arrCopy
        Erase arrPaste
    
    End Sub
    Private Function CreateDictionary(arr As Variant) As Dictionary
    
        Dim i As Long
        Set CreateDictionary = New Dictionary
        For i = 1 To 300
            CreateDictionary.Add arr(i, 2), i
        Next i
    
    End Function
    Private Sub PasteData(arrPaste As Variant, arrCopy As Variant, i As Long, MyMatch As Long)
    
        Dim j As Long
        For j = 1 To UBound(arrCopy, 2)
            If arrCopy(MyMatch, j) = vbNullString Then Exit For
            arrPaste(i, j) = arrCopy(MyMatch, j)
        Next j
    
    End Sub