Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Excel Macro: Copying row values from one worksheet to a specific place in another worksheet, based on criteria

Tags:

I have only been working with macros in Excel for about 4 months now and have essentially been teaching myself by finding existing code and figuring out how it works. I am now a bit stuck.

I have a report in an Excel workbook. I need to copy the data across a number of worksheets (within the same workbook), based on the data that appears in column D. That is to say, I need to copy the entire row where Column D matches certain criteria. The original worksheet contains formulas, but I only want the values to appear when the data is copied.

I have been able to copy the data across, but I have two problems: 1) the formulas are copying across, not just the values 2) the data appears in the new worksheet at cell A2, but I need it to start at cell A5

I am setting this up as a template, as the main report needs to be run and split every month, so the range from which I am copying will not be constant. This is a sample of the code I am currently using:

    Sub RefreshSheets()

    Sheets("ORIGIN").Select
    Dim lr As Long, lr2 As Long, r As Long
    lr = Sheets("ORIGIN").Cells(Rows.Count, "A").End(xlUp).Row
    lr2 = Sheets("DESTINATION").Cells(Rows.Count, "A").End(xlUp).Row

    For r = lr To 2 Step -1
        If Range("D" & r).Value = "movedata" Then
            Rows(r).Copy Destination:=Sheets("DESTINATION").Range("A" & lr2 + 1)
            lr2 = Sheets("DESTINATION").Cells(Rows.Count, "A").End(xlUp).Row
        End If


    Next r

    End Sub

I have tried adding ".PasteSpecial Paste:=xlPasteValues" after ".Range("A" & lr2 + 1)", but I get a compile error (Expected: end of statement). I am sure I have missed something obvious (this is what I get for using code I don't fully understand yet), but nothing I have tried so far has worked.

Any advice would be greatly appreciated.

like image 797
Gevauden Avatar asked Jul 27 '17 00:07

Gevauden


1 Answers

The first version uses a For loop (it can be slow with a lot of rows)

Option Explicit

Public Sub RefreshSheets()
    Dim wsO As Worksheet, wsD As Worksheet, lrO As Long, lrD As Long, r As Long

    Set wsO = ThisWorkbook.Sheets("ORIGIN")
    Set wsD = ThisWorkbook.Sheets("DESTINATION")
    lrO = wsO.Cells(Rows.Count, "A").End(xlUp).Row
    lrD = wsD.Cells(Rows.Count, "A").End(xlUp).Row

    If lrD < 5 Then lrD = 5

    For r = lrO To 2 Step -1
        If wsO.Range("D" & r).Value2 = "movedata" Then
            wsO.Rows(r).Copy
            wsD.Range("A" & lrD + 1).PasteSpecial xlPasteValues
            lrD = lrD + 1
        End If
    Next
End Sub

This version uses an AutoFilter to copy all rows with "movedata" at once:

Public Sub RefreshSheetsFast()
    Dim wsO As Worksheet, wsD As Worksheet, lrD As Long

    Set wsO = ThisWorkbook.Sheets("ORIGIN")
    Set wsD = ThisWorkbook.Sheets("DESTINATION")
    lrD = wsD.Cells(Rows.Count, "A").End(xlUp).Row

    If lrD < 5 Then lrD = 5    'Makes sure the first row on DESTINATION sheet is >=5

    If Not wsO.AutoFilter Is Nothing Then wsO.UsedRange.AutoFilter
    With wsO.UsedRange
        .Columns(4).AutoFilter Field:=1, Criteria1:="movedata"
        .Offset(1).Resize(.Rows.Count - 1).Copy        'Excludes the header (row 1)
    End With
    wsD.Range("A" & lrD + 1).PasteSpecial xlPasteValues

    Application.CutCopyMode = False
    wsO.UsedRange.AutoFilter    'Removes the "movedata" filter
End Sub
like image 161
paul bica Avatar answered Oct 05 '22 00:10

paul bica