VBA循环复制粘贴报错Run-time error 1004,请求排查解决
我帮你看了下代码,直接导致这个1004错误的原因很明确,不过还有几个潜在问题也得一起修复,不然就算解决了当前错误,后续可能还会出其他问题:
直接触发错误的原因
你在复制粘贴那行的目标Range地址写错了!
原来的代码里:
Workbooks("Testes2").Sheets("Report").Range("A" & first_line_range & "I" & last_line_range)
这里的区域地址缺少了列之间的冒号,Excel无法识别A1I10这种格式的区域,正确的写法应该是"A" & first_line_range & ":I" & last_line_range,也就是在A列和I列之间加上冒号,这样Excel才能理解你要指向的是从A列到I列的连续区域。
其他需要修复的潜在问题
除了上面的语法错误,还有几个地方可能导致后续异常:
变量声明不规范:你的Dim语句里,只有
last_line_range被声明为Integer,其他变量(list_end、last_line等)默认都是Variant类型。虽然VBA会自动处理,但明确声明类型能避免很多隐性问题,比如改成:Dim list_end As Integer, last_line As Integer, h As Integer Dim first_line_range As Integer, last_line_range As Integer Dim sht_qty As Integer获取最后一行的方式有缺陷:
Range("A1").End(xlDown).Row这种写法,如果当前工作表的A列只有A1有数据(比如只有表头),A2是空的,那么End(xlDown)会直接跳到Excel的最后一行(比如1048576),导致你复制一个超大的空区域。建议改用更可靠的方式:last_line = Workbooks("Testes2").Sheets(h).Cells(.Rows.Count, "A").End(xlUp).Row这样会从A列最后一行往上找,准确找到有数据的最后一行。
list_end没有更新:你的list_end初始值是1,但每次复制完数据后没有更新它的值,导致所有工作表的内容都会粘贴到同一个起始位置,直接覆盖之前的数据。你需要在复制语句后加上:
list_end = last_line_range这样下一次循环时,就能从上次粘贴的最后一行的下一行开始。
可以优化代码可读性:用
With语句来简化重复的工作簿/工作表引用,减少代码冗余,也避免拼写错误。
修复后的完整代码
Sub final_data() Dim list_end As Integer, last_line As Integer, h As Integer Dim first_line_range As Integer, last_line_range As Integer Dim sht_qty As Integer list_end = 1 sht_qty = ThisWorkbook.Sheets.Count For h = 1 To sht_qty With ThisWorkbook.Sheets(h) If .Name <> "Report" Then ' 可靠获取当前工作表A列最后一行 last_line = .Cells(.Rows.Count, "A").End(xlUp).Row ' 跳过只有表头的工作表(避免复制空区域) If last_line >= 2 Then first_line_range = list_end + 1 ' 计算目标区域的最后一行:起始行 + 源数据行数(源数据从A2开始,共last_line-1行) last_line_range = list_end + (last_line - 1) ' 修复后的Range地址,添加了冒号 .Range("A2:I" & last_line).Copy Destination:=ThisWorkbook.Sheets("Report").Range("A" & first_line_range & ":I" & last_line_range) ' 更新list_end,为下一次粘贴做准备 list_end = last_line_range End If End If End With Next h End Sub
这个版本的代码应该能解决你的1004错误,同时避免后续可能出现的其他问题,比如覆盖数据、复制空区域等。
内容的提问来源于stack exchange,提问作者SSGrace

