WPS能用MAP和MAKEARRAY,为何嵌套LAMBDA仍不行
WPS能用MAP和MAKEARRAY,为何嵌套LAMBDA仍不行
摘要
同一份订单明细,要按客户横向排出全部订单号,Excel 和新版 WPS 都能用 LET、MAP、MAKEARRAY 写成一条溢出公式。真正拉开兼容性差异的,不是 LAMBDA 这个函数本身,而是让一个 LAMBDA 返回另一个 LAMBDA,再把返回值当函数调用。本文用一张 WPS 实测截图把这两个层次分开,也给出一条 Excel 和 WPS 都能计算的公式。
一、订单要横着排,公式从哪里变复杂了
1.1 一列明细,右侧要变成每客户一行
1.1.1 订单数量并不相同
假设 A2:B8 是一份订单明细。A 列是客户,B 列是订单号:
| 客户 | 订单号 |
|---|---|
| 华东门店 | SO-1001 |
| 华南门店 | SO-1002 |
| 华东门店 | SO-1003 |
| 华北门店 | SO-1004 |
| 华南门店 | SO-1005 |
| 华东门店 | SO-1006 |
| 华北门店 | SO-1007 |
我希望得到的是一张横向清单。华东门店有三张订单,华南和华北各有两张,短的那一行在最后补空白:
| 客户 | 订单1 | 订单2 | 订单3 |
|---|---|---|---|
| 华东门店 | SO-1001 | SO-1003 | SO-1006 |
| 华南门店 | SO-1002 | SO-1005 | |
| 华北门店 | SO-1004 | SO-1007 |
这篇文章接着前一篇关于 MAP 返回数组与 LAMBDA 打包的说明。前文的 packed 写法在 Excel 内部计算可以成立;这次把同一需求放到 WPS 测试,才发现兼容差异不在动态数组函数是否存在,而在 LAMBDA 返回后能否继续被调用。
直接写成 MAP(names,LAMBDA(n,FILTER(orders,customers=n))) 不行。每个客户筛出的订单数不同,MAP 会收到“数组里的数组”,Excel 会报 #CALC!。因此,最终公式必须先决定结果区域有几行、几列,再让每个位置只返回一个订单号。
二、这条公式在 Excel 和 WPS 都能计算
2.1 让 MAKEARRAY 每次只拿一个值
2.1.1 不保存函数,直接按坐标筛选
下面的公式从 A2:B8 读取明细,结果从公式所在单元格向右下方溢出:
=LET(
customers,A2:A8,
orders,B2:B8,
names,UNIQUE(customers),
width,MAX(MAP(names,LAMBDA(n,SUM(–(customers=n))))),
HSTACK(
names,
MAKEARRAY(
ROWS(names),
width,
LAMBDA(
r,c,
IFERROR(INDEX(FILTER(orders,customers=INDEX(names,r)),c),“”)
)
)
)
)
这里的 width 先计算某个客户最多有几张订单。MAKEARRAY 随后逐格工作:r 表示第几个客户,c 表示该客户的第几张订单。FILTER 先得到该客户的纵向订单清单,INDEX(...,c) 只取其中一个值。订单不够时,IFERROR 返回空文本。
我刻意没有在公式里建立 packed 变量,也没有让 LAMBDA 作为中间结果留在数组中。MAKEARRAY 的每次回调都返回标量,最终拼出的只是一个普通的矩形数组。
2.2 WPS 的实测结果
2.2.1 公式编辑器和溢出区域同时给出了结果
下图是在 WPS Office 12.1.0.22529 中输入上面公式的结果。左侧 D:G 已经溢出为三行客户和对应订单,右侧公式编辑器显示的是同一条 LET 公式。

这张图说明 WPS 能识别并计算 LET、UNIQUE、MAP、LAMBDA、FILTER、MAKEARRAY 与 HSTACK,而且这条公式确实返回了预期的 3 行订单清单。
2.3 Excel 的实测结果
2.3.1 同一条公式得到同一张溢出表
Excel 中输入相同公式,D:G 的溢出结果也与 WPS 一致。公式编辑区和结果区域都在同一张图里,订单的排列顺序没有变化。

两张实测图放在一起看,结论就比较明确了:新版 WPS 和 Excel 都支持本文这条“逐格筛选”的 MAKEARRAY 写法。它们的共同点是,LAMBDA 只承担回调,回调的结果始终是单元格值。
三、支持 LAMBDA,不等于支持函数值继续流转
3.1 两种用法看起来只差一层,计算器看到的不是一回事
3.1.1 新公式把 LAMBDA 当作回调
兼容公式里的两个 LAMBDA 都是高阶函数的回调参数:
=MAP(names,LAMBDA(n,SUM(–(customers=n))))
=MAKEARRAY(ROWS(names),width,LAMBDA(r,c, … ))
MAP 把当前客户名交给第一个回调,回调返回一个订单数。MAKEARRAY 把行号和列号交给第二个回调,回调返回一个订单号或空白。它们的返回结果都是普通值,因此 Excel 和上图所示版本的 WPS 都可以把结果组成工作表数组。
原先那条 Excel 专用写法多走了一步。它先让外层 LAMBDA 返回一个尚未执行的内层 LAMBDA:
=MAP(
names,
LAMBDA(n,LAMBDA(TOROW(FILTER(orders,customers=n))))
)
随后再用 INDEX(packed,r,1)() 取出第 r 个函数并调用。Excel 能把这个返回的 LAMBDA 保留在同一条 LET 公式的内部计算过程中,最后由 MAKEARRAY 逐格取值。
3.2 WPS 卡在“返回后再调用”这一步
3.2.1 用一个最小公式就能看出边界
我在同一版本的 WPS 里分别测试了几个公式:
| 公式 | WPS 结果 |
|---|---|
=LAMBDA(x,x+1)(1) |
返回 2 |
=MAP(A2:A8,LAMBDA(n,n)) |
正常溢出 |
本文的 MAKEARRAY 公式 |
正常返回订单清单 |
=LET(f,LAMBDA(x,LAMBDA(x+1)),f(1)()) |
将尾部 () 判为括号使用错误 |
先看 Excel。公式栏显示的是完整的 =LET(f,LAMBDA(x,LAMBDA(x+1)),f(1)()),单元格 I5 的计算结果为 2。这说明 Excel 能先得到内层 LAMBDA(x+1),再执行紧跟在 f(1) 后面的第二组括号。

WPS 对同一条公式的处理不同。它把 f(1)() 中用于调用返回函数的那组空括号提示为“公式中括号使用错误”,并建议改写成没有内层 LAMBDA 的另一条公式。

截图弹窗里的“公式结果:2”对应的是 WPS AI 给出的更正公式 =LET(f,LAMBDA(x,x+1),f(1)),不是原始嵌套公式已经计算成功。原式被判错,正好说明 WPS 没有把 f(1) 的返回结果当作可继续调用的 LAMBDA。
最后一行就是分水岭。外层 LAMBDA 的结果不是数字、文本或数组,而是另一个 LAMBDA;f(1)() 又试图立刻调用这个返回的函数。WPS 12.1.0.22529 不支持这段组合,因此完整的 packed 写法同样无法计算。
所以,问题不能概括成“WPS 不支持 LAMBDA”。=LAMBDA(x,x+1)(1) 已经证明普通的定义和调用没有问题。更准确的说法是:在这次实测的 WPS 版本中,公式引擎不能完成“LAMBDA 返回 LAMBDA,再对返回值加 () 调用”这一层函数值传递。
四、为什么改写后两边都能接受
4.1 函数没有离开自己的调用位置
4.1.1 计算过程始终回到单元格值
兼容公式里,LAMBDA 只出现在 MAP 和 MAKEARRAY 的参数位置。WPS 在执行到回调时马上给它传入 n,或者传入 r 与 c,回调立刻交回数字、文本或空文本。没有任何一个数组元素需要保存为“以后再执行的函数”。
这也是我更愿意把它作为跨 Excel 和 WPS 的默认写法的原因。它没有绕开 #CALC! 的嵌套数组限制,却把原本会成组返回的订单,拆成了目标矩形区域中的单个格子。公式的工作量和结果形状都更直观。
4.2 两个版本都要先识别这些函数
4.2.1 出现 #NAME? 时,先查版本而不是改括号
本文的兼容结论只覆盖能识别 LET、UNIQUE、MAP、LAMBDA、FILTER、MAKEARRAY 和 HSTACK 的 Excel 与 WPS。若输入公式后出现 #NAME?,说明当前版本缺少其中至少一个函数,这时不是把 packed 删除就能解决的问题。
我会先从 =LAMBDA(x,x+1)(1)、=MAP({1,2},LAMBDA(x,x))、=MAKEARRAY(1,1,LAMBDA(r,c,1)) 这类短公式开始检查。哪个函数不识别,就按实际版本升级,或者改用辅助列、透视表等更传统的整理方式。
五、写在最后
5.1 兼容性要看组合,不只看函数清单
5.1.1 同名函数可用,嵌套方式仍可能不同
公式兼容性最容易误判的地方,是看到 WPS 能输入 MAP、LAMBDA 和 MAKEARRAY,便以为 Excel 的组合写法都能照搬。这个订单清单的例子正好相反:函数名都能识别,但“先返回函数,再调用返回值”跨过了 WPS 当前公式引擎的边界。
把筛选动作放回 MAKEARRAY 的逐格回调后,公式不再依赖函数值传递,Excel 和 WPS 都能把它落成同一张订单清单。以后遇到类似的兼容问题,我会先拆出最小公式,确认究竟是哪一层组合失败,再决定是换函数,还是只改返回值的组织方式。
如果你也经常用 Excel 和 VBA 处理表格里的兼容性问题,欢迎关注“VBA爱好者”。
夜雨聆风