如何修复VBA代码以实现去重并向下填充公式?
VBA宏问题修复方案
问题修复后的完整代码
Public Function GetLastRow(Optional Col As Integer = 1, Optional Sheet As Excel.Worksheet) If Sheet Is Nothing Then Set Sheet = Worksheets("LSMW ZVOL MATERIAL") End If GetLastRow = Sheet.Cells(Sheet.Rows.Count, Col).End(xlUp).Row End Function Sub PricingTransferZVOL() Dim LastRowSum As Long Dim LastRowZVOL As Long Dim wsSum As Worksheet Dim wsZVOL As Worksheet ' 定义工作表对象,简化重复调用 Set wsSum = Worksheets("SUM") Set wsZVOL = Worksheets("LSMW ZVOL MATERIAL") ' 清空目标表旧数据 wsZVOL.Rows("7:" & wsZVOL.Rows.Count).Delete wsZVOL.Range("A4:D6").ClearContents ' 应用筛选规则 Call Removefilters Call ZVOLFilter ' 弹出确认弹窗,用户选择否则终止 If MsgBox("是否继续执行复制、去重及公式填充操作?", vbYesNo + vbQuestion, "确认操作") = vbNo Then Exit Sub End If ' 获取SUM表筛选后的有效数据最后一行 LastRowSum = wsSum.Cells(wsSum.Rows.Count, "AT").End(xlUp).Row ' 仅复制筛选后的可见数据到目标表 wsSum.Range("AT3:AW" & LastRowSum).SpecialCells(xlCellTypeVisible).Copy _ Destination:=wsZVOL.Range("A4") ' 获取目标表新数据的最后一行 LastRowZVOL = GetLastRow(1, wsZVOL) ' 有数据时执行去重 If LastRowZVOL >= 4 Then wsZVOL.Range("A4:D" & LastRowZVOL).RemoveDuplicates Columns:=Array(1, 2, 3, 4), Header:=xlNo End If ' 重新获取去重后的最后一行 LastRowZVOL = GetLastRow(1, wsZVOL) ' 有数据时填充公式 If LastRowZVOL >= 5 Then wsZVOL.Range("E5:AA5").AutoFill _ Destination:=wsZVOL.Range("E5:AA" & LastRowZVOL), _ Type:=xlFillCopy End If End Sub
关键问题修复说明
1. 复制数据时的空行问题
原代码直接复制整个范围,会包含筛选后的隐藏行或空行,改用SpecialCells(xlCellTypeVisible)仅复制可见单元格,彻底避免多余空行;同时删除了不必要的Select操作,直接通过工作表对象操作,提升代码稳定性。
2. 去重及公式填充失效问题
原代码中LastRowZVOL和UsdRw是在复制数据前获取的,此时目标表还没有新数据,导致去重范围和填充范围完全错误。修复后在复制数据完成后重新获取目标表的最后一行,确保操作范围准确;同时增加判断条件,避免无数据时执行操作引发报错。
3. 新增确认弹窗功能
在设置筛选后加入MsgBox弹窗,通过判断用户选择的vbYesNo返回值决定是否继续,选择「否」则直接终止宏执行。
其他优化点
- 定义工作表对象
wsSum和wsZVOL,减少重复调用Worksheets的次数,提升代码可读性和运行效率; - 将变量类型从
Integer改为Long,避免行数超过Integer最大值(32767)时出现溢出错误。
内容的提问来源于stack exchange,提问作者Pom
相关产品推荐
相关产品推荐

