官方说明:
Expression.Evaluate( document as text, optional environment as nullable record) as any
解读:
这是一个神奇的函数,登场率并不高,可能你也是第一次见,甚至连官方说明里都不愿意给上半个字的解释,但是在合适的地方用上它,可能会带来意想不到的惊喜。
在M函数库规范文档中有对该函数的解释:需要一个包含M的表达式并返回运算结果,类似宏表函数中的evaluate。直接上案例:
给一个文本形式的"6+4",直接返回运算结果10:
仅仅是这样吗?上面说的是包含M的表达式,所以你甚至可以给一个包含let in的完整语句:
用它来构建list:
那么也一定可以直接使用函数咯?注意引号的使用,""表示文本,若文本内本身包含引号就要写成两个引号。
结果发现报错了,报的还让人看不懂,这是为什么?正确的写法应该是:
简单来说,就是缺少运算环境。此时需要第二参数,类型为record,也就是说我帮你算没问题,但你得告诉我怎么算,规则在哪?而我们知道输入= #shared
不仅会返回所有函数的函数名还包含函数的语法规则,且类型刚好为record,所以此时该参数就相当于声明允许使用全局函数的表达式。当然你也可以写[Text.ToList=Text.ToList],虽然看上去有点傻。再来看一个:
let a = {1..10}, b = Expression.Evaluate("a{0}",#shared) in b
首先创建一个1到10的list,然后取出list中的第一个值,此时已经加了第二参数,可是发现又报错了:
这是因为该函数只对括号内的环境运算,a是另一个步骤和它没关系,所以它并不知道你这个a是什么鬼,你得指定一个record告诉它。而此时第二参数给的是#shared
,里面并没有a,正确的写法应该是:
那么问题来了,如果是这样呢?
let a = "ABCDEFG", b = Expression.Evaluate("Text.ToList(a)") in b
这时候感觉第二参数写#shared
也不是,写[a=a]也不是,那怎么办?那就两个一起写呗,把两个record合并起来,写成:
案例:
例1:
看到这你应该对该函数的语法有所了解了,但是可能还并不知道怎么用,或者说什么时候用,甚至会感觉有些多余。。。
来看一个题:
根据逗号分隔的数字求和,常规思路如图中的公式,先拆分再求和,但我们既然学了这个不寻常的函数,是不是就该来些不寻常的套路?把逗号替换成加号,直接求和:
例2:
把范围拆成列表,如果按照常规的套路一个个提取你肯定得发狂,而使用该函数构建list是不是会让你眼前一亮。
= Table.AddColumn(源, "列表", each Expression.Evaluate("{"&Text.Replace([范围],"-","..")&"}"))
例3:
通过时长计算分钟数,如果按照常规套路得写很长,而这个就很巧妙。先把"分钟"去掉,然后把"小时"替换成"*60+",处理成数学表达式运算一步出结果。
= Table.AddColumn(源, "迟到分钟数", each Expression.Evaluate(Text.Replace(Text.BeforeDelimiter([迟到时长],"分钟"),"小时","*60+")))
你可能会问,这个括号里也有函数名但为什么不要加第二参数呢?因为这里的函数只是对文本的嵌套处理而已,并不在引号内没有参与运算,这个要搞清楚。
感觉没看懂,不知道什么时候该加引号,什么时候该写第二参数
第一参数类型是文本,文本外面加引号,文本内是一个独立的运算环境,引用环境外部的步骤或函数等就需要第二参数
这个如果自己研究的话,估计研究到死也研究不出来,还是看大神们研究成果比较好。谢谢。
大神很无私,免费分享知识。佩服。
太感谢大神了,自己都看不懂
太神奇了,大神就是神。
牛~
神奇的函数!我又发现了一篇新大陆!感谢大神指点
大神指点,豁然开朗...
一个字绝
看不懂