Excel VBA中如何让WorksheetFunction.Sumif仅对筛选可见单元格求和
实现思路
WorksheetFunction.SumIf 本身没有忽略隐藏单元格的内置参数,你当前的代码已经预先按A列匹配r、第7列匹配指定编码做了筛选,剩余可见行本身就符合SumIf的统计条件,因此不需要再调用SumIf,直接对筛选后的可见单元格求和即可。
修改后的代码
' 提前定义工作表对象,避免反复Select影响稳定性 Dim ShtData As Worksheet, ShtTemplate As Worksheet Set ShtData = ThisWorkbook.Sheets("data") Set ShtTemplate = ThisWorkbook.Sheets("template") ' TOTAL THE QUANTITY, COST AND SALE FOR EACH ADVISOR For Each r In ShtTemplate.Range("T2", ShtTemplate.Range("T" & ShtTemplate.Rows.Count).End(xlUp)) ' 直接操作data工作表,不需要Select With ShtData ' 先取消之前的筛选,避免叠加筛选错误 If .AutoFilterMode Then .AutoFilterMode = False With .Range("$A$1:$I$1") .AutoFilter Field:=1, Criteria1:=r .AutoFilter Field:=7, Criteria1:=Array( _ "5741", "WW16K", "WW36K", "WW96K", "WW27K", "WW12K", "8056"), Operator:=xlFilterValues End With ' 错误处理,避免无匹配可见行时Sum报错 On Error Resume Next ' 直接对筛选后B/C/D列的可见行求和,因为已经筛选过A列等于r,不需要再用SumIf r.Offset(, 1) = WorksheetFunction.Sum(.Range("B:B").SpecialCells(xlCellTypeVisible)) r.Offset(, 2) = WorksheetFunction.Sum(.Range("C:C").SpecialCells(xlCellTypeVisible)) r.Offset(, 3) = WorksheetFunction.Sum(.Range("D:D").SpecialCells(xlCellTypeVisible)) On Error GoTo 0 ' 取消当前筛选,准备下一轮循环 .AutoFilterMode = False End With Next r
关键修改说明
- 移除了所有冗余的
Select操作,直接通过工作表对象操作数据,避免选中区域偏移导致的未知错误,运行效率也更高 - 替换原SumIf逻辑:因为你已经通过筛选将A列等于
r、第7列符合编码要求的行设置为可见,直接对可见行求和即可,天然符合原SumIf的统计逻辑,也自动忽略了隐藏行 - 增加了错误处理逻辑:当没有符合筛选条件的可见行时,不会抛出运行时错误,对应统计结果直接为空
- 统一了筛选的开关逻辑,避免原代码末尾筛选取消不彻底的问题
如果你后续遇到不需要预先筛选、需要同时完成条件匹配+忽略隐藏行的场景,可以用SumProduct结合Subtotal的函数组合实现,示例如下:
r.Offset(, 1) = WorksheetFunction.SumProduct((ShtData.Range("A:A") = r) * WorksheetFunction.Subtotal(109, ShtData.Range("B:B")))
该方案灵活性更高,但整列运算的效率低于预筛选后直接求和的方案,可根据自身场景选择。
内容的提问来源于stack exchange,提问作者DavidRood
相关产品推荐
相关产品推荐

