我有一个物料清单,我想在几列上过滤它,然后计算零件编号列中唯一值的数量。当我更改其他列中的过滤条件时,该计数应该更新。我怎样才能做到这一点?谢谢!
来自MrExcel.com:
=SUM(IF(FREQUENCY(IF(SUBTOTAL(3,OFFSET(A2,ROW(A2:A10)-ROW(A2),,1)),
IF(A2:A10<>"",MATCH("~"&A2:A10,A2:A10&"",0))),ROW(A2:A10)-ROW(A2)+1),1))
Run Code Online (Sandbox Code Playgroud)
该公式假定数据范围为 A2:A10。您需要调整单元格 A2 和区域 A2:A10 的引用以适合您的数据。
这是一个数组公式,必须与输入Control- Shift-Enter组合键。
更仔细地观察表达式,人们会发现它依赖于数组与四个 Excel 函数的结合使用。这些解释如下。出于说明的目的,讨论将集中在以下示例上,单元格 A2:A10 中共有 9 个值,过滤后只有 5 个可见。
1. MATCH("~" & A2:A10, A2:A10 & "", 0)
Run Code Online (Sandbox Code Playgroud)
该MATCH
函数通常用于在另一个值范围内查找值,如果找到该值,则返回找到匹配值的行位置。
当数组同时用作查找值和查找范围时,MATCH
返回一个数组,该数组显示范围中每个值的第一个匹配值(如果有)的行位置。
如果范围包含重复值,则为每个重复值返回相同的行位置。使用示例数据,该MATCH
函数将产生:
MATCH(A2:A10, A2:A10, 0)}
-->MATCH({11, 98, 67, , 37, 67, 98, 56, 67},{11, 98, 67, ,37, 67, 98, 56, 67},0)
--> { 1, 2 , 3, 4, 5, 3, 2, 8, 3}
Run Code Online (Sandbox Code Playgroud)
稍加工作,这个结果可以用来计算每个值在原始数组中出现的次数:例如,注意值 67 的行位置 3 在结果数组中出现了 3 次,对应于该值在输入数组中出现的三次。*
2. SUBTOTAL(3, OFFSET(A2, ROW(A2:A10)-ROW(2),,1)
Run Code Online (Sandbox Code Playgroud)
这个问题的特殊困难在于如何区分过滤列表中出现的值和没有出现的值。SUBTOTAL
应用于范围的函数在其结果中仅包含可见行,但即使作为数组公式输入,也不提供有关其输入范围内的单个单元格是否可见的信息。
但是,OFFSET
此处使用的函数以SUBTOTAL
生成数组结果的形式返回单元格数组。归功于Laurent Longre,此公式为可见单元格生成 1 数组,为隐藏单元格生成 0 数组。
SUBTOTAL(3, OFFSET(A2, ROW(A2:A10) - ROW(A2), , 1))
--> SUBTOTAL(3, OFFSET(A2, {2, 3,..., 10} - {2}, , 1))
--> SUBTOTAL(3, OFFSET(A2, {0, 1,..., 8}, , 1))
--> SUBTOTAL(3, ({A2}, {A3},...,{A9}))
--> {0, 1, 1, 0, 0, 0, 1, 1, 1}
Run Code Online (Sandbox Code Playgroud)
有了这个结果,就可以在任何后续计算中只计算过滤后可见范围内的值。**
3. FREQUENCY(IF(SUBTOTAL(3,OFFSET(...)),IF(A2:A10<>"",MATCH(...))),
ROW(A2:A10)-ROW(A2)+1)
Run Code Online (Sandbox Code Playgroud)
该FREQUENCY
函数接受两个参数,一个数据值数组和一个bin数组,并返回一个数组,该数组显示该范围内有多少个值落在每个 bin 内。例如,如果 bin 范围内的值是 (1.5, 2.5, 3.5),FREQUENCY
将返回小于或等于 1.5、大于 1.5 且小于或等于 2.5 等的数据值的计数。
在公式中,数据数组通过IF语句和SUBTOTAL/OFFSET
andMATCH
表达式的组合来 表示。这真正归结为由这些表达式生成的数组的逐个元素 AND 运算。
SUBTOTAL/OFFSET ARRAY: {0, 1, 1, 0, 0, 0, 1, 1, 1} [visible vs. hidden]
MATCH ARRAY: {1, 2, 3, F, 5, 3, 2, 8, 3} [row position of 1st match]
RESULT ARRAY: {F, 2, 3, F, F, F, 2, 8, 3} [row position of 1st match
in visible cells]
'F' = FALSE
Run Code Online (Sandbox Code Playgroud)
表达式生成的 bin 数组ROW(A2:A10)-ROW(A2)+1
只是值 1 到 9,对应于范围 A2:10 中可能的行位置。
BIN ARRAY: {1, 2, 3, 4, 5, 6, 7, 8, 9}
FREQUENCIES: {0, 2, 2, 0, 0, 0, 0, 1, 0}
Run Code Online (Sandbox Code Playgroud)
频率 jibe 与 98 的 2 倍显示在过滤范围内,2 倍 67 显示,1 倍 56 显示。
由于目标是计算过滤范围内不同值的数量,最终封闭IF
- IF(FREQUENCY(...), 1)
- 将频率数组中的非零值转换为 1:
DISTINCT VALUES ARRAY: {F, 1, 1, F, F, F, F, 1, 0}
Run Code Online (Sandbox Code Playgroud)
对这个数组求和,得出这个例子的最终答案 3。
*表达式中的波浪号 (~)MATCH
用于转义诸如 '+' 和 '>' 之类的字符,如果它们是匹配值中的第一个字符,则会产生错误值(因为 Excel 会将它们视为运算符而不是人物)。
**函数的第一个参数SUBTOTAL
值 3 告诉函数返回可见单元格的计数。最常见的值 9 产生可见单元格的总和。
归档时间: |
|
查看次数: |
12358 次 |
最近记录: |