PowerQuery学习(持续少量更新)
什么是PowerQuery?
PowerQuery是基于"查询"的数据处理工具,相比传统的Excel工作表函数,PowerQuery效率更高更灵活!
从下图可直观看出PowerQuery工具与工作表函数及VBA之间的学习时间与效益对比:
标题
作者
查看原文
1.巧用Table.FillUp函数
雾伴湾沟
汇集多人填表信息
2.财务中的转换发票问题
雾伴湾沟
批量发票号的处理
3.PowerQuery中的each嵌套
峡山小明
公众号(略)
Each _ 是什么?
我们都知道使用pq转换数据的时候,很多时候都需要用到pq自带的函数做运算,那么在运算时必然有一个"环境"存在,这个环境的作用是约定了当前的运算能操作的是哪些数据?它可能是一个table,也可能是table里的一行,或者是这一行中某一列的值. 我这里用了"环境"这个词,个人感觉这个词是较通俗准确的.有书籍也把这叫为"上下文",应该是引申了dax的叫法,但实在没必要,因为上下文远比这复杂的多. 那么这个环境是怎么确定的呢?答案就是,函数本身确定了环境.
举个例子,新手接触pq时大多数会有一个疑惑,要对table的某列内容进行修改,应当使用的是Table.TransformColumns,但是如果想要根据其他列的内容来修改这一列的内容,用Table.TransformColumns你就不知道如何下手了,请教高手他们都会告诉你,Table.TransformColumns没办法根据其他列来动态更改列内容,必须用其他函数来修改,比如Table.ReplaceValue,然后你就开始去翻Table.ReplaceValue怎么用,但是很长一段时间里,你都不知道为什么Table.TransformColumns不能做到? 实际上,这个问题的根本原因就是,Table.TransformColumns函数确定的数据(环境)就是表格中指定列的当前值,除此以外没有其他,你在这个函数里得不到其他列的值,自然也就没办法根据其他列的值来对指定列做修改. 讲了这么多,我们还是没说清楚each到底是什么. 别急,很快就有答案了.
前面我们说到,环境是由函数本身确定的,那么在函数内部,这个环境的表现形式是什么呢?很多朋友看到这里相信已经呼之欲出了,没错,答案就是传参!
现在我们来看:
List.Transform({1},(x)=>x+1)
x为这个例子中传入的参数,它等于前面的{1},这也就是List.Transform这个函数约定的环境.而这一个语句完全等价于
List.Transform({1},each _+1)
比较看看这两行代码差别在哪里?
没错,终于到了揭开答案的时候了.each到底是什么?答案只有一句话:
each只是一个语法糖,它的本质是(_)=>
如果把(_)=>代入上面的语句,就是:
List.Transform({1},(_)=>_ +1)
可以看到,除了_和x两个字符不同,其他完全一致!
嵌套的each如何分得清楚?
一句代码中可以出现多个each,这很正常.这些each之间的关系有两种,嵌套,或者独立.
独立的each之间彼此互不影响,比如
Table.TransformColumns(table,{{"Column1",each _},{"Column2",each _}})
以上语句中,针对表格的不同列进行处理,每个_都是独立互不影响的.
我们主要的目标是知道嵌套的情况下怎么分清楚?这个问题答案其实不难,但是想用一句话说清楚似乎是不太可能,我尝试总结如下:
1.每个each会向右展开一个属于它的"环境",在当前each语句结束之前出现的每一个each都将取代前一个each形成新的_环境
2.每个_对应的是它左边的第一个each!
3.同一层的_(出现在同一个each之后下一个each出现之前这段区间内的_,我们称它们为同一层)只能代表一个值
以上几点感觉有部分重复,但是为了新手能从更多的角度理解这个问题,就不在意这些细节了.
下面我们举例说明一下
List.Transform({{0,20,30},{20,40,50}},each List.Select(_,each _>25))
我们可以看到上面这个例子中List.Select函数中第一参数跟第二参数都出现了_,但是这两个_代表的是不同的值,按照我前面总结的,想知道每个_代表的是什么,最简单的办法就是往左去找第一个each!所以第一个_左边第一个each是List.Transform的第二参数,因此,它代表的是List.Transform的数据环境,第二个_左边第一个each才是List.Select的数据环境.
为什么要知道怎么分清嵌套的each?
前面我们知道each _可以写成(x)=>x的形式,而嵌套的情况下,如果都使用each的话,不但人为阅读会有障碍,而且还有可能造成内部无法识别.也就是对人,对机器同时是难以理解的,所以在嵌套的情况下,使用(x)=>的形式去写不就可以了吗?为什么还要说这么多内容呢?
没错,这种观点是绝对正确的.本文目的只是帮助新手如何理解嵌套中的each,而不是鼓励大家在实际应用中去使用each嵌套!而正确的认识each的嵌套,一来可以增强对pq的认识,二来可以避免内部识别不良的错误情况(没错,只要遵守前面总结的内容,内部对each是不会识别失误的).
感谢各位阅读!欢迎指正!
ICP备案: 粤ICP备18011712号