Can't get copy to find last row of data - excel

I had previous question on how to find the last row of data for a formula in Column A based on data in Column C. And ya'll helped me figured that portion out!
Now I'm taking it a step further, and looping through more worksheets.
The data in Column C is Copying/Pasting correctly to the next available row.
However, the formula is pasting over the first set of data in Column A, versus finding the last row.
Better yet.. is there a way to make this formula a 1 liner?? I can't seem to get that to work either.
`Dim Mkts As Worksheet
Dim ws As Worksheet
'Destination Worksheet
Set Mkts = Workbooks("Nielsen SC Template.xlsm").Worksheets("Markets")
'Copy 4Wk Data
Workbooks.Open "C:\Users\cday\OneDrive - udfinc.com\Nielsen Scorecard\4Wk Data.xlsx"
Dim Wb4 As Workbook
Set Wb4 = Workbooks("4Wk Data.xlsx")
For Each ws In Wb4.Worksheets
With ws
If .Index <> 1 Then
'Find last used row in the copy range based on data in Column A
Dim CopyLastRow4 As Long
CopyLastRow4 = .Cells(.Rows.Count, 1).End(xlUp).Row
'Find first blank row in the destination range based on data in Column C, Offset 1 Row
Dim DestLastRowC As Long
DestLastRowC = Mkts.Cells(Mkts.Rows.Count, "C").End(xlUp).Offset(1).Row
'Find last used row in the destination range based on data in Column C
Dim LastRowColumnC As Long
LastRowColumnC = .Range("C" & .Rows.Count).End(xlUp).Row
If .Index = 2 Then
'Copy and Paste Data into C3
.Range("A4:V" & CopyLastRow4).Copy Mkts.Range("C" & DestLastRowC)
'Add Dates to Column A
Dim FR As Range 'first row
Dim LR As Range 'last row
Set FR = Mkts.Range("A3")
Set LR = Mkts.Range("A" & LastRowColumnC - 1)
Range(FR, LR).Formula = "=Mid('[4Wk Data.xlsx]Report1'!$A$1, 9, 28)"
'Add Markets to Column B
Set FR = Mkts.Range("B3")
Set LR = Mkts.Range("B" & LastRowColumnC - 1)
Range(FR, LR).Formula = "=Mid('[4Wk Data.xlsx]Report1'!$A$1, 48, 13)"
End If
If .Index = 3 Then
'Copy and Paste Data into C3
.Range("A4:V" & CopyLastRow4).Copy Mkts.Range("C" & DestLastRowC)
**'Add Dates to Column A
Set FR = Mkts.Range("A" & DestLastRowC)
Set LR = Mkts.Range("A" & LastRowColumnC)
Range(FR, LR).Formula = "=Mid('[4Wk Data.xlsx]Report2'!$A$1, 9, 28)"
'Add Markets to Column B
'Set FR = Mkts.Range("B" & DestLastRowC)
'Set LR = Mkts.Range("B" & LastRowColumnC)
'Range(FR, LR).Formula = "=Mid('[4Wk Data.xlsx]Report2'!$A$1, 48, 15)"**
End If
End If
End With
Next ws

Try something like this:
Sub Test()
Dim Mkts As Worksheet, ValA1
Dim ws As Worksheet, Wb4 As Workbook, rngCopy As Range, rngDest As Range
'Destination Worksheet
Set Mkts = Workbooks("Nielsen SC Template.xlsm").Worksheets("Markets") 'ThisWorkbook ?
'Copy 4Wk Data
Set Wb4 = Workbooks.Open("C:\Users\cday\OneDrive - udfinc.com\Nielsen Scorecard\4Wk Data.xlsx")
For Each ws In Wb4.Worksheets
With ws
If .Index = 2 Or .Index = 3 Then
'range of data to be copied from ws: A4 to V[last row in colA]
Set rngCopy = .Range("A4:V" & .Cells(.Rows.Count, 1).End(xlUp).Row)
'destination for pasting in ColC
Set rngDest = Mkts.Cells(Mkts.Rows.Count, "C").End(xlUp).Offset(1)
rngCopy.Copy rngDest 'copy the data
'grab the value from A1 on Report1
ValA1 = .Range("A1").Value '<<<<<<
'fill a range starting from rngDest two columns to the
' left and the same size (# of rows) as the copied range
' using part of the value from A1
rngDest.Offset(0, -2).Resize(rngCopy.Rows.Count).Value = Mid(ValA1, 9, 28) 'ColA
'similar process for a column one to the left from rngDest
rngDest.Offset(0, -1).Resize(rngCopy.Rows.Count).Value = Mid(ValA1, 48, 13) 'ColB
End If
End With
Next ws
End Sub

Related

Problems with copying to the next empty row

I am trying to copy data from wsSource to wsDestination if the data doesn't exist in wsDestination. The data copies if the data doesn't exist but it copies to the last row rather than the next empty row.
I have attached screen shots to illustrate this
Screenshot showing data from wsDestination before any copy is done
Screenshot showing data in wsSource
Screenshot showing data in wsDestination after data has been copied
Sub test()
Dim wsSource As Worksheet, wsDestination As Worksheet
Dim LastRowSource As Long, LastRowDestination As Long
Dim i As Long, y As Long
Dim Value_1 As String, Value_2 As String, Value_3 As String
Dim ValueExists As Boolean
With ThisWorkbook
Set wsSource = .Worksheets("Data Source")
Set wsDestination = .Worksheets("Data Destination")
End With
With wsSource
'Find the last row of Column C, wsSource
LastRowSource = .Cells(.Rows.Count, "C").End(xlUp).Row
'Loop Column C, wsSource
For i = 13 To LastRowSource
'Data to be tested if it doesn't exist in wsDestination
Value_1 = .Range("B" & i).Value
Value_2 = .Range("C" & i).Value
Value_3 = .Range("D" & i).Value
ValueExists = False
With wsDestination
'Find the last row of Column B, wsDestination
LastRowDestination = .Cells(.Rows.Count, "B").End(xlUp).Row
'Loop Column B, wsDestination
For y = 5 To LastRowDestination
'Check to see whether data exists
If .Range("B" & y).Value = Value_1 Then
ValueExists = True
Exit For
End If
Next y
'If data doesn't exist in wsDestination then copy data to next available row
If ValueExists = False Then
.Range("B" & y).Value = Value_1
.Range("C" & y).Value = Value_2
.Range("D" & y).Value = Value_3
End If
End With
Next i
End With
End Sub
Screenshot 4 showing results after amended code
If I unterstood your problem, you always want to fill the next empty range on the destination sheet. First of all check this line:
For y = 5 To LastRowDestination
This loop will start from row number 5 which is the header row on the destination sheet. You don't want to accidentally overwrite it, so you start the loop from the 6th row like this:
For y = 6 To LastRowDestination
This line will check your rows to the last row on your destination sheet. So if every empty row has been filled, it will go to your last (not empty) row:
LastRowDestination = .Cells(.Rows.Count, "B").End(xlUp).Row
You want to check + 1 row (it will be a guaranteed empty row).
LastRowDestination = .Cells(.Rows.Count, "B").End(xlUp).Row + 1
You don't need ValueExists flag, you can check if a range is empty like this:
If WorksheetFunction.CountA(.Range("B" & y & ":D" & y)) = 0 Then ' EMPTY RANGE
So here is the cleaned up version of your code:
Sub test()
Dim wsSource As Worksheet, wsDestination As Worksheet
Dim LastRowSource As Long, LastRowDestination As Long
Dim i As Long, y As Long
With ThisWorkbook
Set wsSource = .Worksheets("Data Source")
Set wsDestination = .Worksheets("Data Destination")
End With
With wsSource
'Find the last row of Column C, wsSource
LastRowSource = .Cells(.Rows.Count, "C").End(xlUp).Row
'Loop Column C, wsSource
For i = 13 To LastRowSource
With wsDestination
'Find the last row of Column B, wsDestination
LastRowDestination = .Cells(.Rows.Count, "B").End(xlUp).Row + 1
'Data to be tested if it doesnt exist in wsDestination
'if IsError is true, data does not exist in wsDestination
If IsError(Application.VLookup(.Range("B" & i), .Range("B6:B" & LastRowDestination), 1, False)) Then
'Loop Column B, wsDestination
For y = 6 To LastRowDestination
'Check to see whether data existsd
If WorksheetFunction.CountA(.Range("B" & y & ":D" & y)) = 0 Then ' EMPTY RANGE
.Range("B" & y) = wsSource.Range("B" & i)
.Range("C" & y) = wsSource.Range("C" & i)
.Range("D" & y) = wsSource.Range("D" & i)
Exit For
End If
Next y
End If
End With
Next i
End With
End Sub

Copy row based on cell value

I am trying to search within a specific column for a "yes" value and copy the entire row of data if present into a new sheet.
So far I copy and paste a row which doesn't include a "yes". This results in four rows of the same data pasted instead of the four I need.
Dim rng As Range, cell As Range
Dim sht As Worksheet
Set sht = Worksheets("Output")
With sht
lastRow = .Range("R" & .Rows.Count).End(xlUp).Row
End With
If lastRow < 2 Then lastRow = 2
Set rng = sht.Range("R2:R" & lastRow)
For Each cell In rng
If cell.Value = "Yes" Then
ActiveCell.EntireRow.Copy
Worksheets("Callouts").Activate
Range("A" & Rows.Count).End(xlUp).Offset(1).Select
ActiveCell.PasteSpecial Paste:=xlPasteValues
End If
Next
End Sub
First you want iterate through each row, then each cell in the row to find the "Yes". Then you want to copy the row to the new sheet. Consider:
Dim rng As Range, cell As Range
Dim targetLastRow as Range
Dim sht As Worksheet
Set sht = Worksheets("Output")
'capture last row in source
sourceLastRow = sht.Range("R" & Rows.Count).End(xlUp).Row
If sourceLastRow < 2 Then sourceLastRow = 2
'set source rng
Set rng = sht.Range("R2:R" & lastRow)
'Capture last row in target sheet
targetLastRow = Sheets("Callouts").Range("A" & Rows.Count).End(xlUp).Row
'iterate through each row in source range
For each row in rng.rows
'iterate through each cell in row
For Each cell In row
If cell.Value = "Yes" Then
cell.EntireRow.Copy
Sheets("Callouts").Cells(targetLastRow, 1).PasteSpecial Paste:=xlPasteValues
'increment target to next row
targetLastRow = targetLastRow + 1
End If
Next
Next

How to enter a formula filling in to last data row

Within a Macro, I am consolidating data from one workbook (4WkData) with multiple worksheets to one worksheet (Markets).
After I pull the data from Wk4 - Sheet2, I then have a formula to take the information on Sheet 2 - "A3" and paste the formula into "A3" and "B3" (filling to the last Data Row in Column C).
This would replicate until I loop through all the Worksheets in the 4WkData Workbook.
However, my current macro is only pasting the formula in the top row, and not down. How do I fix this please?
Dim Mkts As Worksheet
Dim ws As Worksheet
Dim aDestLastRow As Long
Dim cDestLastRow As Long
Dim FR As Range 'first row
Dim LR As Range 'last row
'Destination Worksheet
Set Mkts = Workbooks("Nielsen SC Template.xlsm").Worksheets("Markets")
'Copy 4Wk Data
Workbooks.Open "C:\Users\cday\OneDrive - udfinc.com\Nielsen Scorecard\4Wk Data.xlsx"
Dim Wb4 As Workbook
Set Wb4 = Workbooks("4Wk Data.xlsx")
For Each ws In Wb4.Worksheets
With ws
If .Index <> 1 Then
'Find first blank row in the destination range based on data in Column A
aDestLastRow = Mkts.Cells(Mkts.Rows.Count, 1).End(xlUp).Row + 1
'Find first blank row in the destination range based on data in Column C
cDestLastRow = Mkts.Cells(Mkts.Rows.Count, 3).End(xlUp).Offset(1).Row
'Find last used row in the copy range based on data in Column A
Dim CopyLastRow4 As Long
CopyLastRow4 = .Cells(.Rows.Count, 1).End(xlUp).Row
If .Index = 2 Then
'Copy and Paste Data into C3
.Range("A4:V" & CopyLastRow4).Copy Mkts.Range("C" & cDestLastRow)
'Add Dates
Set FR = Mkts.Range("A3")
Set LR = Mkts.Range("A" & cDestLastRow)
Range(FR, LR).Formula = "=Mid('[4Wk Data.xlsx]Report1'!$A$1, 9, 28)"
'Add Markets
Set FR = Mkts.Range("B3")
Set LR = Mkts.Range("B" & cDestLastRow)
Range(FR, LR).Formula = "=Mid('[4Wk Data.xlsx]Report1'!$A$1, 48, 13)"
End If
'If .Index = 3 Then (Etc..)
End If
End With
Next ws

Loop that will copy Data from multiple sheets to one sheets

I looked through the other questions, and couldn't find one to match my scenario.
I have multiple worksheets, and want to copy/paste into another Workbook/Worksheet called 'Markets'.
The next steps are to take the data out of "A1" and add those to Column A and B (respectively)
However, the copied data is currently pasting over the previous data.
My formulas also are not dragging down to the end of the data.
Dim Mkts As Worksheet
Dim ws As Worksheet
Dim aDestLastRow As Long
Dim cDestLastRow As Long
Dim FR As Range 'first row
Dim LR As Range 'last row
'Destination Worksheet
Set Mkts = Workbooks("Nielsen SC Template.xlsm").Worksheets("Markets")
'Find first blank row in the destination range based on data in Column A
aDestLastRow = Mkts.Cells(Mkts.Rows.Count, "A").End(xlUp).Row
'Find first blank row in the destination range based on data in Column C
cDestLastRow = Mkts.Cells(Mkts.Rows.Count, "C").End(xlUp).Offset(1).Row
'Copy 4Wk Data
Dim Wb4 As Workbook
Set Wb4 = Workbooks("4Wk Data.xlsx")
For Each ws In Wb4.Worksheets
With ws
If .Index <> 1 Then
'Find last used row in the copy range based on data in Column A
Dim CopyLastRow4 As Long
CopyLastRow4 = .Cells(.Rows.Count, "A").End(xlUp).Row
If .Index = 2 Then
'Copy and Paste Data into C3
.Range("A4:V" & CopyLastRow4).Copy Mkts.Range("C" & cDestLastRow)
'Add Dates
Set FR = Mkts.Range("A" & cDestLastRow)
Set LR = Mkts.Range("A" & aDestLastRow)
Range(FR, LR).Formula = "=Mid('[4Wk Data.xlsx]Report1'!$A$1, 9, 28)"
'Add Markets
Set FR = Mkts.Range("B" & cDestLastRow)
Set LR = Mkts.Range("B" & aDestLastRow)
Range(FR, LR).Formula = "=Mid('[4Wk Data.xlsx]Report1'!$A$1, 48, 13)"
End If
If .Index = 3 Then
'Copy and Paste Data
.Range("A4:V" & CopyLastRow4).Copy Mkts.Range("C" & cDestLastRow)
etc...
Since I cannot test your code, I can see only two issues:
Issue 1 You are not updating aDestLastRow and cDestLastRow in the code provided (at least)
Issue 2 To assign the value of aDestLastRow you seem to have forgotten to Offset the row by one.
A simple fix is to move these assignment into the loop. Another fix is to simply update the values of aDestLastRow and cDestLastRow by adding the number of copied rows, which I can see as CopyLastRow4 - 4, but obviously this needs to be tested. In the following code I moved the assigment lines into the code, which is the less efficient option. I hope this helps!
Dim Mkts As Worksheet
Dim ws As Worksheet
Dim aDestLastRow As Long
Dim cDestLastRow As Long
Dim FR As Range 'first row
Dim LR As Range 'last row
'Destination Worksheet
Set Mkts = Workbooks("Nielsen SC Template.xlsm").Worksheets("Markets")
'Copy 4Wk Data
Dim Wb4 As Workbook
Set Wb4 = Workbooks("4Wk Data.xlsx")
For Each ws In Wb4.Worksheets
'*****Moved these lines into loop
'*****You forgot to offset the first assignment
'Find first blank row in the destination range based on data in Column A
aDestLastRow = Mkts.Cells(Mkts.Rows.Count, "A").End(xlUp).Row + 1
'Find first blank row in the destination range based on data in Column C
cDestLastRow = Mkts.Cells(Mkts.Rows.Count, "C").End(xlUp).Offset(1).Row
'******End of edit
With ws
If .Index <> 1 Then
'Find last used row in the copy range based on data in Column A
Dim CopyLastRow4 As Long
CopyLastRow4 = .Cells(.Rows.Count, "A").End(xlUp).Row
If .Index = 2 Then
'Copy and Paste Data into C3
.Range("A4:V" & CopyLastRow4).Copy Mkts.Range("C" & cDestLastRow)
'Add Dates
Set FR = Mkts.Range("A" & cDestLastRow)
Set LR = Mkts.Range("A" & aDestLastRow)
Range(FR, LR).Formula = "=Mid('[4Wk Data.xlsx]Report1'!$A$1, 9, 28)"
'Add Markets
Set FR = Mkts.Range("B" & cDestLastRow)
Set LR = Mkts.Range("B" & aDestLastRow)
Range(FR, LR).Formula = "=Mid('[4Wk Data.xlsx]Report1'!$A$1, 48, 13)"
End If
If .Index = 3 Then
'Copy and Paste Data
.Range("A4:V" & CopyLastRow4).Copy Mkts.Range("C" & cDestLastRow)

Copy data to a new sheet excluding the last 4 rows

I'm trying to copy a table from sheet 1, defined by the area D21:O21, until the end – (minus) the last 4 lines.
I have a problem pasting results. In sheet 2 I have a table that feeds pivot charts. After I delete previous filled rows (with values) and paste new ones (new values) the table extends further than it is supposed to. It adds blank cells downstream as if the copied sheet 1 had more rows with values.
For example: Imagine that my table (in sheet 1) has 600 rows with values. If I paste to the table (in sheet 2) it extends further than 600 rows (approx. 10000). Instead of adding multiple empty lines I want 600 except last 4 lines = from top to 596 rows.
Sub Prime()
Dim Last_Row1 As Long, Last_Row2 As Long
Dim ws1 As Worksheet, ws2 As Worksheet
Set ws1 = Sheets("Enter DATA here")
Set ws2 = Sheets("DATA")
Application.ScreenUpdating = False
Last_Row1 = ws1.Range("C" & Rows.Count).End(xlUp).Row ' Determine the lastrow of the data to copy
Last_Row2 = ws2.Range("A" & Rows.Count).End(xlUp).Row ' Determine the next empty row in order to paste the data
ws1.Range("D21:O21" & Last_Row1).Copy ws2.Range("A" & Last_Row2)
Application.ScreenUpdating = True
End Sub
Try this:
Sub Prime()
Dim Last_Row1 As Long, Last_Row2 As Long, table As Range
Dim ws1 As Worksheet, ws2 As Worksheet
Set ws1 = Sheets("Enter DATA here")
Set ws2 = Sheets("DATA")
Set table = ws1.Range("D21:O28") // I arbitrarily set this to 8 rows
Application.ScreenUpdating = False
Last_Row1 = ws1.Range("C" & Rows.Count).End(xlUp).Row ' Determine the lastrow of the data to copy
Last_Row2 = ws2.Range("A" & Rows.Count).End(xlUp).Row ' Determine the next empty row in order to paste the data
table.Resize(table.Rows.Count - 4, table.Columns.Count).Copy ws2.Range("A" & Last_Row2)
Application.ScreenUpdating = True
End Sub
Sub Prime()
Dim Last_Row1 As Long, Last_Row2 As Long
Dim ws1 As Worksheet, ws2 As Worksheet
Set ws1 = Sheets("Enter DATA here")
Set ws2 = Sheets("DATA")
Application.ScreenUpdating = False
Last_Row1 = ws1.Range("C" & Rows.Count).End(xlUp).Row ' Determine the lastrow of the data to copy
Last_Row2 = ws2.Range("A" & Rows.Count).End(xlUp).Row ' Determine the next empty row in order to paste the data
ws1.Range("D21:O" & Last_Row1-4).Copy ws2.Range("A" & Last_Row2)
Application.ScreenUpdating = True
End Sub
You can use Offset function to exclude the last 4 rows.
Last_Row1 = ws1.Range("C" & Rows.Count).End(xlUp).offset(-4,0).Row
When you copy the range, you should delete row indicator "21" behind column "O", otherwise, the code would not select till the last row. Like following:
ws1.Range("D21:O" & Last_Row1).Copy ws2.Range("A" & Last_Row2)

Resources