我正在尝试在VBA中做一个副本,作为一个更大的宏的一部分,因此它必须在VBA中,且在特定工作表中的范围未知。
如果我在该工作表中,那么我的代码可以工作:
Sub Copy()
Range("O2", Range("O" & Cells(Rows.Count, "A").End(xlUp).Row)).copy
End Sub()
并且我在以下特定范围内有效:
Sub Test()
Worksheets("Data").Range("O2:O10").Copy
End Sub()
如何使第二个代码不明确地工作。
谢谢
答案 0 :(得分:3)
最简单,最肮脏的解决方案是这个:
Range("O2:O" & Cells(Rows.Count, "A").End(xlUp).Row).Copy
或者您可以将最后一行隔离为单独的变量:
lastRow = Cells(Rows.Count, "A").End(xlUp).Row
Range("O2:O" & lastRow).Copy
最后,可以决定将要复制的范围声明为一个单独的变量并使用它,并声明父工作表:
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
更进一步,实际上是使用专用功能查找每个工作表的最后一行(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
答案 1 :(得分:3)
您应该练习始终完全限定所有Sheet
和Range
对象。
下面的代码有点长,但是定义和设置所有对象和变量是一个好习惯。
代码
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
答案 2 :(得分:2)
在某个时候,您的代码将必须知道将要复制的范围,对吗?您将其分配给变量,然后使用它。
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
答案 3 :(得分:0)
您可以使用一个函数,将“种子”范围传递给该函数,并返回从传递的范围到同一列中最后一个非空单元格的范围,如下所示(注释中的解释)
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
将用于以下用途:
Sub Test()
GetRange(Worksheets("Data").Range("O2")).Copy
End Sub
您可以增强功能并使其处理给定的“最终”行
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
将用于以下用途:
Sub Test()
GetRange(Worksheets("Data").Range("O2"), 2).Copy
End Sub
将“ final”行保留为可选行,该函数可以与否一起使用:
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
答案 4 :(得分:0)
您显然不喜欢使用变量,所以:
Worksheets("Data").Range("O2", Worksheets("Data").Range("O" & Cells(Rows.Count, "A").End(xlUp).Row)).copy
足够了。
通常,更常见的解决方案是使用相交和CurrentRegion:
Application.intersect(Worksheets("Data").Range("O2").CurrentRegion,Worksheets("Data").Range("O2:O999999")).copy