VBA 跨工作表复制时 Range 调用报错,如何排查?
数据小陈
结论
当 lastcopyRow >= 2 时,sourceSheet.Range("J2:N" & lastcopyRow) 会生成类似 J2:N500 的有效地址。如果 J 列从第 2 行起没有数据,lastcopyRow 可能为 1,生成的地址就是 J2:N1,Range 调用会失败。检查 lastcopyRow 和最终生成的地址,就能确认是否如此。
原代码中的另一个地址也不正确:Range("A:E" & Rows.Count) 会生成类似 A:E1048576 的字符串,这不是有效范围。即使修好了 sourceRange,代码运行到这一行时仍可能报错。
检查动态范围地址
将行数限定在对应工作表中,并在创建范围前检查行号:
With sourceSheet
lastcopyRow = .Cells(.Rows.Count, "J").End(xlUp).Row
If lastcopyRow < 2 Then
MsgBox "J 列第 2 行以下没有可复制的数据。"
Exit Sub
End If
Set sourceRange = .Range("J2:N" & lastcopyRow)
End With
这里根据 J 列确定末行,适用于提问中 J 列用于标识记录的情况。如果 J 列可能有空缺,但 K
列仍有数据,就需要检查 J 中最后一个有内容的行,否则后续记录可能会遗漏。修正目标区域并复制
下面的代码会查找目标表 A
列中最后一个有内容的单元格,并从下一行开始粘贴,同时保留原代码要求的值和数字格式:Sub UpdateQCLog()
Dim sourceSheet As Worksheet
Dim destinationSheet As Worksheet
Dim sourceRange As Range
Dim lastcopyRow As Long
Dim nextDestinationRow As Long
Dim lastCell As Range
Set sourceSheet = ThisWorkbook.Worksheets("QC Production Live Log Import")
Set destinationSheet = ThisWorkbook.Worksheets("% Yield by Product")
With sourceSheet
lastcopyRow = .Cells(.Rows.Count, "J").End(xlUp).Row
If lastcopyRow < 2 Then
MsgBox "J 列第 2 行以下没有可复制的数据。"
Exit Sub
End If
Set sourceRange = .Range("J2:N" & lastcopyRow)
End With
Set lastCell = destinationSheet.Range("A:E").Find( _
What:="*", _
After:=destinationSheet.Range("A1"), _
LookIn:=xlFormulas, _
LookAt:=xlPart, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False)
If lastCell Is Nothing Then
nextDestinationRow = 1
Else
nextDestinationRow = lastCell.Row + 1
End If
sourceRange.Copy
destinationSheet.Cells(nextDestinationRow, "A").PasteSpecial _
Paste:=xlPasteValuesAndNumberFormats
Application.CutCopyMode = False
End Sub
如果目标表第 1 行是标题且 A
为空,将空表时的nextDestinationRow = 1 改为 2,以免覆盖标题。目标表有其他结构时,也应根据实际数据区域确定首个可写入行。
仍报错时
可以在 Set sourceRange 前临时加入 Debug.Print lastcopyRow, "J2:N" & lastcopyRow,然后运行代码,在 VBA 编辑器的“立即窗口”查看行号和地址。再确认工作表名称与工作簿标签完全一致,并检查 J 列第 2 行及之后是否有数据。
备注:内容仅供参考。
