Reputation: 169
I am trying to do a copy in VBA, as part of a bigger macro so it needs to be in VBA, of an unknown range in a specific worksheet.
I have this code that work if I am in that worksheet:
Sub Copy()
Range("O2", Range("O" & Cells(Rows.Count, "A").End(xlUp).Row)).copy
End Sub()
And I have below that works for a specific range:
Sub Test()
Worksheets("Data").Range("O2:O10").Copy
End Sub()
How can I make the second code work as unspecific.
Thanks,
Upvotes: 1
Views: 1238
Reputation: 2866
You clearly don't enjoy using variables, so:
Worksheets("Data").Range("O2", Worksheets("Data").Range("O" & Cells(Rows.Count, "A").End(xlUp).Row)).copy
would suffice.
Generally, a more common solution would be to use intersect and CurrentRegion:
Application.intersect(Worksheets("Data").Range("O2").CurrentRegion,Worksheets("Data").Range("O2:O999999")).copy
Upvotes: 0
Reputation: 13386
you could use a Function you pass the "seed" range to and returning a range from passed one to the last not empty cell in the same column, as follows (explanations in comments)
Function GetRange(rng As Range) As Range
With rng.Parent ' reference passed range parent worksheet
Set GetRange = .Range(rng, .Cells(.Rows.Count, rng.Column).End(xlUp)) ' return referenced sheet range from passed range to passed range column last not empty cell
End With
End Function
to be used as follows:
Sub Test()
GetRange(Worksheets("Data").Range("O2")).Copy
End Sub
you could enhance the function and have it handle a given "final" row
Function GetRange(rng As Range, Optional finalRow As Variant) As Range
With rng.Parent ' reference passed range parent worksheet
If IsMissing(finalRow) Then ' if no "final" row passed
Set GetRange = .Range(rng, .Cells(.Rows.Count, rng.Column).End(xlUp)) ' return referenced sheet range from passed range to passed range column last not empty cell
Else 'else
Set GetRange = .Range(rng, .Cells(finalRow, rng.Column)) ' return referenced sheet range from passed range to passed range column cell in give "final" row
End If
End With
to be used as follows:
Sub Test()
GetRange(Worksheets("Data").Range("O2"), 2).Copy
End Sub
having kept "final" row as optional, the function can be used with or without passing it:
Sub Test()
GetRange(Worksheets("Data").Range("O2")).Copy ' this will copy worksheet "Data" range from row 2 down to its column "O" last not empty row
GetRange(Worksheets("Data").Range("O2"), 3).Copy ' this will copy worksheet "Data" range from row 2 down to row 3
End Sub
Upvotes: 0
Reputation: 43595
The simplest & dirtiest solution is this one:
Range("O2:O" & Cells(Rows.Count, "A").End(xlUp).Row).Copy
or you can isolate the last row as a separate variable:
lastRow = Cells(Rows.Count, "A").End(xlUp).Row
Range("O2:O" & lastRow).Copy
at the end, one may decide to declare the range to be copied as a separate variable and to work with it, declaring the parent worksheet as well:
Public Sub TestMe()
Dim lastRow As Long
Dim ws As Worksheet
Dim rangeToCopy As Range
Set ws = workshetes("Sheet1")
With ws
lastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
Set rangeToCopy = .Range("O2:O" & lastRow)
rangeToCopy.Copy
End With
End Sub
And going really one step further is using a dedicated function for finding the last row per worksheet (GitHub repo here):
Function lastRow(wsName As String, Optional columnToCheck As Long = 1) As Long
Dim ws As Worksheet
Set ws = Worksheets(wsName)
lastRow = ws.Cells(ws.Rows.Count, columnToCheck).End(xlUp).Row
End Function
Upvotes: 3
Reputation: 5687
At some point, your code will have to know the range that's going to be copied, right? You assign that to a variable and you use it.
Option Explicit
Sub Test()
Dim startRow as Long
startRow = 'your method of determining the starting row
Dim startCol as Long
startCol = 'your method of determining the starting column
Dim endRow as Long
endRow = 'your method of determining the ending row (Last used row would work just fine)
Dim endCol as Long
endCol = 'your method of determining the ending column
With Worksheets("Data")
.Range(.Cells(startRow, startCol), .Cells(endRow, endCol)).Copy
End with
End Sub
Upvotes: 2
Reputation: 33692
You should practice to always fully qualify all your Sheet
and Range
objects.
The code below is a little long, but it's good practice to define and set all your objects and variables.
Code
Option Explicit
Sub Test()
Dim Sht As Worksheet
Dim LastRow As Long
' set your worksheet object
Set Sht = ThisWorkbook.Worksheets("Data")
With Sht
' get last row in column A
LastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
' copy dynamic range in column O
.Range("O2:O" & LastRow).Copy
End With
End Sub
Upvotes: 3