VBA - Copy variable range from one sheet to another - vba

I would like to copy data from a sheet "Inv_Headers", Column C, from 2nd row until the last row to a sheet "Customers", Column U, from 4th row.
Private Sub Invoice_C()
Dim ws As Worksheet, ws1 As Worksheet
Dim lastrow As Long
Set ws = Worksheets("Inv_Headers")
Set ws2 = Worksheets("CUSTOMERS")
lastrow = ws.Cells(Rows.Count, 3).End(xlUp).Row ' last row in column C
ws.Range("C2:C" & lastrow).Copy
ws1.Range("U4").PasteSpecial xlPasteValues
ws1.Activate
End Sub
My code is giving me error msg '91' - Object variable or With block variable not set. But the code should work without With statement as well, shouldn't it?
Could I ask you for your advices, please?
Many thanks!

Based on check from #Absinthe, I've corrected the typo and here is the correct code:
Private Sub Invoice_C()
Dim ws As Worksheet, ws1 As Worksheet
Dim lastrow As Long
Set ws = Worksheets("Inv_Headers")
Set ws1 = Worksheets("CUSTOMERS")
lastrow = ws.Cells(Rows.Count, 3).End(xlUp).Row ' last row in column C
ws.Range("C2:C" & lastrow).Copy
ws1.Range("U4").PasteSpecial xlPasteValues
ws1.Activate
End Sub

In addition to Srpic's offering, I can remember not getting this part to work:
ws.Range("C2:C" & lastrow).Copy
you can fix it with ws.Range("C2", "C" & lastrow).Copy
If you start typing in Range() you will see that , is an acceptable separator, whereas : for an incomplete range assingment is not.
Private Sub Invoice_C()
Dim ws As Worksheet, ws1 As Worksheet
Dim lastrow As Long
Set ws = Worksheets("Inv_Headers")
Set ws1 = Worksheets("CUSTOMERS")
lastrow = ws.Cells(Rows.Count, 3).End(xlUp).Row ' last row in column C
ws.Range("C2", "C" & lastrow).Copy
ws1.Range("U4").PasteSpecial xlPasteValues
ws1.Activate
End Sub

Related

How to dynamically select a range VBA

My question is very similar to the following:
Excel VBA code to select non empty cells
However, I have some empty cells in between. In particular, I'm trying to define a range where the first row needs to be excluded, since it's a header. I also have to exclude the empty cells that follow. I was trying something like
Dim wb as workbook, ws as worksheet
Dim myrange as range
'Defined reference wb and ws
myrange=ws.range("B2",range("B2"),end(xldown))
But this only works if there are not empty cells in between. So, is there a fast and simple way to dynamically select a range that includes non-empty cells, excepted the header?
Try this
'Defined reference wb and ws
Set myrange = ws.range("B2", ws.Range("B" & Rows.Count).End(xlUp))
Don't forget to use the Set keyword
Try the next way, please:
Sub testDefineRange()
Dim ws As Worksheet, lastRow As Long, myrange As Range
Set ws = ActiveSheet 'use here what you need
lastRow = ws.Range("B" & ws.rows.count).End(xlUp).row
'Defined reference ws
Set myrange = ws.Range("B2:B" & lastRow)
myrange.Select
End Sub
I have found this link to be very useful on MANY occasions.
https://www.thespreadsheetguru.com/blog/2014/7/7/5-different-ways-to-find-the-last-row-or-last-column-using-vba
Ways To Find The Last Row
Sub FindingLastRow()
'PURPOSE: Different ways to find the last row number of a range
'SOURCE: www.TheSpreadsheetGuru.com
Dim sht As Worksheet
Dim LastRow As Long
Set sht = ActiveSheet
'Using Find Function (Provided by Bob Ulmas)
LastRow = sht.Cells.Find("*", searchorder:=xlByRows, searchdirection:=xlPrevious).Row
'Using SpecialCells Function
LastRow = sht.Cells.SpecialCells(xlCellTypeLastCell).Row
'Ctrl + Shift + End
LastRow = sht.Cells(sht.Rows.Count, "A").End(xlUp).Row
'Using UsedRange
sht.UsedRange 'Refresh UsedRange
LastRow = sht.UsedRange.Rows(sht.UsedRange.Rows.Count).Row
'Using Table Range
LastRow = sht.ListObjects("Table1").Range.Rows.Count
'Using Named Range
LastRow = sht.Range("MyNamedRange").Rows.Count
'Ctrl + Shift + Down (Range should be first cell in data set)
LastRow = sht.Range("A1").CurrentRegion.Rows.Count
End Sub
Ways To Find The Last Column
Sub FindingLastColumn()
'PURPOSE: Different ways to find the last column number of a range
'SOURCE: www.TheSpreadsheetGuru.com
Dim sht As Worksheet
Dim LastColumn As Long
Set sht = ThisWorkbook.Worksheets("Sheet1")
'Ctrl + Shift + End
LastColumn = sht.Cells(7, sht.Columns.Count).End(xlToLeft).Column
'Using UsedRange
sht.UsedRange 'Refresh UsedRange
LastColumn = sht.UsedRange.Columns(sht.UsedRange.Columns.Count).Column
'Using Table Range
LastColumn = sht.ListObjects("Table1").Range.Columns.Count
'Using Named Range
LastColumn = sht.Range("MyNamedRange").Columns.Count
'Ctrl + Shift + Right (Range should be first cell in data set)
LastColumn = sht.Range("A1").CurrentRegion.Columns.Count
End Sub
If it suits your case, I like to use CurrentRegion with Intersect to eliminate the title row.
with ws.range("b2")
set myRange = intersect(.currentregion, .currentregion.offset(1,0))
end with
debug.print myRange.address

VBA - Copy data from one sheet to another

I'm trying to copy data from sheet "DATEV_RAB_UNVERBINDLICH", Range D2:D to sheet "Ready to upload", Range B2:B.
I would like find data to the last row and then copy them into the other sheet. I have this code:
Sub CopyInvoiceNo()
Dim ws, ws1 As Worksheet
Dim lastrow As Long
lastrow = .Cells(.Rows.Count, "D").End(xlUp).Row
Set ws = Sheets("DATEV_RAB_UNVERBINDLICH")
Set ws1 = Sheets("Ready to upload")
ws.Range("D2" & lastrow).Copy
ws1.Range("B4").PasteSpecial xlPasteValues
ws1.Activate
End Sub
But I receive error msg Invalid or unqualified reference. Could you advise me, what do I do wrong, please?
Two errors in your code
At line 3, this is not the correct way to define multiple variable types in the same line. You have to define each of them.
At line 10, lets say your lastrow is "20". It would set the range to "D220", which is also not what you want.
Sub CopyInvoiceNo()
Dim ws As Worksheet, ws1 As Worksheet
Dim lastrow As Long
Set ws = Sheets("DATEV_RAB_UNVERBINDLICH")
Set ws1 = Sheets("Ready to upload")
lastrow = ws.Cells(Rows.count, 4).End(xlUp).Row
ws.Range("D2:D" & lastrow).Copy
ws1.Range("B4").PasteSpecial xlPasteValues
ws1.Activate
End Sub
I also changed to define the variables and its values at the start of the code. The lastrow bit didn't code here too after a bit of testing. Now it works for me at least.

Copy and Paste Dynamic Range from One Worksheet to Another

I am attempting to copy column A starting in row 2 on "Sheet1" and paste it in Column C on sheet "ABC" starting at row 5. The number of rows in Column A is variable so I cannot use a fixed range.
The code below does what I need, but I am trying to avoid using .Select and .Activate
LastRow = Range("A" & Rows.Count).End(xlUp).Row
Sheets("Sheet1").Range("A2:A" & LastRow).Copy
Sheets("ABC").Activate
Sheets("ABC").Range("C5:C" & LastRow).Select
Selection.PasteSpecial xlPasteValues
I tried setting the columns equal to one another using this code:
Sheets("ABC").Range("C5").End(xlDown).Value=Sheets("Sheet1").Range("A2:A" & LastRow).Value
This runs without error but it "does nothing" -- No data appears on worksheet "ABC"
I also tried to following:
Dim WS As Worksheet
Dim wsABC As worksheet
Set WS = Sheets("Sheet1")
Set wsABC = Sheets("ABC")
LastRow = Range("A" & Rows.Count).End(xlUp).Row
WS.Range("A2:A" & LastRow).Copy
wsABC.Range("C5").End(xlDown).Paste
This produces a "Run-time error #438 Object doesn't support this property or method" Error on this line:
wsABC.Range("C5").End(xlDown).Paste
Another method I tried was as follows:
Dim WS As Worksheet
Set WS = Sheets("Sheet1")
Set wsABC = Sheets("ABC")
With WS
LastRow = Range("A" & Rows.Count).End(xlUp).Row
WS.Range("A2:A" & LastRow).value = wsABC.Range("C5:C & LastRow").Value
End With
This produces a "Run-time error '1004' Application-defined or object defined error.
I am open to corrections / comments on any of my attempts, I just want to avoid using .Select and .Activate.
Thank you in advance for your time and assistance!
Coding styles can vary greatly. Here's one way to do what you're looking for:
Sub tgr()
Dim wb As Workbook
Dim wsData As Worksheet
Dim wsDest As Worksheet
Set wb = ActiveWorkbook
Set wsData = wb.Sheets("Sheet1")
Set wsDest = wb.Sheets("ABC")
With wsData.Range("A2", wsData.Cells(wsData.Rows.Count, "A").End(xlUp))
wsDest.Range("C5").Resize(.Rows.Count).Value = .Value
End With
End Sub
With Worksheets("Sheet 1")
With .Range("A2", .Cells(.Rows.Count, 1).End(xlUp))
Worksheets("ABC").Range("C5").Resize(.Rows.Count).Value = .Value
End With
End With

How to start selecting at row 2, rather than all rows?

How can I modify the following to limit the selection to only start at row 2? Currently it selects every row.
Set myRng = .Range("D2", .Cells(.Rows.Count, "D").End(xlUp))
To make it work, you will have to ensure that there is data in cell D2. See this example.
Sub Sample()
Dim myRng As Range
Dim ws As Worksheet
Dim Lrow As Long
'~~> Change this to the relevant worksheet
Set ws = ThisWorkbook.Sheets("Sheet1")
With ws
'~~> Get last row which has data in Col D
Lrow = .Range("D" & .Rows.Count).End(xlUp).row
If Not Lrow < 2 Then
Set myRng = .Range("D2:D" & Lrow)
MsgBox myRng.Address
Else
MsgBox "There is no data in cell D2"
End If
End With
End Sub

Excel 2007 macro fills to end of first sheet for all sheets in workbook

The code below creates a new column (A), gives the it the header "Class" and then fills column A with the worksheet name until the last row of B for all worksheets in workbook. It is working except that it fills all worksheets to the the last row of B from the first sheet processed for all subsequent sheets. What have I done wrong? I like the fill to be determined by the last row of B for each sheet.
Option Explicit
Sub AddColumnFill()
Dim sht As Worksheet
For Each sht In ActiveWorkbook.Worksheets
sht.Range("A1").EntireColumn.Insert xlShiftToRight
sht.Cells(1, 1) = "Class"
sht.Range("A2:A" & Cells(Rows.Count, "B").End(xlUp).Row).Value = sht.Name
Next sht
End Sub
This works for me.
Option Explicit
Sub AddColumnFill()
Dim sht As Worksheet
Dim lRow As Long
For Each sht In ActiveWorkbook.Worksheets
With sht
lRow = .Range("A" & .Rows.Count).End(xlUp).Row
.Columns("A:A").Insert Shift:=xlToRight
.Cells(1, 1) = "Class"
.Range("A2:A" & lRow).Value = .Name
End With
Next sht
End Sub
Use
sht.Range("A2:A" & sht.Cells(sht.Rows.Count, "B").End(xlUp).Row).Value = sht.Name
Instead of
sht.Range("A2:A" & Cells(Rows.Count, "B").End(xlUp).Row).Value = sht.Name