COUNTIF有表格过滤,或者SUMPRODUCT / SUBTOTAL / OFFSET组合实际上如何运作?

时间:2015-03-17 09:26:41

标签: filter count excel-formula subtotal walkthrough

给出以下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  |
+---+--------+----+----+

我需要计算xV1列中V2的数量:

=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。我已经找到了如何改进它以便考虑可能的过滤器(这个解决方案可以很容易地在互联网上找到):

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

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

1 个答案:

答案 0 :(得分:2)

首先让我们来看看SUMPRODUCT: SUMPRODUCT期望它的参数为数组(矩阵)。所以

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

{TRUE,TRUE;TRUE,FALSE;TRUE,FALSE}数组,具体取决于(B2:C4="x")

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

将数字上下文中的布尔值作为{1,1;1,0;1,0}。现在,SUMPRODUCT将对此数组进行SUM并得到4。

=SUBTOTAL(3, B2:C4)只会计算B2:C4中的单个单元格是否不可见,因为它已被过滤掉。因此,未经过滤时会得到6,但如果过滤掉则为4,则为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和out filter 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}之外,

的工作方式相同,因为&#34; A&#34;是一个固定的文本字符串,如果要在列A之前插入列,则必须更改公式。

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