基础用法:
在M语言中,标准库函数(standard library functions)约有700个。但是如果你觉得太少了,或者说不好用,那么也可以通过自定义函数来实现自己想要的效果。自定义函数的基本语法为:
函数名=(参数1,参数2,参数3...)=>表达式
先来看个例子:
let get_list = (start as number,end as number)=>{start..end}, result = get_list(1,100) in result
首先定义一个名为"get_list"的自定义函数,需要2个形参:start和end,并且限制类型为number,所以当如果我们传入的实参类型为text等时就会报错。as number可以不写,如果不写默认的类型为any,在M中定义变量类型是非必需的。最右边是函数的表达式,我们构建了一个起止分别为这两个参数的list。参数与表达式之间用=>
隔开,这是固定组合。
然后调用自定义函数,将实参1和100传入函数,表达式变为{1..100},即最后的结果。
如果在变量前加上optional,则声明该参数为可选参数,比如optional end as number
,那么调用该函数的时候这个参数就可省略。
但是在M中并没有默认参数的概念,不能对可选参数指定一个默认值。如果要实现默认参数的效果,可以在=>
后面用if start is null then...else...
的方式判断是否传入了实参,稍微麻烦了一点。
匿名函数:
先看案例:
let select = (x)=>Table.SelectRows(source, each [index] <= x), source = Excel.CurrentWorkbook(){[Name="table"]}[Content], result = Table.AddColumn(source, "acc", each List.Sum(select([index])[index])) in result
定义一个名为"select"的自定义函数,筛选index<=变量的行,然后深化出筛选表的index列,再进行求和,实现根据index累计求和的效果。
那我们就想能不能不多写一个步骤,直接把自定义函数嵌套在里面呢?事实上也是可以的:
let source = Excel.CurrentWorkbook(){[Name="table"]}[Content], result = Table.AddColumn(source, "acc", each List.Sum(Table.SelectRows(source,(x)=>x[index]<=[index])[index])) in result
这么一改,我们依然使用了一个自定义函数,但是并没有给函数命名,所以叫做匿名函数。这个参数x起到了突破上下文的作用,具体请参考《深入理解函数》。
小技巧:
- 如在查询的其中一个步骤中创建自定义函数,调用时函数名为步骤名,此时自定义函数只能供该查询内部调用;
- 如单独将一个查询创建为自定义函数,调用时函数名为查询名,此时自定义函数可供其他所有查询调用;
- 如在步骤之间创建自定义函数,继续添加步骤或调整步骤顺序时比较容易出错,所以建议打开高级编辑器,将自定义函数写作第一个步骤。
练习:
请根据以上介绍的方法,将累计求和的案例改为条件累计求和,即[name]为"a"只累计"a"的。
条件累计求和:
let
source = Excel.CurrentWorkbook(){[Name="table"]}[Content],
result = Table.AddColumn(source, "acc", each List.Sum(Table.SelectRows(source,(x)=>x[index]<=[index] and x[name]=[name])[index]))
in
result
let
select = (x,y)=>Table.SelectRows(Table.SelectRows(source, each [name] = x),each [index]<=y),
source = Excel.CurrentWorkbook(){[Name="Table"]}[Content],
result = Table.AddColumn(source, "acc", each List.Sum(select([name],[index])[index]))
in
result
发现一个问题,一旦Index里有相同的值,结果就不对了
这里只是举个例子,实际如果对表中已有的列累计求和,可以先添加索引列,索引列不会重复的
弱弱地请问一句,如果真的需要累加的值有相同,该如何修改程序,感谢!
能不能为自己的自定义函数添加说明文档和示例?
自定义函数能处理文本不?
当然可以
自定义函数可以跨表使用吗?
老师,在创建自定义函数时,输入参数为字段时,
在自定义函数内部要怎么表示这个字段,
例如,自定义函数包含两个参数,T为表格,R为字段
自定义函数内要怎么表达T表格里的R字段
我写TR不行,T【R】也不行
就像楼上施老师说的一样,先加一个索引列,然后再将条件判断的地方列名称改为[索引]就行了。
请教下,我在A工作簿创建了一个自定义函数,但是想在B工作簿引用这个自定义函数,有没有什么办法
请教下,假如在A表创建了自定函数,想在另一个工作簿B引用自定义函数有什么方法吗