日前,微软宣布在ExcelInsiderBeta版本中发布了一项新功能LAMBDA。Excel公式是世界上使用最广泛的编程语言,方便快捷的Excel公式也是大家最常用的功能,但是Excel公式的死的无法自定义。如果能在其基础上进行自主定义和编程是一个很大使用场景,现在这个愿望可以达成了,使用LAMBDA可以基于公式实现可自定义可重用函数的能力。
概述
简而言之,LAMBDA允许用户将Excel的公式语言来定义自己的自定义功能。Excel已经允许定义自定义函数,但是只能通过使用完全不同的语言(例如VBA,JavaScript)编写它们。LAMBDA则可以让用户使用Excel自己的公式语言定义自定义函数。还支持在函数中调用其他函数,通过函数调用可以部署的功能不受限制。在很多语言中,有函数式编程的lambda语法,同样的LAMBDA的引入标志着Excel公式语言完成了图灵完备。
使用LAMBDA,可以通过Excel中现有公式,并将其打包为在LAMBDA函数,并重命名命名。然后,就可以在工作表中的任何地方引用该函数,在整个工作表中可以重复使用该自定义函数。
LAMBDA还支持递归。例如,如果创建一个名为MYFUN的LAMBDA,则可以在MYFUN的定义内调用MYFUN。此前,递归功能必须通过脚本来实现。
LAMBDA基础
=LAMBDA包含以下三个关键部分:LAMBDA功能组件,命名lambda和调用lambda函数
LAMBDA功能组件
一个创建基本lambda函数的示例。
假设我们有以下公式:
=LAMBDA(x,x+)
在公式中,x是调用LAMBDA时可以传递的参数,而x+是逻辑。
例如,假设调用了lambda并为x输入值1,则Excel将执行以下计算:
1+
而1+=
命名lambda
如果对LAMBDA命名,就可以实现简单重用,为了达到该目的需要需要使用名称管理器。
可以在功能区中找到名称管理器,方法是:
公式名称管理器
打开名称管理器后,将看到以下窗口
创建一个新条目(New…)并填写相关字段
名称Name:要创建的函数名称
注释Comment:调用函数时将显示说明和相关的提示
Refers引用:lambda函数定义
完成后,单击OK保存该lambda,并且应该在结果窗口中看到返回的定义。
然后就可以通过按其名称调用工作簿中的新创建的自定义函数。
调用LAMBDA
简而言之,调用lambda函数的方式与在Excel中调用本机函数的方式相同。
例如对前面的示例,可以直接调用MYLAMBDA:
=MYLAMBDA()
返回值:
最后要注意的一点是,可以在不命名的情况下调用lambda。如果没有命名前面的公式,而只是在网格中编写它,可以如下调用它:
=LAMBDA(x,x+)(1)
这将为x传递1,并返回
可重用的自定义功能
在Excel中使用公式的更具挑战性的部分之一是经常会使用相当复杂的公式,这些公式在工作表中多次重复使用(通常仅通过复制/粘贴)。这样会使其他人很难阅读和理解其功能,而且更容易出错,进行故障分析和修复也比较困难。使用LAMBDA,可以重复使用并具有可组合性。
假设有一个序号列表,其中位置编码(双字母)在需要中,需要将该值提取出来:
使用Excel函数有很多方法可以做到这一点,比如使用LET公式:
=LEFT(RIGHT(A2,LEN(A2)-FIND(-,A2)),FIND(-,RIGHT(A2,LEN(A2)-FIND(-,A2)))-1)
将公式并将其复制到状态列中,就能自动获得结果。
这种方法有两个问题:
易错误:如果发现需要纠正的逻辑错误,则必须返回并在错误的地方进行更新。此外,每当一遍又一遍地重复复杂的公式(而不是一次定义然后引用)时,都会存在风险。例如,如果有序列号为--WA-73,那么用上述公式就出错。如果发现这样的问题并要修复,则需要对使用该公式的每个单元格都要进行更新。
可组合性/可读性差:如果是使用别人的公式,则很难知道该公式的意图(提取位置)。也不好将该公式和其他公式结合使用,例如,如果想获取到位置并根据结果值进行查找。
使用LAMBDA,可以创建一个名为GETLOCATION的函数,并将公式逻辑放入该函数的定义中。
=LAMBDA(SN,LEFT(RIGHT(SN,LEN(SN)-FIND(-,SN)),FIND(-,RIGHT(SN,LEN(SN)-FIND(-,SN)))-1))
注意,指定了函数要使用的参数(在本例中为SN)以及函数的逻辑。然后在电子表格,可以简单的写的getLocation作为一个公式,和任何其他Excel函数一样。如果发现错误,则将只需修复一个位置,并且使用该功能的所有位置都会自动修复。
另外还可以使用其他逻辑来组合该功能。例如,如果每个位置的税率表,则可以编写此简单公式以根据SN返回税率。
=XLOOKUP(GETLOCATION(B2),table1[locations],table1[tax])
递归
Excel公式中最大的遗漏项之一是缺乏循环功能,以动态定义的间隔重复一组逻辑。可以通过多种方式手动配置Excel重新计算的间隔,以在一定程度上模拟该间隔,但这并不是公式语言所固有的。
假设我有一组字符串,并且我们要指定应该从这些字符串中动态删除哪些字符:
由于指定的字符集不是静态的,因此确实没有任何好的方法。如果是一组固定的字符,则可以通过大量的嵌套逻辑公式来实现,但这将非常复杂并且容易出错。还要考虑如果要删除的字符数大于设想的字符数就会报错失败。
使用LAMBDA,可以创建一个称为REPLACECHARS的函数,该函数引用自身,然后循环调用要删除的字符列表:
=LAMBDA(textString,illegalChars,
IF(illegalChars=,textstring,
REPLACECHARS(
SUBSTITUTE(textString,LEFT(illegalChars,1),),
RIGHT(illegalChars,LEN(illegalChars)-1)
)))
注意,在REPLACECHARS的定义中,有一个对REPLACECHARS的引用。IF语句表明如果没有更多非法字符,则返回输入textString,否则,将每次出现在invalidChars中最左边的字符都删除。递归开始于使用更新的字符串和其余的invalidChars再次调用REPLACECHARS的请求。这样它会一直调用自己,直到对要删除的每个字符进行了解析,从而获得了所需的结果。
不仅是数字和字符串