带有 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 |
+---+--------+----+----+
我需要计算 V1
和 V2
列中 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
变体不需要这样做,因为所有参数都是单元格引用,在插入列时会自动更新。
给出以下 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 |
+---+--------+----+----+
我需要计算 V1
和 V2
列中 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
变体不需要这样做,因为所有参数都是单元格引用,在插入列时会自动更新。