上周有位做销售的粉丝咨询了一个问题。问我有没有办法快速算出每个客户的“数量合计”和“金额合计”。他的表格长得很典型:A列客户名用了合并单元格,B列是客户对应的类别,C列区分“数量”和“金额”,D列是对应的数值。他之前试过透视表,但合并单元格一拖进去就变成空行。他想知道能不能用一个公式一步到位,中间过程不用辅助列也不用VBA。我琢磨了一下,发现新版Excel里的Scan、Hstack加上Groupby正好能完美的解决这个问题。既不用拆合并单元格,又能自动把“客户”和“区分”组合成唯一的分组,最后直接按组出汇总结果。说实话,放在几年前,这种“合并单元格+多条件汇总”的需求能把人折腾够呛。最常见的做法就像第一段文字中提到的:先手动取消合并、公式+Ctrl回车逐行填充客户名,再用Sumifs分别算数量和金额,或者干脆插个透视表再手动调整布局,致命缺点是联动性极差,当数据源增删改动数据后,需要反复维护数据源。更别提有些同事连合并单元格都不敢动,怕破坏原表结构了,只能一个个复制粘贴,最后交差的时候还要反复核对,生怕哪个客户的数据串了行。那时候遇到这种问题,基本上就是“能用就行”,没人指望一个公式搞定。
目前很多小伙伴仍然在大力宣扬上面这种老方法,可能是“他也不愿意接触新东西”,或者是“人家本来就认为这是好方法”。我的观点是:爱用啥用啥,用和自己知识储备相匹配的、自己喜欢的方法就是好方法,至于有没有学到新东西,自己心里有杆秤就OK了。其实目前这种局面让我想到另一个感触:很多Excel老手看到合并单元格就浑身难受,恨不得立刻帮对方改成标准的一维表。但你真去提建议,对方可能并不领情:“我这表领导就要这样看”、“合并了才清晰”、“改了格式我后面公式全乱了”。久而久之我们会发现:Excel学习者最大的自律,恰恰是克制自己去纠正别人的欲望。与其纠结对方的表格规不规范,不如想办法在现有结构下把活干完。就像今天这个案例,合并单元格确实不符合统计结构原则,但我们照样能用Scan把它整理成可计算的结构,而不必强迫对方改表。尊重别人的习惯,同时用自己的技术兜底,这才是真正的高效。使用Scan函数:
=SCAN(0,A2:A9,LAMBDA(x,y,IF(y<>"",y,x)))
由于A列的“客户”是合并单元格,导致每个合并单元格内除首个单元格外其余后面的空单元格无法直接作为分组依据。Scan在这里的作用类似于“向下填充”。可以取代以前的“单单元格公式+手动填充”的老方法。Scan函数从上到下遍历A列的每个单元格值,如果遇到非空值(如 a),就记下这个值;如果遇到空值,就延续上一个记下的的值。结果生成一个数组溢出结果 {"a";"a";"b";"b";"b";"b";"a";"a"},让每一行都有了明确的客户归属。第二步:
构建复合维度
=HSTACK(SCAN(0,A2:A9,LAMBDA(x,y,IF(y<>"",y,x))),C2:C9)
Hstack将每个参数的所指代的数组区域横向拼接起来:目的就是让第一步的结果“客户”填充列与C2:C9的“区分”列,两个“1列8行”的数组横向拼接,变成一个“2列8行”的整体结构的大数组。因为后续使用Groupby时,需要知道按什么来分组。这里将“补全后的客户”和“区分(数量/金额)”横向拼接到一起,形成一个“组合式”的“行字段”作为分组依据,实际就是要确定Groupby的第一参数是什么。结果会生成一个两列的数组,作为后续Groupby汇总计算的分组标签。第三步:
执行分组汇总
=GROUPBY(HSTACK(SCAN(0,A2:A9,LAMBDA(x,y,IF(y<>"",y,x))),C2:C9),D2:D9,SUM,0,0)
GROUPBY(第二步的结果, D2:D9, SUM, 0, 0)行标签(行分组依据):上一步Hstack拼合后的“客户”和“区分”数组。聚合值(汇总值):指定D2:D9的数值(值)作为需要计算的原始数据。Groupby会扫描第二步生成的复合“行标签”,自动将相同行标签对应的D列数值进行Sum相加。我们举个例子:将所有标签为(a, 金额)的行数值累加(400+900),得到合计数1300。最后的两个参数“0, 0”表示“没有标头”和“不显示总计行”,这样设置参数后会输出一个最终的干净的汇总表。(如果您还有其它方面的问题,可后台消息框回复“提问”进行咨询)
学习Excel/你可以不常用/但不能不会用/如果你没有天赋/那就一直重复/当你快到本能反应的时候/你的重复就是别人眼中的天赋/冲破捆绑/展翅翱翔