变量x加个括号,WPS突然就听话了!到底发生了什么?
上周在微信答疑群里,有位朋友发来一张截图,咨询了一个问题。A列是一长串快递运单号,中间夹杂着若干空行,他想把这些空行快速填上:用其下方第一个非空运单号补齐,也就是所谓的“向上填充”。
他试了网上常见的 Map+Lambda 组合公式,在微软的Excel里跑得稳稳当当,可一放到金山WPS表格里就弹出“公式中有多余的运算数据”,回车键无法完成公式,死活不出结果。折腾了半天,最后他偶然给变量x身上套了个括号(x),公式居然奇迹的恢复正常了。群里顿时炸开了锅:“凭什么加个括号就能救回来?” 这个问题恰好撞上了我今天想聊的主题:为什么要给变量x加上括号?
=TOCOL(A2:A8,1)
Tocol(区域, 1)
将指定区域转换为一列垂直数组,并且忽略所有空单元格。
所以此时我们就将A2:A8这个最完整最全的“原始单号”列区域,同时忽略其中的空值单元格后重新再次转置为了单列。
其实目的就是为了去掉空格,这是利用Tocol函数去空格的一种窍门方法,我们在很多案例中都会借鉴到这种技巧。
=TAKE(TOCOL(A2:A8,1),1)
Take(…, 1)
在这里,Take(数组,1)的意思就是提取上一步Tocol得到的数组中的第一行(即第一个)元素“jd01”
也就是让上面的Take(Tocol(A2:A8,1),1)这个逻辑模型中的A2:A8区域动态缩小,就像下面这样,该区域的起始位置由最初的A2逐渐缩小,而区域的结束位置则保持最后的A8固定不变。缩小变化过程如下:
A2:A8
A3:A8
A4:A8
A5:A8
A6:A8
A7:A8
A8:A8
按照上面的思路,为了让大家看清数据是如何流动的,我们将这个“动态缩小范围”逐步代入Take+Tocol中进行观察学习:
①当遍历到A3时,范围是A3:A8,提取到该范围的第一个非空值 jd01:
=TAKE(TOCOL(A3:A8,1),1)
②当遍历到A4时,范围是A4:A8,提取到该范围的第一个非空值 jd01:
=TAKE(TOCOL(A4:A6,1),1)
③当遍历到A5时,范围是A5:A8,提取到该范围的第一个非空值 sf66:
=TAKE(TOCOL(A5:A8,1),1)
④当遍历到A6时,范围是A6:A8,提取到该范围的第一个非空值 sf66:
=TAKE(TOCOL(A6:A8,1),1)
⑤当遍历到A7时,范围是A7:A8,提取到该范围的第一个非空值 yt88:
=TAKE(TOCOL(A7:A8,1),1)
⑥当遍历到A8时,范围是A8:A8,提取到该范围的第一个非空值 yt88:
=TAKE(TOCOL(A8:A8,1),1)
我们发现,如果能让起初的“A2:A8”范围逐渐动态缩小的话:
A2:A8
A3:A8
A4:A8
A5:A8
A6:A8
A7:A8
A8:A8
我们就能按照Take+Tocol的这个非常经典且巧妙的Excel和WPS数组公式,解决“向上填充空行”的问题。实际上逻辑是向上填充,但实现方式是单列数据跳过空值后截取第一个值的思路。
如下图所示,构造的动态取值结果就是“向上填充空行”的结果:
所以我们可以将“A2:A8”的起始位置用变量x表示。当公式遍历到某个单元格x时,x:A8就构成了一个动态的引用范围:
TAKE(TOCOL(x:A8,1),1)
Lambda(x,Take(Tocol(x:A8,1),1))
=MAP(A2:A8,lambda(x,TAKE(TOCOL(x:A8,1),1)))
map函数是驱动上面lambda工作的关键引擎,它会将第一参数A2:A8遍历区域中的每个值依次传递给变量x进行lambda的自定义(Take+Tocol)的计算,实现向上填充效果。
理论上这样完全没问题,逻辑清晰,找不到任何破绽,但是小编目前使用的金山WPS表格,提示“公式中有多余的运算数据”,导致无法回车键一键出结果。
如果我们单独对变量x加上括号变成(x)后,金山WPS版本下就能一键出结果了:
=MAP(A2:A8,LAMBDA(x,TAKE(TOCOL((x):A8,1),1)))
其实这个弊端只会出现在金山WPS表格中,如果大家使用的是微软的Office Excel,这个公式是完全没问题的。
那么为什么同样一个公式,在WPS表格与微软Excel里会被区别对待呢?
这是Excel与WPS公式引擎在Lambda参数类型处理上的差异导致的,本质是一个“引用保留”的问题。
Map(A2:A8,Lambda(x,…))在遍历时,x保留了单元格引用的属性,即x仍然是一个引用类型,比如$A$2、$A$3等形式。
所以当你写x:A8时:x比如引用的是$A$2,A8是引用$A$8,冒号运算符会把两个引用拼成一个动态范围$A$2:$A$8。Excel的引用引擎原生就支持这种“引用+冒号+引用”的拼接,x:A8符合规则,不需要括号。
Map+Lambda在传参时,把x先求值变成了“值”,而不是保留“引用”。
这时候问题就来了:冒号“:”作为范围运算符,左边期待的是一个引用,但WPS给过来的是个具体值“jd01”。于是WPS的解析器懵了:
“值是不能跟“:A8”拼成范围的啊,你这公式是不是写错了?”
于是抛出了“公式中有多余的运算数据”的错误提示框。
(x)在金山WPS的解析器里触发了一个微妙的行为:括号强制让x回到“引用语义”后重新参与运算,或者说括号改变了优先级,让解析器先把x当成一个独立单元,再去跟“:A8”做范围拼接时,走的是另一套语法路径,避开了“值+冒号+引用”的冲突判断。
所以这里“加括号”的动作绝对不是多此一举,是在金山WPS里给Lambda的形参补引用身份的惯用手法,只是很多人没有细致思考过这个问题。如果公式要在WPS和Excel两家通吃,保留(x)这种写法是最稳的。
(如果您还有其它方面的问题,可后台消息框回复“提问”进行咨询)
学习Excel/你可以不常用/但不能不会用/如果你没有天赋/那就一直重复/当你快到本能反应的时候/你的重复就是别人眼中的天赋/冲破捆绑/展翅翱翔



map遍历scan遍历reduce迭代
pivotby降维byrow函数let函数
pivotby函数groupby函数
makearraymakearray
Excel视频大全①/Excel视频大全②
数据转换大全/Excel大全/正则大全