PowerBI之DAX神功:第1卷第14回 同一表上的多層嵌套上下文EARLIER當前行與VAR變量
EARLIER 函數(shù)提取本行對應的該列的值,實際上就是提取本行和參數(shù)列交叉的單元格。返回:當前行上下文的行值
例如:第2行是當前行,那B列的當前行就是紅色格子

現(xiàn)在我們看一下案例:表名是Shee1

需求:取下一行的銷售日期
下一行日期 = sumx(FILTER('Sheet1','Sheet1'[序號]=EARLIER('Sheet1'[序號])+1),'Sheet1'[銷售日期])?
// 這個知識我們在《火力全開》筆記10.Earlier函數(shù)【當前行】 已經(jīng)詳細講過了
但是,你要區(qū)分:下一行日期與下一個日期的區(qū)別
下一個日期 = nextday('Sheet1'[銷售日期])?
//《火力全開》筆記27.4,下一個日期指的是指定日期的第二天,但是與當前表中日期總數(shù)有關,《火力全開》中做過詳細解釋

很多網(wǎng)友在學習了《火力全開》第10課以后,想不通,為什么這一次的sumx不能寫在度量值里面。
【新建列】下一行日期 = sumx(FILTER('Sheet1','Sheet1'[序號]=EARLIER('Sheet1'[序號])+1),'Sheet1'[銷售日期])?
sumx創(chuàng)建行上下文,它是可以放到度量值中的,但是這里,因為使用了EARLIER函數(shù),由于當前行EARLIER函數(shù)只在行上下文中才有意義,篩選上下文中沒有當前行的概念,所以并不是sumx不能放到度量值中,而是EARLIER函數(shù)不能放到度量值中。
這件事我們先放一放,我們先舉個簡單的例子:

《The Definitive Guide to DAX》書中有這樣一節(jié)課:理解Filter、ALL和上下文交互,這里講的東西,真的是把我整蒙圈了。
例如:有一張表,名字叫Sheet2

計算男生人數(shù),寫一個度量值:
男生人數(shù) = countrows(FILTER('Sheet2','Sheet2'[性別]="男"))
放到矩陣中:

這個時候不顯示李四是正常的,因為李四是女生,我們是通過filter將男生的表篩選出來,對男生的表統(tǒng)計行數(shù),所以這里面沒有李四。
當我使用切片器篩選男同學時:

當我使用切片器篩選女同學時:什么都不顯示了

《The Definitive Guide to DAX》書中的解釋:它有兩個上下文,一個是Filter行上下文的篩選,另一個是外部切片器的篩選上下文。然后就開始不停的飆專業(yè)術語。
我發(fā)現(xiàn)一個問題:
假設,我現(xiàn)在用的尿壺(只是舉例,大多數(shù)人已經(jīng)不用了),我讓你摸,你肯定不摸,你嫌臟。如果我是秦朝的人,兩千年后有一天,你挖坑將我的尿壺挖出來了,可能你會拿它當成寶。你覺得它是古董,我覺得它只是一個舊的尿壺。
同樣的道理,用大白話講出來的東西往往不如用專業(yè)術語講的更高大尚,無論專業(yè)術語你是否能聽懂,似乎就是看專業(yè)術語沒聽懂也覺得自己很牛。我現(xiàn)學現(xiàn)賣,既然大家喜歡聽離生活比較遠的東西,那么講原理時,我盡量少用地球上的事情來講。

塞伯坦星球上面有兩伙變形金剛,分別是霸天虎和汽車人
現(xiàn)在,我只看霸天虎這一部分,相當于是從塞伯坦星球上篩選出霸天虎的成員名單。
接下來,我要在霸天虎的成員名單中找擎天柱和大黃蜂。你說說看:我為什么找不到呢?

女生為什么篩選為空,不就明白了嗎?

現(xiàn)在我們思考幾個問題:
【1】我們想取Sheet2這張表中所有人員的總數(shù):
總?cè)藬?shù)固定值=calculate(countrows('Sheet2'),all('Sheet2'))
【2】我想取Sheet2這張表男生人數(shù)的固定值:
男生人數(shù)1 = Calculate(Countrows(filter('Sheet2','Sheet2'[性別]="男")),all('Sheet2'))
【3】但是上面的公式太啰嗦,它的等效公式:
男生人數(shù)2 = Countrows(FILTER(ALL('Sheet2'),'Sheet2'[性別]="男"))

原理就是推導的過程,有必要知道它是怎么推導出來的,因為:
道生一,一生二,二生三,三生萬物
你理解了道理,就學會了舉一反三,但是在使用中,你不需要所有的事情都從頭推一遍,我們記住了結(jié)果,就可以使用結(jié)果,如果你只背結(jié)果,思維永遠得不到鍛煉,這就是有些人數(shù)學考試中使用公式考出高分,但是參加工作后完全無用武之地的原因。
現(xiàn)在我們回歸正題:如何將表Sheet1的【新建列】寫成【度量值】

【新建列】下一行日期 = sumx(FILTER('Sheet1','Sheet1'[序號]=EARLIER('Sheet1'[序號])+1),'Sheet1'[銷售日期])?

寫成度量值:
【度量值】下一行日期 = sumx(FILTER(all('Sheet1'),'Sheet1'[序號]=SELECTEDVALUE('Sheet1'[序號])+1),'Sheet1'[銷售日期])?
先回憶一下Selectedvalue的作用:

為什么Filter第一參數(shù)要加all?
因為新建列中的sumx是沒有篩選功能的它只是創(chuàng)建行上下文,
但是將sumx放到度量值中就具有了篩選功能
我們現(xiàn)在的度量值,是要體現(xiàn)當前行的作用,所以要取消篩選
剛才我們已經(jīng)通過公式推導了filter+all的演變過程
這是整個的推導過程,也是原理的生成過程。

《The Definitive Guide to DAX》書中將EARLIER當前行函數(shù)說的一無是處,它建議用VAR函數(shù)代替,這個問題我早在2020年6月《孫興華講PowerBI重制篇》中就做了講解。沒有書中說的那么夸張,你想用哪個都可以。
例如:將新建列寫成VAR函數(shù)
【新建列】下一行日期 = sumx(FILTER('Sheet1','Sheet1'[序號]=EARLIER('Sheet1'[序號])+1),'Sheet1'[銷售日期])?
改寫成:
新建列 =?
var x='Sheet1'[序號]
return
sumx(FILTER('Sheet1','Sheet1'[序號]=x+1),'Sheet1'[銷售日期])?

我們使用VAR變量時,就相當于指定了當前行,只是隱藏了當前行函數(shù)而已。
當你將它改寫成度量值時,仍然注意我們提到兩個問題:
filter+all? 與? ?selectedvalue

【度量值】
下一行日期 =?
var x=SELECTEDVALUE('Sheet1'[序號])
return
sumx(FILTER(all('Sheet1'),'Sheet1'[序號]=x+1),'Sheet1'[銷售日期])?

不顯示總計,老規(guī)矩:IF+HASONEVALUE
下一行日期 = var x=SELECTEDVALUE('Sheet1'[序號])
return
if(HASONEVALUE('Sheet1'[序號]),sumx(FILTER(all('Sheet1'),'Sheet1'[序號]=x+1),'Sheet1'[銷售日期]))

《火力全開》筆記10.Earlier函數(shù)【當前行】
我們還有其它3個案例,當時只是用Earlier函數(shù)做了新建列
現(xiàn)在你們可以使用VAR變量做新建列,再利用filter+all 與 SELECTEDVALUE 組合做度量值
