(Power BI) DAXの変数


DAXの変数

 DAXで変数を使う場合、以下のような形で書けます。

VAR 変数名 = 
RETURN
    戻り値

 宣言された変数のスコープを閉じるには、RETURNステートメントが必要です。
 RETURNで閉じられるまで、複数の宣言を行うことができます。
 変数は一度だけ割り当てることができ、再割り当てはできません。

変数を使った例
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の値を変えて、正しく計算されているかステップ・バイ・ステップで確認することもできます。

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