VBA代码问题:多工作表数据插入Status工作表时出现覆盖情况
问题分析与解决方案
你的VBA代码出现覆盖问题的核心原因是写入位置未动态更新:初始只计算了一次Status表的非空行数count,循环中始终用这个固定值写入数据,导致每次循环都覆盖同一行;同时Update数据直接写入count+1,也没有跟随已写入的内容动态调整位置。
另外代码里用Sheet1、Sheet4这类索引引用工作表,容易因工作表顺序变化出错,建议改用工作表名称;用公式计算行数的方式也不够稳定,直接用VBA获取最后一行更可靠。
修正后的代码
Sub commit() Dim wsStatus As Worksheet Dim wsCreate As Worksheet Dim wsUpdate As Worksheet Dim wsExtend As Worksheet Dim wsDelete As Worksheet Dim lastRowStatus As Long Dim lastRowCreate As Long Dim lastRowUpdate As Long Dim lastRowExtend As Long Dim lastRowDelete As Long Dim i As Long ' 绑定工作表对象(用名称更可靠) Set wsStatus = ThisWorkbook.Sheets("Status") Set wsCreate = ThisWorkbook.Sheets("Create") Set wsUpdate = ThisWorkbook.Sheets("Update") Set wsExtend = ThisWorkbook.Sheets("Extend") Set wsDelete = ThisWorkbook.Sheets("Delete") ' 获取Status表当前最后一行(A列非空行的下一行) lastRowStatus = wsStatus.Cells(wsStatus.Rows.Count, "A").End(xlUp).Row ' 如果Status表为空,从第2行开始写(假设第1行是表头) If lastRowStatus = 1 And wsStatus.Range("A1").Value = "" Then lastRowStatus = 2 Else lastRowStatus = lastRowStatus + 1 End If ' ===== 处理Create工作表数据 ===== lastRowCreate = wsCreate.Cells(wsCreate.Rows.Count, "E").End(xlUp).Row ' 从第3行开始遍历(对应原代码的b=3) For i = 3 To lastRowCreate ' 写入Create数据到Status表 wsStatus.Range("A" & lastRowStatus).Value = wsCreate.Range("B" & i).Value wsStatus.Range("C" & lastRowStatus).Value = wsCreate.Range("D" & i).Value wsStatus.Range("D" & lastRowStatus).Value = wsCreate.Range("F" & i).Value wsStatus.Range("E" & lastRowStatus).Value = wsCreate.Range("J" & i).Value ' 原代码中Sheet1的F列数据,这里保留原逻辑,建议后续替换为工作表名称 wsStatus.Range("G" & lastRowStatus).Value = ThisWorkbook.Sheets("Sheet1").Range("F" & (WorksheetFunction.CountA(ThisWorkbook.Sheets("Sheet1").Range("F5:F8")) + 3)).Value ' 更新Status表最后一行位置,准备写下一条数据 lastRowStatus = lastRowStatus + 1 Next i ' ===== 处理Update工作表数据 ===== lastRowUpdate = wsUpdate.Cells(wsUpdate.Rows.Count, "E").End(xlUp).Row For i = 3 To lastRowUpdate wsStatus.Range("A" & lastRowStatus).Value = wsUpdate.Range("B" & i).Value ' maintenance request code wsStatus.Range("C" & lastRowStatus).Value = wsUpdate.Range("D" & i).Value ' line number wsStatus.Range("D" & lastRowStatus).Value = wsUpdate.Range("F" & i).Value ' mattype code wsStatus.Range("E" & lastRowStatus).Value = wsUpdate.Range("G" & i).Value lastRowStatus = lastRowStatus + 1 Next i ' ===== 处理Extend工作表数据(可参照Create/Update的逻辑补充)===== lastRowExtend = wsExtend.Cells(wsExtend.Rows.Count, "E").End(xlUp).Row For i = 3 To lastRowExtend ' 这里根据你的需求写入对应列的数据 ' wsStatus.Range("A" & lastRowStatus).Value = wsExtend.Range("XX" & i).Value ' ... lastRowStatus = lastRowStatus + 1 Next i ' ===== 处理Delete工作表数据(可参照Create/Update的逻辑补充)===== lastRowDelete = wsDelete.Cells(wsDelete.Rows.Count, "E").End(xlUp).Row For i = 3 To lastRowDelete ' 这里根据你的需求写入对应列的数据 ' wsStatus.Range("A" & lastRowStatus).Value = wsDelete.Range("XX" & i).Value ' ... lastRowStatus = lastRowStatus + 1 Next i ' 释放对象 Set wsStatus = Nothing Set wsCreate = Nothing Set wsUpdate = Nothing Set wsExtend = Nothing Set wsDelete = Nothing End Sub
关键修改说明
- 动态更新写入位置:每次写入一条数据后,
lastRowStatus自动加1,确保下一条数据写到新行,不会覆盖之前的内容。 - 用工作表名称引用:避免因工作表顺序调整导致的引用错误,代码可读性更强。
- 直接获取最后一行:用
Cells(Rows.Count, 列号).End(xlUp).Row替代公式计算行数,更稳定高效。 - 模块化处理:将每个工作表的处理逻辑分开,便于维护和扩展Extend、Delete的处理代码。
内容的提问来源于stack exchange,提问作者momo
相关产品推荐
相关产品推荐

