copy and paste entire row from one to another sheet issue - vba

I would like to copy entire row from today Sheet to last available row of main Sheet if today Sheet B2:B cell value = "Update". However, I come up with copy area and paste area are not the same size issue. I've tried many ways but cannot get it solved. Can anyone help? Thanks in advanced.
Sub getnew()
Dim Sheet1 As Worksheet
Dim Sheet3 As Worksheet
Dim lastrow As Integer
Dim i As Integer
Set Sheet1 = ThisWorkbook.Sheets("main")
Set Sheet3 = ThisWorkbook.Sheets("today")
lastrow = Sheet3.Range("C" & Rows.Count).End(xlUp).Row
Dim erow As Long
For i = 2 To lastrow
erow = Sheet1.Range("C" & Rows.Count).End(xlUp).Row + 1
If Sheet3.Cells(i, 2).Value = "Update" Then
Sheet3.Cells(i, 2).EntireRow.Copy Destination:=Sheet1.Range("B" & erow)
End If
Next i
End Sub

You are trying to copy the entire row of a worksheet, but you are pasting that row in another sheet, starting at column B. They aren't the same size, because an entire row contains 16,384 columns, but a row starting at column B only has 16,383 columns.
You have a few options to resolve this:
You could paste the entire row onto the other sheet at column A, like so:
Sheet3.Cells(i, 2).EntireRow.Copy Destination:=Sheet1.Range("A" & erow)
Or you could copy only the number of columns which you care about, instead of trying to copy the entire row, like so [I don't know what it is you're trying to copy, so you will need to figure out how exactly you want to size it. I have assumed that 10 columns is sufficient]:
Sheet3.Range(Cells(i, 2), Cells(i,11)).Copy Destination:=Sheet1.Range("B" & erow)

Related

Excel VBA macro to copy rows that meet a criteria to a new row on another sheet

I am struggling with my code- and will admit that I am a newbie to VBA.
Yes- I have reviewed a ton of posts and dont seem to be able to fix my code!
I am trying to extract rows that meet a specific value ('Priority')- which is located in column H across 15 sheets. The code needs to extract any rows that meet the criteria from all of the 15 sheets. The extracted row is to be pasted into the front sheet "FootpathStrategyTool"- starting at cell A20 (below the predefined headers).
I am having difficulty getting the loop to paste the copied row into the next blank row. The code runs, but seems to miss the first few worksheets. It may have something to do with my final row line.
If anyone can help I would be extremely grateful!!!!
Sub getdata()
'1. what is the priority value you wish to search for?
'2. define lastrow for the sheets
'3. Find records that match priority value and paste them into the main sheet
Dim Priority As Integer
Dim Worksheet As Worksheet
Priority = Sheets("FootpathStrategyTool").Range("I10").Value
' Find the final row of data for all sheets
For Each Worksheet In ActiveWorkbook.Worksheets
Worksheet.Select
finalrow = Cells(Rows.Count, 1).End(xlUp).Row
Dim NextRow As Range
Set NextRow = Sheets("FootpathStrategyTool").Cells(Cells.Rows.Count,
1).End(xlUp).Offset(1, 0)
' Loop through each row
For x = 4 To finalrow
' Decide if to copy based on column H Priority
ThisValue = Cells(x, 8).Value
If ThisValue = Priority Then
Cells(x, 1).Resize(1, 33).Copy
Sheets("FootpathStrategyTool").Select
NextRow = Cells(“A” & Rows.Count).End(xlUp).Row + 19
Cells(NextRow, 1).Select
End If
' Step down 1 row from present location.
ActiveCell.Offset(1, 0).Select
ActiveSheet.Paste
Sheets("FootpathStrategyTool").Select
Next x
Next Worksheet
End Sub
A few suggestions I hope you find helpful:
Dim Worksheet As Worksheet. Typically you wouldn't want to declare a variable name with the same name as an object. It can make things a bit confusing. I'd suggest Dim wsData As Worksheet.
ThisValue = Cells(x, 8).Value. While this works, you haven't explicitly declared ThisValue with a type which means ThisValue is now a Variant type. In the example above, you have a simple evaluation of "If ThisValue = Priority Then" so everything in this code will probably work as expected, but you might get unexpected results or errors in a more complex application. The same goes for "finalrow" and "x".
There 's a significant difference between "Cells" and ".Cells". ".Cells" refers to a specific worksheet that you defined earlier in the code while "Cells" refers to whichever worksheet was last active. Since your code is trying to create row numbers while jumping back and forth between the front sheet and the data sheets, it's easy to lose track of which sheet you're actually creating the numbers from.
When referring to specific worksheets and ranges, it's not always necessary to jump between them and activate them. You can just move the data as an array by specifying the source and destination locations.
I believe, however, the source of your problem is
NextRow = Cells(“A” & Rows.Count).End(xlUp).Row + 19. You established the last row range when you Declared and Set it above, and now your re-establishing it then adding another 19 rows to it. Also, Cells(“A” & Rows.Count) is not a valid reference. "A" will return as empty which means you're actually saying Cells(Rows.Count) and not providing a column reference.
Please consider this as an alternative.
Sub getdata()
'1. what is the priority value you wish to search for?
'2. define lastrow for the sheets
'3. Find records that match priority value and paste them into the main sheet
'This identifies precisely which sheet you're copying data to.
Dim wsHome As Worksheet: Set wsHome = ActiveWorkbook.Worksheets("FootpathStrategyTool")
Dim Priority As Integer: Priority = wsHome.Range("I10").Value
Dim wsData As Worksheet
Dim ThisValue As Variant
Dim NextRow As Variant
Dim finalrow As Long
'i0 will be used to cycle through the data worksheets.
Dim i0 As Long
'i1 will be used to increment through the rows on the Home sheet starting at row 20.
Dim i1 As Long: i1 = 20
'This says to start at the second worksheet and look at each one to the end.
For i0 = 2 To ActiveWorkbook.Worksheets.Count
'This specifies exactly which worksheet you're working with.
With ActiveWorkbook.Worksheets(i0)
finalrow = .Cells(.Rows.Count, 1).End(xlUp).Row
'Loop through each row
For x = 4 To finalrow
'Decide if to copy based on column H Priority. Pull the whole range as an object.
If .Cells(x, 8).Value = Priority Then
ThisValue = .Range(.Cells(x, 1), .Cells(x, 33)).Value
'Identify the data's destination on the Home tab.
Set NextRow = wsHome.Cells(i1, 1)
'Resize the destination range and drop the data in one line.
NextRow.Resize(1, UBound(ThisValue, 2)).Value = ThisValue
'Increment the cell reference to the next row.
i1 = i1 + 1
End If
Next x
End With
Next i0
End Sub

Dynamic Last Row

I'm using the following code to find the last row in Sheet1 & Sheet2
Dim 1LastRow As Long
Dim 2LastRow As Long
1LastRow = Sheets("Sheet1").Cells(Rows.Count, 1).End(xlUp).Row
2LastRow = Sheets("Sheet2").Cells(Rows.Count, 1).End(xlUp).Row
This works as initially expected, however I'd like "1LastRow" to adjust to dynamically pick up the last row.
For example, if Sheet1 initially has 50 rows, but after:
Sheets("Sheet2").Range("B2:B" & 2LastRow).Copy
Sheets("Sheet1").Range("D2").PasteSpecial xlPasteValues
Sheet1 now has 55 rows. However, "1LastRow" is still assuming that Sheet1 only has 50 rows, and thus creates inconsistencies throughout the rest of the code when "1LastRow" is used. Any input is greatly appreciated!
Well, a variable doesn't magically update itself. You see that you have code that pastes rows. Just repeat the code that sets the variable for the last row when you do something that changes the last row.
Dim 1LastRow As Long
Dim 2LastRow As Long
1LastRow = Sheets("Sheet1").Cells(Rows.Count, 1).End(xlUp).Row
2LastRow = Sheets("Sheet2").Cells(Rows.Count, 1).End(xlUp).Row
Sheets("Sheet2").Range("B2:B" & 2LastRow).Copy
Sheets("Sheet1").Range("D2").PasteSpecial xlPasteValues
1LastRow = Sheets("Sheet1").Cells(Rows.Count, 1).End(xlUp).Row
Or you could use a dynamic range name with a formula along the lines of
=INDEX(Sheet1!$A:$A,COUNTA(Sheet1!$A:$A))
Then refer to that range like
ThisWorkbook.Worksheets("Sheet1").Range("OneLastRow").Row
But this will fall over if the column contains blank cells.
first off your code won't compile in an Office VBA environment: variables names can't start with a number. So let's call them LastRow1 and LastRow2, instead
second, even if there were some automagic way of making a variable self update, your code would fail since you are copying a 1-column range from Sheet2 and pasting it starting from cell D2 of Sheet1, which would have no effect whatsoever in column A last row index setting
all that said, you have could use a Function() that returns the wanted row index.
For instance this function:
Function LastRow1() As Long
With Sheets("Sheet1")
LastRow1 = .Cells(.Rows.Count, 4).End(xlUp).Row
End With
End Function
would return Sheet1 column D last not empty row index (well, it would actually fail should column A be totally empty, but it's an easy fix)
you could easily have it return any other column last not empty cell row index by simply changing column index in .Cells(.Rows.Count, 4)
so that your "main" code would look like:
Sub main()
Dim LastRow2 As Long
LastRow2 = Sheets("Sheet2").Cells(Rows.Count, 1).End(xlUp).Row
Sheets("Sheet2").Range("B2:B" & LastRow2).Copy
Sheets("Sheet1").Range("D2").PasteSpecial xlPasteValues
MsgBox LastRow1 ' this would return Sheet1 column D last not empty row index
MsgBox Sheets("Sheet1").Range("D2:D" & LastRow1).Address 'this would return the address of Sheet1 column D range from cell D2 down to last not empty cell
End Sub

Copy paste values from one sheet to another via loop

Maybe somebody can help me with this one very basic problem that I have which is driving me nuts. I just need to copy some data from one sheet to another one depending on its output.
The variables have been defined previously and wMod and wRes stand for worksheets, countP and countC stands for the total amount of cells calculated in another worksheet.
What I need to do is to write a code that would be able to copy data with the value in cell B which has the number 1 in it, paste and paste it in another sheet. When I write the code below though, I only get in column A, sheet wRes the total amount of cells that were stored in variable countP.
You can see what kind of output I get below with the picture I attached.Data output Anybody has any idea why I cannot get the right output? Been stuck with this problem for hours.
For i = 3 To countP
If wMod.Range("B" & i) = 1 Then
For j = 3 To countC1
wMod.Range("A" & i).Copy wRes.Range("A" & j)
Next j
End If
Next i
The following code will check the Last Row with Data on Sheet1 Column A, then it will loop from row 2 to the Last and check if Column B = 1, then it will check the last row with data on Sheet2 Column A, and paste the value in the next row (ie. next empty row).
It goes like so:
Sub foo()
Dim ws As Worksheet: Set ws = Sheets("Sheet1")
Dim ws2 As Worksheet: Set ws2 = Sheets("Sheet2")
Dim LastRow As Long
Dim LastRow2 As Long
LastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
'find the last row with data on Column A in Sheet1
For i = 2 To LastRow 'loop from row 2 to last
If ws.Range("B" & i) = 1 Then 'if column B in Sheet1 = 1 then
LastRow2 = ws2.Cells(ws2.Rows.Count, "A").End(xlUp).Row 'find the last row with data on Sheet2 Column A
ws2.Cells(LastRow2 + 1, 1) = ws.Range("A" & i)
End If
Next i
End Sub

How to Copy data from one sheet to another based on cell value

I have a master dataset in one sheet something like this
In another sheet I want to extract Data from this Master Data set based on a cell value which will have Department as Criteria.
So ,For example if in sheet 2 I type my my Department criteria as Sales, All the rows with Department as Sales should get populated in Sheet 2.
Can this be done by excel functions/Macros/VBA ?
Thanks in advance.
Pardon me if you find this query absurd .
Yes it can be done. Add this code to a module in your workbook. You can run it right from the debugger, or go to macros and assign it a hotkey, or you can create a button on the sheet and put this code inside the button click event. There are probably more efficient ways to do this but it shouldn't matter unless you have a lot of data. I've been explicit so you can see whats going on. I've used the sheet names "Data" and "View" you will have to change the names in the code to match your workbook.
EDIT: I'm also assuming that the top left cell in your screenshot is A1, if not you will have to adjust the code.
Sub GetDepartments()
Dim LastRow As Long
Dim MyRange As Range
Dim SourceRow As Long
Dim DeptValue As String
Dim OutputRow As Long
Dim ColCounter As Long
'get size of current view sheet and clear
LastRow = ThisWorkbook.Worksheets("View").Cells(ThisWorkbook.Worksheets("View").Rows.Count, "A").End(xlUp).Row
If LastRow > 7 Then
Set MyRange = ThisWorkbook.Worksheets("View").Range("A7:C" & LastRow)
MyRange.ClearContents
End If
'get size of data sheet
LastRow = ThisWorkbook.Worksheets("Data").Cells(ThisWorkbook.Worksheets("Data").Rows.Count, "A").End(xlUp).Row
'get value to match
DeptValue = ThisWorkbook.Worksheets("View").Cells(3, 2).Value
'track outputrow
OutputRow = 7
'loop through all rows in data
For SourceRow = 2 To LastRow
'if match found
If ThisWorkbook.Worksheets("Data").Cells(SourceRow, 2).Value = DeptValue Then
'copy 3 cols
For ColCounter = 1 To 3
ThisWorkbook.Worksheets("View").Cells(OutputRow, ColCounter).Value = _
ThisWorkbook.Worksheets("Data").Cells(SourceRow, ColCounter).Value
Next ColCounter
'increment outputrow
OutputRow = OutputRow + 1
End If
Next SourceRow
End Sub

VBA copy & paste with dynamic range

I'm new with VBA and I'm stuck somewhere. I have to copy last row of column A till column H and paste it untill the last row of column I. Last rows of columnns will be always change.
e.g; my data is in A2:H2 and I5 is the last cell with data.
My code should be copy A2:H2 and paste it A3:H5. And second time I run the macro (after I add new data to respective columns) it should be copy A6:H6 and paste it untill the last row of column I.
I wrote two codes which were not fulfill my needs.
first code is;
Sub OrderList1()
Range("a65536").End(xlUp).Resize(1, 8).Copy _
(Cells(Cells(Rows.Count, 9).End(xlUp).Row, 1))
End Sub
this code skips A3:H4 and only pastes to A5:H5
second code is;
Sub OrderList2()
Range("A2:H2").Copy Range(Cells(2, 8), _
Cells(Cells(Rows.Count, 9).End(xlUp).Row, 1))
End Sub
it copies A2:H3 and paste it A5:H5 but when I add new data it doesn't start to paste from A5:H5. It start from A2:H2 and overwrite to old data.
I can see what I have to change,range should be dynamic range like in the first code,but I can't manage to write the code.
I'll really appreciate little help.
You might want to use this as a starting point:
Dim columnI As Range
Set columnI = Range("I:I")
Dim columnA As Range
Set columnA = Range("A:A")
' find first row for which cell in column A is empty
Dim c As Range
Dim i As Long
i = 1
For Each c In columnA.Cells
If c.Value2 = "" Then Exit For
i = i + 1
Next c
' ok, we've found it, now we can refer to range from columns A to H of the previous row
' to a variable (in the previous row, column A has not been empty, so it's the row we want
' to copy)
Dim lastNonEmptyRow As Range
Set lastNonEmptyRow = Range(Cells(i - 1, 1), Cells(i - 1, 8))
' and now copy this range to all further lines, as long as columnI is not empty
Do While columnI(i) <> ""
lastNonEmptyRow.Copy Range(Cells(i, 1), Cells(i, 8))
i = i + 1
Loop
Try this one for something that allows future functionality, or at least it did for me...Ask if you need help understanding it :)
Option Explicit
Sub lastrow()
Dim wsS1 As Worksheet 'Sheet1
Dim lastrow As Long
Dim lastrow2 As Long
Set wsS1 = Sheets("Sheet1")
With wsS1
'Last row in A
lastrow = Range("A" & Rows.Count).End(xlUp).Row
'Last Row in I
lastrow2 = Range("I" & Rows.Count).End(xlUp).Row
'Cut in A:H and paste into last row on I
wsS1.Range("A2:H" & lastrow).Cut wsS1.Range("I" & lastrow2)
End With
End Sub