CALCULATE函數入門介紹【第一篇】

CALCULATE函數是DAX中唯一可以產生或改變既有filter context的函數,功能強大,觀念較深,一旦搞清楚它,各位於DAX學習之路上將不會有太大的阻礙。

本篇文章將著重說明CALCULATE使用的目的,不會教各位太多語法,因為小編認為,學習函數之前一定要先了解學習的目的是什麼,如此可提升學習的動力及往後學習的效果呢!

前言

CALCULATE函數可說是DAX語言中最重要的函數,因其功能強大、觀念較深,要完全理解它絕對不是一天兩天的事情,但請大家先不要畏懼;於DAX聖經裡,作者也鼓勵大家不要因於CALCULATE函數學習之路上迷失而感到失落,因為就算是有幾年經驗的DAX編碼者,仍會有觀念不夠清楚的狀況,只要多回頭複習幾次,一定會逐日進步。(下圖為DAX聖經:The Definitive Guide to DAX)

20220730_20

小編計劃寫一系列CALCULATE函數的介紹文章,本篇為此系列的第一篇文章,將著重在說明CALCULATE函數的使用目的。

建議對於filter context還不了解的讀者可先參考上一篇文章:DAX語言入門介紹 ,及對樞紐分析觀念不夠清楚的讀者可參考此篇文章:樞紐分析表概念介紹

另外,因為DAX語言於Power BI軟體中語意及函數等功能皆較Excel PowerPivot完整,故此篇及未來的文章小編皆會以Power BI來做講解。

CALCULATE函數使用目的

使用CALCULATE函數的目的簡單來說:為改變、移除或增加報表中的篩選環境(Filter Context,以下稱filter context),其公式組成為:

=CALCULATE( Expression, Filter1, Filter2, ... FilterN)。

上述公式中的Filter1、Filter2...等就是CALCULATE函數內部設定的filter context,藉由這些filter context可以去改變此公式要計算的值(Expresssion);相信讀者光看這段文字敘述還無法了解CALCULATE函數的使用目的,接下來小編將以易懂及實際業界的範例來向各位讀者進行說明。

下圖為本文章使用的資料模型關聯圖。

20230627_P2_1

此模型包含了四個資料表:日曆表('Date')、銷售表('Sales')表、客戶表('Customer')及產品表('Product'),其資料表組成摘要如下:(供參考)

(下圖為日曆表 'Date')

20230627_P4

(下圖為銷售表 'Sales')

20230627_P3_1

(下圖為客戶表 'Customer')

20230627_P5

(下圖為產品表 'Product')

20230627_P6

以下將開始進行範例說明。

範例一:改變filter context

第1個範例的報表如下圖,此報表的filter context為年份及月份,報表的值包含4個量值(Measure,以下稱measure):銷售額、去年銷售額、銷售額比去年及銷售額比去年%,其中:銷售額比去年 = 銷售額 - 去年銷售額,及銷售額比去年% = 銷售額比去年 / 去年銷售額。

各位可以先想一想,哪一個measure改變了報表的filter context

20230627_P1_3

答案是:去年銷售額(Sales PY),原因為:例如當計算2022年1月份的去年銷售額時,其報表的filter context為:

'Date'[Year] = 2022 及'Date'[Month Number for sort] = 1

但實際最後的filter context卻是:

'Date'[Year] = 2021 及'Date'[Month Number for sort] = 1

20230627_P14_1

這就是藉由CALCULATE函數的功能,將filter context往前平移了一年,此measure公式為:

Sales PY := CALCULATE( [Sales], DATEADD('Date'[Date],-1,YEAR))

其中,DATEADD為時間智慧(Time Intelligence)函數,可以將年、月及日的filter context進行平移,須於CALCULATE函數中使用,未來再進行詳細介紹。

範例二:移除filter context

第2個範例的報表如下圖,此報表的filter context為產品種類(Product Category),報表的值包含3個measure:銷售額、全部銷售額及銷售額占比%,其中:銷售額占比% = 銷售額 / 全部銷售額

各位想一想,哪一個measure移除了報表的filter context呢?

20230627_P7_1

答案是:全部銷售額(AllSales),原因為:原本銷售額應會依報表的filter context也就是產品種類被拆分開來(break down),但此measure卻不受filter context影響,而顯示出合計銷售額的值(325,994)。(如下圖)

20230627_P8

這就是藉由CALCULATE函數的功能,移除了原本報表的filter context,在沒有filter context的情況下,銷售額當然就等於全部的銷售額。此measure公式為:

AllSales := CALCULATE([Sales],ALL('Sales'))
ALL在這邊的功用是移除filter context,未來會再詳細介紹此函數。

另外補充,AllSales measure存在的目的只是為了要計算出measure銷售額占比%,所以一般報表是不會放此measure進去的(純粹教育目的),一般報表會如下圖所示。

20230627_P9

範例三:增加filter context

第3個範例的報表如下圖,此報表的filter context為客戶名稱(Customer Name),報表的值包含2個measure:銷售額及產品1的銷售額。

各位想一想,哪一個measure增加了報表的filter context?

20230627_P10

相信經過兩個範例之後,各位應該知道答案是:產品1的銷售額(Sales Product1),原因為:原本銷售額僅受報表的filter context(客戶名稱)影響,但此measure又增加了一個新的filter context(產品種類="產品1")給它。

此measure公式為:

Sales Product1 := CALCULATE([Sales],'Product'[Product Category]="產品1")
增加filter context的意思是,例如當計算客戶1的值時,filter context就會包含了:
'Customer'[Customer Name]="客戶1" 及 'Product'[Product Category]="產品1"
公式中 'Product'[Product Category]="產品1" 看似為一個條件式,其實它在通過DAX公式引擎後,會自動轉換成FILTER函數喔!以後會再詳細說明。

範例四:改變filter context(進階版)

第4個範例的報表如下圖,此報表的filter context為產品種類(Product Category),報表的值包含3個measure:銷售額、產品1的銷售額(同範例三)及產品1的銷售額V1。

各位想一想,這幾個measure是如何改變報表的filter context呢?

20230627_P11

針對measure(產品1的銷售額)filter context的變化其實很有趣,因此範例CALCULATE公式中設定的filter項目剛好等於報表的filter項目(都是產品種類),而CALCULATE函數的特性是:若公式裡設定的filter項目等於報表的filter項目,則CALCULATE內部的filter context會取代外部報表的filter context,因此各位可以發現產品1~產品7的值都等於產品1的銷售額(48,737)。(如下圖)

20230627_P12

而measure(產品1的銷售額V1)filter context則是上一個measure的變化形,因measure(產品1的銷售額)於報表中,產品1~產品7的值都相同,這種情況是不可能出現於公司報表的(純粹教育目的);以一般人直觀來想,大家會期待產品1的銷售額應該只顯示於產品1的欄位中,其他產品應該要為空白。(如下圖)

20230627_P13

此measure(產品1的銷售額V1)的公式為:

Sales Product1 V1 := CALCULATE([Sales],KEEPFILTERS('Product'[Product Category]="產品1"))
各位可以看到此公式在filter('Product'[Product Category]="產品1")的外面又加了另一函數KEEPFILTERSKEEPFILTERS的功能很特別,如同英文字面上的意思(keep filter),它可以保留報表中原始的filter context,並在此條件下再增加KEEPFILTERS內部的filter context(為一交集關係),例如於產品2的值中,原始的filter context為:產品種類="產品2",而CALCULATE內部的KEEPFILTERS內的filter context為:產品種類="產品1",因此兩個條件沒有交集,故於報表中顯示空白。

總結及補充:

經過上述四個實用的的範例,相信大家看完可以清楚了解CALCULATE函數的使用目的,各位是不是也覺得很有趣呢?

另外補充,CALCULATE函數有一套很明確的使用規則,及針對:

如何利用報表原始的filter context,通過CALCULATE內部的filter context轉變後,產生了新的(最終的)filter context

有一個明確的轉換順序,這些其實就是學習CALCULATE函數過程中最困難的地方,但一旦了解及多加思考、練習,各位一定都可以戰勝它。

套一句DAX聖經作者的話:Have fun with DAX.

延伸閱讀:

這篇文章對您有幫助嗎?

平均評分 5 / 5. 2

We are sorry that this post was not useful for you!

Let us improve this post!

Tell us how we can improve this post?

發表迴響