はじめに
どうも、ATLのヴィリアスです。
最近 Power BI (DAX) をいじっていると、「スライサーの選択値に応じて、返すテーブルの行を変えたいな~」と思うことがありました。
パッと考えると、「そんなの Switch でスライサーの選択値を見ればいいじゃない」と思いますよね。
思わない?…私がそう思いました。
ところがどっこい、そう簡単には実装させてくれないのが PowerBI (厳密には DAX)。
そこで色々試してみた結果、最終的には想定していた動きを実装できたので、
今後似たようなことで悩む人の参考になれるように記事に残していきます!
やりたいこと
スライサーで選択されている値に応じて、返すテーブルの行を変える!
(そして、返ってきたテーブル内の数値を集計して、メジャーとして扱いたい)
まずは私のアンサー!
※ ここでのスライサーは 1, 2, 3 のいずれかが選択されるとします。
メジャー =
VAR table1 = FILTER(テーブル, SELECTEDVALUE(スライサーの選択値) = 1 [&& 任意のフィルター条件1] …)
VAR table2 = FILTER(テーブル, SELECTEDVALUE(スライサーの選択値) = 2 [&& 任意のフィルター条件2] …)
VAR table3 = FILTER(テーブル, SELECTEDVALUE(スライサーの選択値) = 3 [&& 任意のフィルター条件3] …)
VAR table = UNION(table1, table2, table3)
RETURN SUM(table[集計したい数値を含む列])
ちょっとした解説
FILTER(テーブル, SELECTEDVALUE(スライサーの選択値) = 1 [&& 任意のフィルター条件1] …)
まず FILTER では、条件に合うテーブルの行を取得しています。
条件に合わない (FALSE) 場合、FILTER は 0 行を返します。
これによってスライサーの選択値に応じた、特定のテーブルの行を返すことができます。
(スライサーで 1 が選択されていれば、2, 3 の条件はすべて FALSE (0行) となり、1 のフィルター結果が返ってくる)
SELECTEDVALUE(スライサーの選択値)
SELECTEDVALUE ではスライサーで選択された値を取得しています。
VAR table = UNION(table1, table2, table3)
スライサーの選択値を評価し終えた後は、全テーブルを UNION で結合します。
ここで結合することで、スライサーの選択値がいかなる場合でも 1 つの変数を参照すれば良くなります。
(スライサーの選択値によって、参照する変数を分岐させる必要がなくなる)
(ただ UNION は異なるテーブル間では使えないのがネックですね)
RETURN SUM(table[集計したい数値を含む列])
最後に、私の場合はテーブル内の数値をメジャーとして扱いたかったので、
取得できたテーブルの列に対して集計関数を噛ませています。
なんで Switch を使わない?
Switch を使わないのではなく、"使えない" のです。
ここで、DAX における Switch のドキュメントを見てみましょう。
「戻り値」に注目です。
戻り値
value との一致があった場合、対応する result からのスカラー値が返されます。
そうです。スカラー値 (単一の値) しか返せないんです。
なので、以下みたいな DAX を記述すると Switch の部分でエラーになります。
メジャー =
VAR table = SWITCH(SELECTEDVALUE(スライサーの選択値),
"1", FILTER(テーブル, フィルター条件1),
"2", FILTER(テーブル, フィルター条件2)
"3", FILTER(テーブル, フィルター条件3),
)
RETURN SUM(table[集計したい数値を含む列])
エラー: 複数の列を式で参照しています。複数の列をスカラー値に変換することはできません。
Switch からはスカラー値しか返せないので、
複数の列 (テーブル) が Switch 内の処理結果となってしまうと NG ということです!
おわりに
あくまでもこの記事のやり方は、数ある中の1つのやり方にすぎないと思うので
もしこの記事よりもスマートな方法があれば、ぜひそちらも試してみてください!
それではまた、次の記事で。