PAYATHON 2026

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 行及之后是否有数据。

备注:内容仅供参考。