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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With