数组公式语法解析:请求解释指定ARRAYFORMULA公式的功能
解析ARRAYFORMULA公式的功能与实现逻辑
嘿,我来帮你拆解这个看起来有点绕的ARRAYFORMULA——它本质上是在做指定月份下、多列维度的类别批量计数,全程自动处理源数据,不用手动下拉填充。咱们把它拆成一个个模块,一步步捋清楚逻辑:
核心目标
这个公式要实现的是:统计「表单响应数据」中,A2指定月份内,B2:B里的每个预设类别,在D到AU列对应时段/分类列中的出现次数,最后输出一个规整的计数矩阵。
逐个模块拆解
1. 类别匹配层:N(REGEXMATCH(TRANSPOSE('Form Responses 1'!C2:C), B2:B))
TRANSPOSE('Form Responses 1'!C2:C):把表单里的C列(应该是每条记录的标签/类别字段)转成横向数组,这样就能和纵向的B2:B预设类别列表做逐行逐列的交叉匹配。REGEXMATCH(...):逐个检查转置后的C列内容是否包含B列的某个类别,返回一个TRUE/FALSE的二维数组(行是B列的类别,列是表单的每条记录)。- 外层
N():把布尔值转成1/0,方便后续做数值运算(TRUE→1,FALSE→0)。
2. 双重条件过滤层:N(IFERROR( (EOMONTH('Form Responses 1'!B2:B,-1)+1=A2))*IFERROR( LEFT('Form Responses 1'!D2:AU,FIND(" ",'Form Responses 1'!D2:AU)-1))))
这部分是给记录加两个过滤条件,只有同时满足的记录才会被计入统计:
- 条件1:匹配目标月份
EOMONTH('Form Responses 1'!B2:B,-1)+1是计算表单B列日期所在月份的第一天(比如B列是2024-05-15,计算后就是2024-05-01),再和A2的日期(应该是目标月份的第一天)对比,判断这条记录是否属于目标月份,返回TRUE/FALSE。 - 条件2:匹配列维度
LEFT('Form Responses 1'!D2:AU,FIND(" ",'Form Responses 1'!D2:AU)-1)是提取D到AU列每个单元格的「空格前内容」(比如单元格是“上午 9:00”,就提取“上午”),用来匹配G1:AU1的列标题(后面会用这个范围的列数来裁剪结果)。 - 两个
IFERROR():处理单元格为空或没有空格的情况,避免公式报错;相乘是逻辑与——只有两个条件都满足时,结果才是1,否则0;最后N()转成数字数组。
3. 批量计数核心:MMULT(...)
MMULT是矩阵乘法函数,这里用它把「类别匹配矩阵」和「条件过滤矩阵」相乘:
- 第一个参数是「类别匹配矩阵」(行数=B列类别数,列数=表单记录数)
- 第二个参数是「条件过滤矩阵」(行数=表单记录数,列数=D到AU列的列数)
- 相乘后得到一个
[类别数 × 列数]的结果矩阵,每个单元格就是对应类别在对应列、对应月份下的出现次数——本质是对满足条件的记录做批量求和计数。
4. 结果裁剪:ARRAY_CONSTRAIN(..., COUNTA(B2:B), COUNTA(G1:AU1))
把MMULT输出的结果矩阵裁剪成「B列非空类别数行,G1到AU1非空列数列」,确保结果只填充到有有效数据的范围,不会出现多余的空行空列。
5. 自动扩展:最外层ARRAYFORMULA
虽然里面的函数很多已经支持数组运算,但外层套ARRAYFORMULA是确保整个公式能自动扩展到所有有效行/列,只要源数据更新,结果就会自动刷新,不用手动拖拽公式。
整体执行流程
- 先筛选出表单中属于A2指定月份的记录,同时提取D-AU列的前缀内容用于匹配列维度;
- 再检查每条符合月份条件的记录,其C列内容是否包含B列的某个预设类别;
- 通过矩阵乘法批量计算每个类别在对应列的出现次数;
- 最后裁剪结果到有效数据范围,输出规整的计数表。
内容的提问来源于stack exchange,提问作者Hunter Duprey
相关产品推荐
相关产品推荐

