在前面一篇文章《》里,我们深入分析了DAX度量公式里“增加筛选条件”的情况:
.销量_产品B =
CALCULATE(
[ ],
FILTER('产品销售表','产品销售表'[产品]="B")
)
今天我们再来深入分析“覆盖筛选条件”的情况,真正搞清楚它的计算过程,以及与增加筛选条件的相同的原理却结果存在较大差异的原因,从而进一步强化对CALCULATE函数的理解!
还是用这份简单数据,即一个产品销售表:
度量如下:
.B_覆盖 =
CALCULATE(
[ ],
'产品销售表'[产品]="B"
)
很多朋友应该都知道它的结果如上图所示,但是否真的完全明白为什么会得到这样的结果,可能就不一定了。
对于初学的朋友来说,一般会直接记住,这种情况就是产品(=B)这个筛选参数会完全覆盖透视表里的产品筛选条件,所以,无论对于哪一个产品,其对应的结果都是B的销量。
数据下载链接:
学习没有用,除非你真的去用!
欢迎加入知识星球【Excel到PowerBI】
看实战视频、做实用练习、提实际问题,用起来!
又或者再深入一点儿,这个度量的公式是下面公式的简写(语法糖):
.B_覆盖原型 =
CALCULATE(
[ ],
FILTER(
ALL('产品销售表'[产品]),
'产品销售表'[产品]="B"
)
)
但是,如果再追问一下:
如果这些问题没有搞清楚,写DAX公式就只能照猫画虎,需求稍有变化,可能就会无所适从了。
下面,我们就用calculate函数的完整计值流——备,拷,转,调,叠,算,还原一下度量[B_覆盖原型]的计算过程,看看和你理解的是否有差别。
第1步:备——准备显式筛选器
这里,在计算“大海/A”的[B_覆盖原型]销量时,虽然filter参数当前的原始上下文是[销售人员]为“大海”,[产品]为“A”,但是,因为filter参数中的第一个参数“ALL(‘产品销售表'[产品])”使用了ALL函数,所以,无论什么情况下,都是产品列的所有内容,如下图所示:
然后,filter函数应用其第二个参数([产品]=”B”)进一步的迭代筛选,因为“ALL(‘产品销售表'[产品])”得到的始终是所有产品,所以经过筛选后,无论外部的筛选器是什么,这里都得到产品为“B”的结果。
注意——
这就是filter参数里使用ALL和不使用ALL的差别!而这项差别是导致最终结果差别的最关键原因。
第2步:拷——拷贝原始上下文
这里的原始上下文即透视表的两项:销售、产品,如在计算“大海/A”的销量时,“销售”筛选器的当前值为“大海”,而“产品”筛选器的当前值为“A”。
第3步:转——将行上下文转换为筛选上下文
这里没有行上下文,所以没有触发这个步骤的相关过程,跳过不用管。
第4步:调——调节器调整上下文的影响行文
这里没有调节器,所以这个步骤也跳过不用管。
第5步:叠——应用第1步结果叠加到第2/3/4步筛选器
到了这里,filter参数得到产品为B的筛选器,再次和透视表的筛选器(即第2步拷贝下来的销售、产品两个筛选器)产生作用。
因为filter参数的筛选器——产品,和从透视表中拷贝下来的产品筛选器一致,所以,会直接“覆盖”掉产品筛选器。
注意,是第1步准备的同名筛选器产品B“覆盖”原来的值,所以结果为B的销量,而不是因为取了“交集”!——如果取了交集,这里就应该为空了!
同时,这里因为只是对产品这个筛选器做了处理,所以,对于拷贝下来的“销售”筛选器则没有任何影响。
大家可以试着将“ ALL(‘产品销售表'[产品])”改为“ ALL(‘产品销售表’)”,然后分析一下这个计算过程和结果,去理解一下ALL(表)和ALL(列)的差别。
第6步:算——基于第5步最后的筛选器计算结果
这一步就只是计算了,根据最后的筛选器结果代入计算即可。
最后,汇总整个计算过程如下图所示:
建议大家按照这个完整过程,分析一下“小勤/C”的计值流。
不好意思,这个文章我又重复了一遍“备,拷,转,调,叠,算”,希望不会让大家觉得烦,我一遍又一遍地重复这6个字,只为让大家看到一个有calculate函数的公式,尤其是当其结果和自己想得不一样时,可以条件反射式地把这6个步骤应用进去。
回想我反反复复对Calculate函数一次又一次感觉学会又不断推翻理解的过程,最后总结出来这6个字,才真正随着对这6个字含义及影响的理解越来越清晰,才得以在面对不同的需要时,自然而然地想到用哪一个字哪一种方式去应对,从而顺利地写出正确的度量公式。
学习是起点,实践是路径,应用是目的,这,也许就是从学、到练、到用——学以致用,活学活用的关键过程吧!
———END———
限 时 特 惠: 本站每日持续更新海量各大最新【内部创业教程】,一年会员只需 98 元,全站资源免费下载 点击查看详情
站 长 微 信: webprojs_com