
PowerBI 任意の期間での比較機能を実装しよう(前編)
はじめに
レポートユーザが選択した任意の2点間での集計比較が必要な場面ってありませんか?
例えば先月(2023/02)と前年4月(2022/04)の売上を比較して見せたいみたいな感じです。
この記事では任意の2つの年月で値比較ができるような実装例を、スライサーの単一選択を利用して作成していければと思います。
事前準備
今回は年月のディメンションテーブルと、年月ごとのデータを持っているファクトテーブルが欲しいので、下記のサンプルpbixファイルを使用していきます。
データモデルはこんな感じ

売上データを持つSalesテーブル
実装したい理想イメージ
イメージしている要件は下記の通り
異なる2つの年月(yyyy/mm)を選択するために、スライサーを二つ配置する。(基準月と比較月とする)
配置する2つのスライサーはどちらも単一の月を選択し、異なる2期間の売上比較を行う。
追加要件として、比較月では基準月よりも未来の年月を選択できない、かつ基準月では比較月よりも過去の年月を選択できないようにする。
基準月/比較月どちらのスライサーから選択しても3の要件を満たすようにする。

実装前に
今回サンプルのSalesテーブルに日付型の列が無いので追加して作成していきます。(一応追加しなくてもできます)
文字列形式のyyyymmddがあるので、日付に変換します。
yyyymmdd = DATEVALUE(LEFT(Sales[ReportingPeriodID],4) & "/" & MID(Sales[ReportingPeriodID],5,2) & "/" & RIGHT(Sales[ReportingPeriodID],2))

書式は好きなように設定。今回はyyyy/mm/dd
上記追加列と同様Timeテーブルの型も変更しちゃいましょう。
ReportingPeriodID列もTimeテーブルでは整数型なのでテキスト型に変更します。
ReportingPeriodID列はキー項目なんですが、あえて型を合わせていないんでしょうか?(データ型は揃えておいた方がいい気がしますが、、、)

ちなみにですが、データビューから列の型変更を行うと、PowerQuery内に自動で型変更のステップが追加されてしまいます。
そのため、基本的には型変更はデータビューでは行わず、PowerQueryで終わらせるのが良いと思います。
スライサー用テーブルを作成
新規でテーブルを追加します。
Dax式は下記の通り
スライサー用 =
/*基準月用*/
var Base_Table =
CALCULATETABLE(
DISTINCT(
SELECTCOLUMNS(
'Time',
"基準月",
FORMAT([Month],"yyyy/mm")
)
),
'Time'[ReportingPeriodID] in VALUES(Sales[ReportingPeriodID])
)
/*比較月用*/
var Comp_Table =
DISTINCT(
SELECTCOLUMNS(
Sales,
"比較月",
FORMAT([yyyymmdd],"yyyy/mm")
)
)
/*直積を作る*/
var CJ_Table =
CROSSJOIN(Base_Table,Comp_Table)
return
ADDCOLUMNS(
CJ_Table,
"FLG",
IF([基準月] > [比較月], TRUE(), FALSE())
)
コード解説
基準月の中間テーブルを作成するステップでは、CALCULATETABLE関数を使用して、Salesテーブルにある年月だけを対象としています。
これはスライサーで選択した年月がファクトテーブルになく、値がそもそもないから表示されないみたいな事態を防ぐためです。
比較月の中間テーブルでは、事前準備で追加したyyyymmdd列をFORMAT関数を使用して成形しています。
次回予告
今回はスライサー用テーブルの追加まで完了しました。
次回はこのスライサーテーブルを使用して、要件を満たすようビジュアルを実装していこうと思います。
最後までお読みいただき、ありがとうございました。
後編はこちら