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

COUNTIF with table filtering, or how does the SUMPRODUCT/SUBTOTAL/OFFSET combination actually work?

给出以下 Excel table:

+---+--------+----+----+
|   | 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")

这有效并且 returns 4。现在,如果我过滤 table 以便列 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  |
+---+--------+----+----+.

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

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

这returns3对于第二种情况,符合预期。问题是:它是如何工作的?谁能给我详细介绍第二个公式?

首先让我们看一下 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

{=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"&ROW(2:4))))

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

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