DAXの変数
DAXで変数を使う場合、以下のような形で書けます。
VAR 変数名 = 式
RETURN
戻り値
宣言された変数のスコープを閉じるには、RETURNステートメントが必要です。
RETURNで閉じられるまで、複数の宣言を行うことができます。
変数は一度だけ割り当てることができ、再割り当てはできません。
Power Queryの評価モデルは遅延評価が適用されるものが多いので、変数は値を保存しているのではなく、中身はオブジェクト(式)です。最終的に計算されるかどうかは、全体の評価の中で決まります。
Measure =
VAR One = 1
RETURN
One // 結果は1になります
Measure =
VAR One = 1
VAR Two = 2
-- VAR One = One + 1 // 再割り当てはエラーになります
RETURN
Tne + Two
変数の設定は、順番が関係あります。
Measure =
VAR One = Two // エラーになります。
VAR Two = 2
RETURN
Tne + Two
Nesting =
VAR One = 0
VAR Num1 = 10
VAR Num2 =
VAR One = One + 1 // 外側の変数はオーバーライドできます
VAR Two = 2
RETURN
One + Two // Num2は3になります。
RETURN
Num1 + Num2 // 結果は13になります
-- Num1 + Num2 + Two // エラーになります。入れ子になった内側の変数は参照できません
-- One // 結果は0になります。内側で変更されても外側に影響を与えません
変数が有効な理由
- 複雑さを軽減
- デバッグが容易
- 読みやすさの向上
- パフォーマンスの向上
DAXは、関数の中で関数を使うような形で表現され、複雑さが上がると、非常に読みにくくなります。変数を使うと、人にも機械にもやさしい表現になることがあります。
以下のメジャーは、次の計算を求めます。
$売り上げ前年比 = \frac{今年の売り上げ - 昨年の売り上げ}{昨年の売り上げ}$
Sales YoY% =
DIVIDE (
SUM ( financials[ Sales] )
- CALCULATE (
SUM ( financials[ Sales] ),
SAMEPERIODLASTYEAR ( financials[Date] )
),
CALCULATE (
SUM ( financials[ Sales] ),
SAMEPERIODLASTYEAR ( financials[Date] )
)
)
Sales YoY% M =
VAR PrevSales =
CALCULATE (
SUM(financials[ Sales]),
SAMEPERIODLASTYEAR ( financials[Date] )
)
RETURN
DIVIDE (
SUM(financials[ Sales]) - PrevSales,
PrevSales
)
計算の中で昨年の売り上げが2回使用されますが、変数を使うと1回の記述で済みます。また、一度計算して変数に入れたものを使えば、複数回同じ処理をせずに済みますので、複雑なメジャーであれば、パフォーマンスも向上します。
変数の名前を見れば、何の値を計算しているか理解しやすく、デバッグもしやすくなります。以下のように、RETURNの値を変えて、正しく計算されているかステップ・バイ・ステップで確認することもできます。
Sales YoY% M =
VAR PrevSales =
CALCULATE (
SUM(financials[ Sales]),
SAMEPERIODLASTYEAR ( financials[Date] )
)
RETURN
PrevSales
-- DIVIDE ( [Sales] - PrevSales, PrevSales )
DAXでは、//、--、**/* */**を使って、コメントアウトすることができます。DAXエディターでは、Ctrl + / で、選択範囲をコメントアウトすることができます。(Power BI Desktop のキーボード ショートカット)
フィルターコンテキスト
フィルターコンテキストに変数を使う場合、注意が必要です。
Pct =
DIVIDE (
SUM ( financials[ Sales] ),
CALCULATE (
SUM ( financials[ Sales] ),
ALLSELECTED ( financials[Product] )
)
)
上記のメジャーを、以下のように書き換えると、正しく動作しません。
Pct =
VAR sales = SUM ( financials[ Sales] )
RETRN
DIVIDE (
SUM ( financials[ Sales] ),
CALCULATE (
sales,
ALLSELECTED ( financials[Product] )
)
)
CALCULATEの第1引数の式は、第2引数のフィルターで評価されますが、変数が使われることで、事前に値が決まってしまい、フィルタが適用されません。
メジャーと計算列の変数
メジャーと計算列では、変数の書き方が変わります。
計算列は、行単位で計算を行いますので、以下のような書き方になります。
Profit CC =
financials[Units Sold] * financials[Sale Price] - financials[Discounts] - financials[COGS]
変数を無理やり使って書き換えてみました。
Profit CC =
VAR GrossSales = financials[Units Sold] * financials[Sale Price]
VAR Sales = GrossSales - financials[Discounts]
VAR Profit = Sales - financials[COGS]
RETURN
Profit
一方、メジャーでは、フィルターコンテキストが働きますので、以下のようになります。
Profit M =
SUMX(
financials,
financials[Units Sold] * financials[Sale Price] - financials[Discounts] - financials[COGS]
)
これを、計算列にならって変数を使って書き換えてみます。
Profit M =
VAR GrossSales =
SUMX ( financials, financials[Units Sold] * financials[Sale Price] )
VAR Sales =
GrossSales - SUM ( financials[Discounts] )
VAR Profit =
Sales - SUM ( financials[COGS] )
RETURN
Profit
以下のような書き方はダメです。
Profit M =
VAR UnitsSold = SUM(financials[Units Sold])
VAR SalePrice = SUM(financials[Sale Price])
VAR GrossSales = UnitsSold * SalePrice
VAR Sales = GrossSales - SUM(financials[Discounts])
VAR Profit = Sales - SUM(financials[COGS])
RETURN
Profit
無理やり感がありますが、関数の中に書くという書き方もできます。
Profit M =
VAR GrossSales =
SUMX(
financials,
VAR UnitsSold = financials[Units Sold]
VAR SalePrice = financials[Sale Price]
RETURN
UnitsSold * SalePrice
)
VAR Sales = GrossSales - SUM(financials[Discounts])
VAR Profit = Sales - SUM(financials[COGS])
RETURN
Profit