農林漁牧網

您現在的位置是:首頁 > 農業

PowerBI之DAX神功:第1卷第14回 同表多層巢狀上下文EARLIER與VAR

2022-01-03由 孫興華zz 發表于 農業

行與列交叉形成的格子稱為什麼

EARLIER 函式提取本行對應的該列的值,實際上就是提取本行和引數列交叉的單元格。返回:當前行上下文的行值

例如:第2行是當前行,那B列的當前行就是紅色格子

PowerBI之DAX神功:第1卷第14回 同表多層巢狀上下文EARLIER與VAR

現在我們看一下案例:表名是Shee1

PowerBI之DAX神功:第1卷第14回 同表多層巢狀上下文EARLIER與VAR

需求:取下一行的銷售日期

下一行日期 = sumx(FILTER('Sheet1','Sheet1'[序號]=EARLIER('Sheet1'[序號])+1),'Sheet1'[銷售日期])

// 這個知識我們在《火力全開》筆記10.Earlier函式【當前行】 已經詳細講過了

但是,你要區分:下一行日期與下一個日期的區別

下一個日期 = nextday('Sheet1'[銷售日期])

//《火力全開》筆記27.4,下一個日期指的是指定日期的第二天,但是與當前表中日期總數有關,《火力全開》中做過詳細解釋

PowerBI之DAX神功:第1卷第14回 同表多層巢狀上下文EARLIER與VAR

很多網友在學習了《火力全開》第10課以後,想不通,為什麼這一次的sumx不能寫在度量值裡面。

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

sumx建立行上下文,它是可以放到度量值中的,但是這裡,因為使用了EARLIER函式,由於當前行EARLIER函式只在行上下文中才有意義,篩選上下文中沒有當前行的概念,所以並不是sumx不能放到度量值中,而是EARLIER函式不能放到度量值中。

這件事我們先放一放,我們先舉個簡單的例子:

PowerBI之DAX神功:第1卷第14回 同表多層巢狀上下文EARLIER與VAR

《The Definitive Guide to DAX》書中有這樣一節課:理解Filter、ALL和上下文互動,這裡講的東西,真的是把我整蒙圈了。

例如:有一張表,名字叫Sheet2

PowerBI之DAX神功:第1卷第14回 同表多層巢狀上下文EARLIER與VAR

計算男生人數,寫一個度量值:

男生人數 = countrows(FILTER('Sheet2','Sheet2'[性別]="男"))

放到矩陣中:

PowerBI之DAX神功:第1卷第14回 同表多層巢狀上下文EARLIER與VAR

這個時候不顯示王五是正常的,因為王五是女生,我們是透過filter將男生的表篩選出來,對男生的表統計行數,所以這裡面沒有王五。

當我使用切片器篩選男同學時:

PowerBI之DAX神功:第1卷第14回 同表多層巢狀上下文EARLIER與VAR

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

PowerBI之DAX神功:第1卷第14回 同表多層巢狀上下文EARLIER與VAR

《The Definitive Guide to DAX》書中的解釋:它有兩個上下文,一個是Filter行上下文的篩選,另一個是外部切片器的篩選上下文。然後就開始不停地飆專業術語。

我發現一個問題:

假設,我現在用的尿壺(只是舉例,大多數人已經不用了),我讓你摸,你肯定不摸,你嫌髒。如果我是秦朝的人,兩千年後有一天,你挖坑將我的尿壺挖出來了,可能你會拿它當成寶。你覺得它是古董,我覺得它只是一箇舊的尿壺。

同樣的道理,用大白話講出來的東西往往不如用專業術語講得更高大尚,無論專業術語你是否能聽懂,似乎就是看專業術語沒聽懂也覺得自己很牛。我現學現賣,既然大家喜歡聽離生活比較遠的東西,那麼講原理時,我儘量少用地球上的事情來講。

PowerBI之DAX神功:第1卷第14回 同表多層巢狀上下文EARLIER與VAR

塞伯坦星球上面有兩夥變形金剛,分別是霸天虎和汽車人

現在,我只看霸天虎這一部分,相當於是從塞伯坦星球上篩選出霸天虎的成員名單。

接下來,我要在霸天虎的成員名單中找擎天柱和大黃蜂。你說說看:我為什麼找不到呢?

PowerBI之DAX神功:第1卷第14回 同表多層巢狀上下文EARLIER與VAR

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

PowerBI之DAX神功:第1卷第14回 同表多層巢狀上下文EARLIER與VAR

現在我們思考幾個問題:

【1】我們想取Sheet2這張表中所有人員的總數:

總人數固定值=calculate(countrows(‘Sheet2’),all(‘Sheet2’))

【2】我想取Sheet2這張表男生人數的固定值:

男生人數1 = Calculate(Countrows(filter('Sheet2','Sheet2'[性別]="男")),all('Sheet2'))

【3】但是上面的公式太囉嗦,它的等效公式:

男生人數2 = Countrows(FILTER(ALL('Sheet2'),'Sheet2'[性別]="男"))

PowerBI之DAX神功:第1卷第14回 同表多層巢狀上下文EARLIER與VAR

原理就是推導的過程,有必要知道它是怎麼推匯出來的,因為:

道生一,一生二,二生三,三生萬物

你理解了道理,就學會了舉一反三,但是在使用中,你不需要所有的事情都從頭推一遍,我們記住了結果,就可以使用結果,如果你只背結果,思維永遠得不到鍛鍊,這就是有些人數學考試中使用公式考出高分,但是參加工作後完全無用武之地的原因。

現在我們迴歸正題:如何將表Sheet1的【新建列】寫成【度量值】

PowerBI之DAX神功:第1卷第14回 同表多層巢狀上下文EARLIER與VAR

表名:Sheet1

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

PowerBI之DAX神功:第1卷第14回 同表多層巢狀上下文EARLIER與VAR

寫成度量值:

【度量值】下一行日期 = sumx(FILTER(all(‘Sheet1’),‘Sheet1’[序號]=SELECTEDVALUE(‘Sheet1’[序號])+1),‘Sheet1’[銷售日期])

先回憶一下Selectedvalue的作用:

PowerBI之DAX神功:第1卷第14回 同表多層巢狀上下文EARLIER與VAR

為什麼Filter第一引數要加all?

因為新建列中的sumx是沒有篩選功能的它只是建立行上下文,

但是將sumx放到度量值中就具有了篩選功能

我們現在的度量值,是要體現當前行的作用,所以要取消篩選

剛才我們已經透過公式推導了filter+all的演變過程

這是整個的推導過程,也是原理的生成過程。

PowerBI之DAX神功:第1卷第14回 同表多層巢狀上下文EARLIER與VAR

《The Definitive Guide to DAX》書中將EARLIER當前行函式說的一無是處,它建議用VAR函式代替,這個問題我早在2020年6月《孫興華講PowerBI重製篇》中就做了講解。沒有書中說的那麼誇張,你想用哪個都可以。

例如:將新建列寫成VAR函式

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

改寫成:

新建列 =

var x=‘Sheet1’[序號]

return

sumx(FILTER(‘Sheet1’,‘Sheet1’[序號]=x+1),‘Sheet1’[銷售日期])

PowerBI之DAX神功:第1卷第14回 同表多層巢狀上下文EARLIER與VAR

我們使用VAR變數時,就相當於指定了當前行,只是隱藏了當前行函式而已。

當你將它改寫成度量值時,仍然注意我們提到兩個問題:

filter+all 與 selectedvalue

PowerBI之DAX神功:第1卷第14回 同表多層巢狀上下文EARLIER與VAR

【度量值】

下一行日期 =

var x=SELECTEDVALUE(‘Sheet1’[序號])

return

sumx(FILTER(all(‘Sheet1’),‘Sheet1’[序號]=x+1),‘Sheet1’[銷售日期])

PowerBI之DAX神功:第1卷第14回 同表多層巢狀上下文EARLIER與VAR

不顯示總計,老規矩:IF+HASONEVALUE

下一行日期 = var x=SELECTEDVALUE('Sheet1'[序號])

return

if(HASONEVALUE('Sheet1'[序號]),sumx(FILTER(all('Sheet1'),'Sheet1'[序號]=x+1),'Sheet1'[銷售日期]))

PowerBI之DAX神功:第1卷第14回 同表多層巢狀上下文EARLIER與VAR

《火力全開》筆記10。Earlier函式【當前行】

我們還有其它3個案例,當時只是用Earlier函式做了新建列

現在你們可以使用VAR變數做新建列,再利用filter+all 與 SELECTEDVALUE 組合做度量值

《DAX神功》影片版同步在今日頭條和西瓜影片連載

https://www.ixigua.com/6976409163886756383