如何调整宏中记录的 COUNTIF 和 SUMIF 公式以引用整个列内容?

问题描述 投票:0回答:1

我正在为我的团队创建一个小工具来对订单项进行重新定价。我基本上已经完成了所有工作,并认为为他们保存数据摘要以及为他们删除更多的手动工作会很好。

我对 VBA 还很陌生,我仍然使用宏作为拐杖来启动我的代码,然后从那里进行编辑。我发现此时在 VBA 中创建数据透视表超出了我的能力范围,因此只能在宏中创建基本的 SUMIF 和 COUNTIF 公式。它适用于有限的 我有行/列计数,但我希望它是动态的,特别是每个公式引用中的行计数。 列标题始终是静态的,但行会根据我们需要重新评估的发货量而变化。我知道我可以将单元格引用设置为一些非常高的数字,但我担心这会影响性能(如果不会,请告诉我,我会很乐意这样做)。

这就是我现在拥有的。我用于宏的数据集只有 64 行,这将在 SUMIF 和 COUNTIF 公式中得到证明。最后一点:标题为“列总计”的部分可以单独保留,该部分将是静态的,因为它实际上是摘要的输出,并且将

始终

位于这些单元格中。 Sub TestTable() ' ' TestTable Macro ' ' Keyboard Shortcut: Ctrl+t 'Summary Sheet 'Naming Summary Columns Worksheets("Summary").Select Range("B3").Select ActiveCell.FormulaR1C1 = "Mail Class" Range("C3").Select ActiveCell.FormulaR1C1 = "Count of Postage" Range("D3").Select ActiveCell.FormulaR1C1 = "Sum of Postage" Range("E3").Select ActiveCell.FormulaR1C1 = "Sum of Rerate" Range("F3").Select ActiveCell.FormulaR1C1 = "Sum of Difference" 'List unique Mail Classes Worksheets("Summary").Select Range("B4").Select ActiveCell.FormulaR1C1 = _ "Ground Advantage" Range("B5").Select ActiveCell.FormulaR1C1 = _ "Priority" 'Count Unique Mail Classes Range("C4").Select ActiveCell.FormulaR1C1 = _ "=COUNTIF('Test Sheet'!R3C1:R64C1,""Ground Advantage"")" Range("C5").Select ActiveCell.FormulaR1C1 = "=COUNTIF('Test Sheet'!R3C1:R64C1,""Priority"")" Range("C3").Select ' Sum of Postage Range("D4").Select ActiveCell.FormulaR1C1 = _ "=SUMIF('Test Sheet'!R3C1:R64C1,""Ground Advantage"",'Test Sheet'!R3C4:R64C4)" Range("D5").Select ActiveCell.FormulaR1C1 = _ "=SUMIF('Test Sheet'!R3C1:R64C1,""Priority"",'Test Sheet'!R3C4:R64C4)" 'Sum of Rerate Range("E4").Select ActiveCell.FormulaR1C1 = _ "=SUMIF('Test Sheet'!R3C1:R64C1,""Ground Advantage"",'Test Sheet'!R3C5:R64C5)" Range("E5").Select ActiveCell.FormulaR1C1 = _ "=SUMIF('Test Sheet'!R3C1:R64C1,""Priority"",'Test Sheet'!R3C5:R64C5)" 'Sum of Difference Range("F4").Select ActiveCell.FormulaR1C1 = _ "=SUMIF('Test Sheet'!R3C1:R64C1,""Ground Advantage"",'Test Sheet'!R3C6:R64C6)" Range("F5").Select ActiveCell.FormulaR1C1 = _ "=SUMIF('Test Sheet'!R3C1:R64C1,""Priority"",'Test Sheet'!R3C6:R64C6)" 'Column Totals Range("C6").Select ActiveCell.FormulaR1C1 = _ "=SUM('Summary'!R4C3:R5C3)" Range("D6").Select ActiveCell.FormulaR1C1 = _ "=SUM('Summary'!R4C4:R5C4)" Range("E6").Select ActiveCell.FormulaR1C1 = _ "=SUM('Summary'!R4C5:R5C5)" Range("F6").Select ActiveCell.FormulaR1C1 = _ "=SUM('Summary'!R4C6:R5C6)" Range("G6").Select ActiveCell.FormulaR1C1 = _ "Grand Total" 'Formatting Cells and Data type Cells.Select Cells.EntireColumn.AutoFit Range("D4:F6").Select Selection.Style = "Currency" Range("C3").Select End Sub

如果有更好的方法以更干净、动态的方式完成我正在做的事情,我愿意倾听。我一直在阅读 VBA 文档,但由于我的经验有限,我不确定什么可以真正做到这一点。

excel vba
1个回答
0
投票

Range("B3").Select ActiveCell.FormulaR1C1 = "Mail Class"

Range("B3").FormulaR1C1 = "Mail Class"

至于使范围动态化,有很多选择。这里有一些:

桌子

将测试表上的数据制成表格。选择数据并按 Ctrl+T 或功能区上的“插入 - 表格”。然后这些行

Range("C4").Select ActiveCell.FormulaR1C1 = _ "=COUNTIF('Test Sheet'!R3C1:R64C1,""Ground Advantage"")"

假设您将表命名为 tblTest 并且第一列的标题为“类型”,则新公式为

Range("C4").FormulaR1C1 = "=COUNTIF(tblTest[Type],""Ground Advantage"")"

当您在表中添加或删除行时,此引用(称为结构化表引用)始终指向整个表。

既然您将地面优势标签放在 B4 中,那么该公式可能应该是

Range("C4").FormulaR1C1 = "=COUNTIF(tblTest[Type],B4)"

找到最后一行

从最后一行开始,使用 .End 方法向上移动,直到到达包含内容的最后一行。

Dim lLastRow As Long lLastRow = Sheets("Test sheet").Range("A1048576").End(xlUp).Row Range("C4").FormulaR1C1 = "=COUNTIF('Test Sheet'!R3C1:R" & lLastRow & "C1,B4)"

由于公式只是一个字符串,您可以插入找到的最后一行来代替硬编码的 64。

已用范围

工作表有一个UsedRange属性。您可以使用 Intersect 方法将列限制为仅使用的范围部分。当您添加和删除行时,UsedRange 可能会有点不正常。但它永远不会太小,只会太大。由于您只是出于性能原因限制这一点,所以这不会成为问题。

Dim rRange As Range Dim sh As Worksheet Set sh = Sheets("Test Sheet") Set rRange = Intersect(sh.Columns(1), sh.UsedRange) Range("C4").FormulaR1C1 = "=COUNTIF('Test Sheet'!" & rRange.Address(, , xlR1C1) & ",B4)"

如果工作表的UsedRange是A1:K256,那么Intersect命令将返回A1:A256。然后我使用 Address 属性和选项 xlR1C1 参数来构建作为公式的字符串。

在相交中使用整列有点快捷。如果您确实需要从第 3 行开始,您可以将其更改为

Set rRange = Intersect(sh.Range("A3:A1048576"), sh.UsedRange)

	
© www.soinside.com 2019 - 2024. All rights reserved.