1

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

我需要计算xinV1V2列的数量:

=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第二种情况。问题是:它是如何工作的?有人能给我详细介绍第二个公式吗?

4

1 回答 1

2

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

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

{TRUE,TRUE;TRUE,FALSE;TRUE,FALSE}取一个取决于 if的数组(B2:C4="x")

=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)}在数组上下文中使用gets {=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"&ROW(2:4))))

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

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

于 2015-03-17T10:11:39.043 回答