带有表过滤的 COUNTIF,或者 SUMPRODUCT/SUBTOTAL/OFFSET 组合实际上是如何工作的?

Posted

技术标签:

【中文标题】带有表过滤的 COUNTIF,或者 SUMPRODUCT/SUBTOTAL/OFFSET 组合实际上是如何工作的?【英文标题】:COUNTIF with table filtering, or how does the SUMPRODUCT/SUBTOTAL/OFFSET combination actually work? 【发布时间】:2015-03-17 09:26:41 【问题描述】:

给定以下 Excel 表格:

+---+--------+----+----+
|   | A      | B  | C  |
+---+--------+----+----+
| 1 | Filter | V1 | V2 | <-- header row of the table, with filtering option
+---+--------+----+----+
| 2 | F1     | x  | x  |
| 3 | F2     | x  | y  |
| 4 | F1     | x  | y  |
+---+--------+----+----+

我需要计算V1V2 列中x 的数量:

=COUNTIF(B2:C4, "x")

这有效并返回4。现在,如果我过滤表以使列 Filter 仅包含 F1 值:

+---+--------+----+----+
|   | A      | B  | C  |
+---+--------+----+----+
| 1 | Filter | V1 | V2 | <-- header row of the table, with filtering option
+---+--------+----+----+
| 2 | F1     | x  | x  |
| 4 | F1     | x  | y  |
+---+--------+----+----+.

第一个公式仍然返回4。我已经找到了如何改进它,以便考虑可能的过滤器(这个解决方案可以很容易地在 Internet 上找到):

=SUMPRODUCT((B2:C4="x") * SUBTOTAL(3, OFFSET(B2:C4, ROW(B2:C4) - MIN(ROW(B2:C4)), 0, 1, 1)))

正如预期的那样,对于第二种情况,这将返回 3。问题是:它是如何工作的?有人能给我详细介绍一下第二个公式吗?

【问题讨论】:

【参考方案1】:

首先让我们看一下 SUMPRODUCT: SUMPRODUCT 期望其参数为数组(矩阵)。所以

=SUMPRODUCT((B2:C4="x"))

根据 (B2:C4="x") 是否为 TRUE,TRUE;TRUE,FALSE;TRUE,FALSE 数组。

=SUMPRODUCT((B2:C4="x")*1)

将在数字上下文中获取布尔值1,1;1,0;1,0。现在 SUMPRODUCT 将对这个数组求和并得到 4。

=SUBTOTAL(3, B2:C4) 仅在B2:C4 中的单个单元格因为被过滤掉而不可见时才计数。因此,未过滤时为 6,但例如,如果 F2 被过滤掉,则为 4。

在数组上下文中使用的=OFFSET(B2:C4, ROW(B2:C4) - MIN(ROW(B2:C4)), 0, 1, 1) 得到=OFFSET(B2:C4, 2;3;4 - 2, 0, 1, 1) = =OFFSET(B2:C4, 0;1;2, 0, 1, 1),这需要B2:C4 向下移动0;1;2 行,侧向总是0 列,高度为1,宽度为1,导致B2;B3;B4

所以我们有小计

=SUBTOTAL(3, B2;B3;B4) 只有在B2;B3;B4 未被过滤掉时才算1..

所以过滤掉F2(B3)时SUBTOTAL的结果是:1;0;1

在 SUMPRODUCT 和过滤后的第 3 行中,我们有:

=SUMPRODUCT((B2:C4="x")*1;0;1)

这是TRUE,TRUE;TRUE,FALSE;TRUE,FALSE * 1;0;1 = 1,1;0,0;1,0,总和为 3。


为了简化,我会使用

=SUMPRODUCT((B2:C4="X")*SUBTOTAL(3,INDIRECT("A"&amp;ROW(2:4))))

除了INDIRECT 的结果是A2;A3;A4 之外,它的工作方式相同,并且由于“A”是一个固定的文本字符串,如果要在 A 列之前插入列,则必须更改公式。

OFFSET 变体不需要这样做,因为所有参数都是单元格引用,当插入列时会自动更新。

【讨论】:

感谢您的详细解答。还有一点我不是很清楚:为什么=OFFSET(B2:C4, 0;1;2, 0, 1, 1) 会导致B2;B3;B4?当我们将矩阵作为第一个 OFFSET 参数 (B2:C4) 而不是单个值时会发生什么? 嗯,这不是重点。如果你将B2:C4 向下偏移一排,你会得到B3:C5。但是在使用的 OFFSET 公式中,高度和宽度都是 1。请参阅我在答案中的补充。

以上是关于带有表过滤的 COUNTIF,或者 SUMPRODUCT/SUBTOTAL/OFFSET 组合实际上是如何工作的?的主要内容,如果未能解决你的问题,请参考以下文章

CountIf 和小计

带有反应过滤器的 R 闪亮可编辑表 - 使用表编辑更新过滤器

COUNTIF文本查询在Google工作表中具有偏移量

使用带有条件过滤器的 Include() 连接两个表

带有引导程序的 JavaScript 表过滤器

Power BI DAX CountIF 查询