VBA code to move columns of only newly pasted rows of data - excel

As shown the mocked-up table above, i'm trying write a macro that copies new data from another workbook (OtherWorkBook), then pastes it below the existing database (in ThisWorkBook).
After that, for only the new rows of data that was pasted, i want to shift the values in columns A, B, C, D one cell to the right. My current code works right until when it is supposed to move the columns, but then an error shows up.
Dim wsCopy As Worksheet
Dim wsDest As Worksheet
Dim CopyLastRow As Long
Dim DestLastRow As Long
Dim ToCopy As Range
Dim ToPaste As Range
Set wsCopy = Workbooks("OtherWorkBook").Worksheets("OtherWorkSheet")
Set wsDest = Workbooks("ThisWorkBook").Worksheets("ThisWorkSheet")
CopyLastRow = wsCopy.Cells(wsCopy.Rows.Count, "B").End(xlUp).Row
DestLastRow = wsDest.Cells(wsDest.Rows.Count, "B").End(xlUp).Offset(1).Row
wsCopy.Range("A2:V" & CopyLastRow).Copy _
wsDest.Range("A" & DestLastRow)
Set ToCopy = wsCopy.Range("A2:V" & CopyLastRow)
Set ToPaste = wsDest.Range("A" & PasteToLastRow)
ToCopy.Copy ToPaste
Set ToPaste = ToPaste.Resize(ToCopy.Rows.Count, ToCopy.Columns.Count)
ToPaste.Columns("A:D").Cut
'The debugger highlights this line of code
ToPaste.Columns("D").Insert Shift:=xlToRight
A macro recorder would not be feasible as the macro is periodically executed to add in new rows of data

You say move the values, so you could use Range.Value rather than Cut/Paste
Sub Demo()
Dim wsCopy As Worksheet
Dim wsDest As Worksheet
Dim CopyLastRow As Long
Dim DestLastRow As Long
Dim ToCopy As Range
Dim ToPaste As Range
Set wsCopy = Workbooks("OtherWorkBook").Worksheets("OtherWorkSheet")
Set wsDest = Workbooks("ThisWorkBook").Worksheets("ThisWorkSheet")
CopyLastRow = wsCopy.Cells(wsCopy.Rows.Count, "B").End(xlUp).Row
DestLastRow = wsDest.Cells(wsDest.Rows.Count, "B").End(xlUp).Offset(1).Row
' deleted redundant Copy/Paste here
Set ToCopy = wsCopy.Range("A2:V" & CopyLastRow)
Set ToPaste = wsDest.Range("A" & PasteToLastRow)
' copy the data
ToCopy.Copy ToPaste
' Resize ToPaste to the pasted rows, 4 columns
Set ToPaste = ToPaste.Resize(ToCopy.Rows.Count, 4)
' Move first 4 columns 1 column to right, leave formatting intact
ToPaste.Offset(, 1).Value = ToPaste.Value
' Clear the first column
ToPaste.Columns(1).ClearContents
End Sub

Try the following:
Columns("D").Cut
Columns("E").Insert Shift:=xlToRight
Columns("C").Cut
Columns("D").Insert Shift:=xlToRight
Columns("B").Cut
Columns("C").Insert Shift:=xlToRight
Columns("A").Cut
Columns("B").Insert Shift:=xlToRight
Unfortunately, don't have my Microsoft Office computer open to check whether this works, but you should be able to get the gist of my suggested solution from the above.

Related

Excel VBA do not copy and paste if cells are empty

I have the following code and would like to change it so that if the cells from A2 to H2 are empty in Sheet1 then the macro doesn't do anything (it's part of a larger sub so I don't want to exit sub completely), however, if there is anything in these cells than the macro is executed.
This is my current code, the problem that I have is that it copies the area under the headers of a table and if the area is empty then it copies the headers.
Sub Macro36()
Dim wsCopy As Worksheet
Dim wsDest As Worksheet
Dim lCopyLastRow As Long
Dim lDestLastRow As Long
'Set variables for copy and destination sheets
Set wsCopy = Worksheets("Sheet1")
Set wsDest = Worksheets("Sheet2")
'1. Find last used row in the copy range based on data in column 1
lCopyLastRow = wsCopy.Cells(wsCopy.Rows.count, "A").End(xlUp).Row
'2 Find first bnak row in the destination range based in column A
lDestLastRow = wsDest.Cells(wsDest.Rows.count, "B").End(xlUp).Offset(1).Row
'3. Copy & Paste Data
wsCopy.Range("A2:H" & lCopyLastRow).Copy wsDest.Range("B" & lDestLastRow)
End Sub
This is my attempt to change the code by adding if function, however, the macro is still executed even though cells A2:H2 in Sheet 1 are empty.
Sub Macro36()
Dim wsCopy As Worksheet
Dim wsDest As Worksheet
Dim lCopyLastRow As Long
Dim lDestLastRow As Long
'Set variables for copy and destination sheets
Set wsCopy = Worksheets("Sheet1")
Set wsDest = Worksheets("Sheet2")
'1. Find last used row in the copy range based on data in column 1
lCopyLastRow = wsCopy.Cells(wsCopy.Rows.count, "A").End(xlUp).Row
'2 Find first bnak row in the destination range based in column A
lDestLastRow = wsDest.Cells(wsDest.Rows.count, "B").End(xlUp).Offset(1).Row
'If function
If IsEmpty(Sheets("Sheet1").Range("A2:H2")) = False Then
'3. Copy & Paste Data
wsCopy.Range("A2:H" & lCopyLastRow).Copy wsDest.Range("B" & lDestLastRow)
Else
Range("A1").Select
End if
End Sub
I was wondering how I could change the code?
Thanks,

Copying Data from one sheet to the last row of another sheet

I'm trying to make something in Excel work, but I cannot.
I have 2 Sheets
Sheet 1 is the "main sheet"
Sheet 2 has a filter.
I want 2 filtered columns to be copied to the main sheet and pasted at the end of the already existing content.
Try this - you will need to update the ranges/sheet names as required.
Sub CopyDataLastRow()
Dim wsCopy As Worksheet
Dim wsDest As Worksheet
Dim CopyLastRow As Long
Dim DestLastRow As Long
'Set Variables
Set wsCopy = Sheets("Sheet1") 'Update your sheet name as required.
Set wsDest = Sheets("Sheet2") 'Update your sheet name as required.
'Find Last Row in Copy Range
CopyLastRow = wsCopy.Cells(wsCopy.Rows.Count, "A").End(xlUp).Row
'Find 1st blank row in Destination Range - Offset 1 row
DestLastRow = wsDest.Cells(wsDest.Rows.Count, "A").End(xlUp).Offset(1).Row
'Copy & Paste Data
wsCopy.Range("A2:B" & CopyLastRow).Copy _
wsDest.Range("A" & DestLastRow)
End Sub

How do i set copy and paste destination?

My goal is to copy and paste from one workbook to another, but I want to have dynamic names - now are statitic and declared in code.
From the code below is visible how it is set now. How can i change my code so these names will be automatic based on the cell (eg.: destination now is "ToThere.xslx" to a value that is in a cell "O2")
Dim wsCopy As Worksheet
Dim wsDest As Worksheet
Dim lCopyLastRow As Long
Dim lDestLastRow As Long
Dim Name as Short
Name = Range("O2").Value
'Set variables for copy and destination sheets
Set wsCopy = Workbooks("FromHere.xlsm").Worksheets("List1")
' I would like this part here to be: Workbooks(Name).Worksheets("List1")
Set wsDest = Workbooks("ToThere.xlsx").Worksheets("List1")
'1. Find last used row in the copy range based on data in column A
lCopyLastRow = wsCopy.Cells(wsCopy.Rows.Count, "A").End(xlUp).Row
'2. Find first blank row in the destination range based on data in
column A
'Offset property moves down 1 row
lDestLastRow = wsDest.Cells(wsDest.Rows.Count,
"A").End(xlUp).Offset(1).Row
'3. Copy & Paste Data
wsCopy.Range("A2:H" & lCopyLastRow).Copy _
wsDest.Range("A" & lDestLastRow)
Here's your example
Sub test()
Dim wsCopy As Worksheet
Dim wsDest As Worksheet
Dim lCopyLastRow As Long
Dim lDestLastRow As Long
Dim Name As Integer
Name = Range("O2").Value
'Set variables for copy and destination sheets
Set wsCopy = Workbooks("FromHere.xlsm").Worksheets("List1")
' I would like this part here to be: Workbooks(Name).Worksheets("List1")
Set wsDest = Workbooks("ToThere.xlsx").Worksheets("List1")
'1. Find last used row in the copy range based on data in column A
lCopyLastRow = wsCopy.Cells(wsCopy.Rows.Count, "A").End(xlUp).Row
'2. Find first blank row in the destination range based on data in
'Column A
'Offset property moves down 1 row
lDestLastRow = wsDest.Cells(wsDest.Rows.Count, "A").End(xlUp).Offset(1).Row
'3. Copy & Paste Data
wsCopy.Range("A2:H" & lCopyLastRow).Copy
ActiveSheet.Paste Destination:=wsDest.Range("A" & lDestLastRow)
End Sub

Increasing range for each iteration

I'm automating an Excel sheet for my work and I'm stuck in a problem.
I'm trying to copy a specific range (A3:D3) and paste it to the ending row of another workbook. I'm trying to use an if statement to filter ranges that have the number 0 in cell B3.
Please help. I'm a complete rookie and I'm just starting out. Sorry if there's a lot of questions.
I've tried to change the range to a cell (i, 2) but it only copies B3 and not the rest (A3:D3).
Edit: forgot to add the s in cells
Edit2: I just need to copy four cells (A3:D3) and increment it on my next iteration so that the copied cell would be (A4:D4)
Sub CopyData()
Dim wsCopy As Worksheet, wsDest As Worksheet
Dim iCopyLastRow As Long, iDestLastRow As Long
Set wsCopy = Workbooks("file1.xlsx").Worksheets("trend")
Set wsDest = Workbooks("file2.xlsx").Worksheets("raw data")
iCopyLastRow = wsCopy.Cells(wsCopy.Rows.Count, "A").End(xlUp).Row
For i = 3 To iCopyLastRow
If wsCopy.Cells(i, 2).Value = 0 Then
Else
wsCopy.range(Cell(i,2), Cell(i,4)).Copy
'wsCopy.Cells(i, 2). Copy ##this copies just one cell
iDestLastRow = wsDest.Cells(wsDest.Rows.Count, "B").End(xlUp).Offset(1).Row
wsDest.range("A" & iDestLastRow).PasteSpecial xlPasteValues
End If
Next i
Error messages:
Run-time error '1004':
Method 'Range' of object '_Worksheet' failed
and the debug highlights wsCopy.range(Cell(i,2), Cell(i,4)).Copy, the statement after else
Try using this code:
Sub CopyData()
Dim wsCopy As Worksheet, wsDest As Worksheet
Dim iCopyLastRow As Long, iDestLastRow As Long
Set wsCopy = Workbooks("file1.xlsx").Worksheets("trend")
Set wsDest = Workbooks("file2.xlsx").Worksheets("raw data")
iCopyLastRow = wsCopy.Cells(wsCopy.Rows.Count, "A").End(xlUp).Row
For i = 3 To iCopyLastRow
If wsCopy.Cells(i, 1).Value <> 0 Then
'A = 1, D = 4
wsCopy.Range(wsCopy.Cells(i, 1), wsCopy.Cells(i, 4)).Copy
iDestLastRow = wsDest.Cells(wsDest.Rows.Count, "B").End(xlUp).Offset(1).Row
wsDest.Range("A" & iDestLastRow).PasteSpecial xlPasteValues
End If
Next i
End Sub
Just make sure that iCopyLastRow and iDestLastRow are the values that you expect.
I hope this helps.
Try below code, it's ready to use in a loop:
Sub CopyAndAppend()
Dim destSheet As Worksheet, srcSheet As Worksheet, lastRow As Long
Set destSheet = Worksheets("Sheet2")
Set srcSheet = Worksheets("Sheet1")
' determine last row in Sheet2
lastRow = destSheet.Cells(destSheet.Rows.Count, 1).End(xlUp).Row
Dim i As Long
i = 3
' copy range A3:D3 and paste it right after last row in Sheet2
srcSheet.Range(srcSheet.Cells(i, 1), srcSheet.Cells(i, 4)).Copy destSheet.Cells(lastRow + 1, 1)
' increment row index
i = i + 1
' do something else
End Sub

Paste data from a different sheet after the last active row of the current sheet

I want to copy the values from A and B columns of the orders tab of the workbook and paste those values to the Duplicate warning settings tab after the last active row.
Public Sub My_Copy_Orders()
Dim Last_Row As Long
Sheets("Duplicate warning Settings").Select
Last_Row = Range("A1").End(xlDown).Offset(1).Row
Sheets("Orders").Columns("A:B").Copy Destination:=Sheets("Duplicate warning Settings").Range("A" & Last_Row)
End Sub
It gives me an error
You're copying entire columns A & B (all 1,048,576 rows by two columns). Your destination is correctly using only the top-left corner as a reference point but since you are below the first row, you no longer have 1,048,576 rows worth of empty cells below the destination. Essentially you're trying to paste empty cells below the bottom of the worksheet.
Simply limit the source of the copy to the worksheet's usedrange.
with Sheets("Orders")
intersect(.usedrange, .Columns("A:B")).Copy _
Destination:=Sheets("Duplicate warning Settings").Range("A" & Last_Row)
end with
Try below sub
Public Sub My_Copy_Orders()
Dim Last_Row As Range
Dim sht1, sht2 As Worksheet
Dim aRow, bRow As Long
Set sht1 = Sheets("Duplicate warning Settings")
Set sht2 = Sheets("Orders")
Set Last_Row = sht1.Cells(Rows.Count, "A").End(xlUp).Offset(1, 0)
aRow = sht2.Range("A1").End(xlDown).Row
bRow = sht2.Range("B1").End(xlDown).Row
If aRow > bRow Then
sht2.Range("A1:B" & aRow).Copy Last_Row
Else
sht2.Range("A1:B" & bRow).Copy Last_Row
End If
End Sub
Basic code using variables.
Dim wsSrc As Worksheet, wsDest As Worksheet, scrlRow As Long
Set wsSrc = ThisWorkbook.Sheets("Orders")
Set wsDest = ThisWorkbook.Sheets("Duplicate warning Settings")
srclRow = wsSrc.Cells(Rows.Count, 1).End(xlUp).Row
Dim cpyRng As Range
Set cpyRng = Range("A1:B" & srclRow)
cpyRng.Copy wsDest.Range("A" & Rows.Count).End(xlUp).Offset(1, 0)

Resources