この記事はMicrosoft Power BI Advent Calendar 2023に参加しています。
使用しているPower BIは2023/12/20時点の最新バージョンです。
ISINSCOPE
ISINSCOPEは、指定した列がレベルの階層においてそのレベルである場合は True を返します。
読んでも意味が分かりません。
実際にどういう動きをするか見ていきましょう。
検証で利用するデータセット
Power BIの神Takeshi Kagataさんが作成したサンドボックスのデータを利用させていただきました。
ファクトが1つ、ディメンションが4つのスタースキーマです。


ISINSCOPEの検証
ISINSCOPEの動作を検証するために、ディメンションテーブルをISINSCOPEの引数にしてみましょう。
今回利用するPersonsテーブルは社員と所属のIDと、それぞれの表示名で構成されています。

メジャーは以下の通りです。
ISINSCOPE所属 = ISINSCOPE(Persons[所属])
Personsテーブルから所属の列をISINSCOPEの引数とします。
このメジャーをレポートページに置いただけではFalseになります。

スライサーの場合
所属のスライサーをページに追加して大阪支社を選択してみます。
大阪支社が選択されてもメジャーはFalseのままです。

テーブルビジュアルに組み込んだ場合
所属とメジャーを同じテーブルビジュアルに組み込むとTrueになります。
この時、合計欄はFalseです。

次にPersonsテーブルから所属に加えて氏名列もテーブルビジュアルに組み込んでみます。
結果は前と変わりません。

最後にテーブルビジュアルから所属列を消してみます。
全てFalseになりました。

どうやらISINSCOPEの引数にした所属列がカギのようです。
マトリックスビジュアルに組み込んだ場合
マトリックスビジュアルで所属を行に、メジャーを値に組み込むとTrueになります。
この時、合計欄はFalseです。

次にPersonsテーブルから所属に加えて氏名列もマトリックスビジュアルに組み込んでみます。
所属の下の階層に氏名を置きました。

所属と氏名の階層を逆にしてみましょう。
所属が表示されている行以外は全てFalseになりました。

Personsテーブルで所属と氏名が一致しているセルだけTrueになりました。


ISINSCOPEの動き
ここまでの結果では、ISINSCOPEの引数にしたPersonsテーブルの所属列がビジュアルに含まれている場合にだけメジャーがTrueになりました。
今までの結果を踏まえた上で、改めてISINSCOPEの説明を見てみましょう。
ISINSCOPEは、指定した列がレベルの階層においてそのレベルである場合は TRUE を返します。
テーブルビジュアルでは全ての行に所属列が含まれており、合計欄以外はTrueです。

マトリックスビジュアルでは行に階層があり、下の階層は上の階層に含まれます。
つまり所属の下に氏名を置いた場合、氏名は上の階層である所属に含まれるので合計欄以外はTrueです。

逆に氏名を上の階層に置いた場合、所属まで階層を展開しないとTrueが出てきません。

最後に氏名をマトリックスビジュアルの列に置いた場合ですが、これは行の所属と列の氏名によるクロス集計です。
Personsテーブルに存在する所属と氏名の組み合わせはTrueになり、以外はBlankになりました。
そして所属を置いた行の小計は全てTrue、氏名を置いた列と総計欄はFalseです。

これらの結果から「指定した列がレベルの階層においてそのレベルである場合は TRUE を返します」をもう少しかみ砕くと、「ISINSCOPEの引数にした列が含まれた階層またはセルであればTrueを返します」とでも言えるのかなと思います。
何故合計欄は全てFalseなのか
Power BIにおいて、メジャーは基本的に総計で計算されます。

これにDAX式やビジュアルでフィルターをかけることで、ディメンション単位で個々の値を表示することが出来ます。

しかし合計欄はビジュアル内のフィルターから独立しているので、ISINSCOPEの引数にした列から影響を受けることはありません。

クロス集計の行の小計がTrueだったのはISINSCOPEの引数にした列を行に置いたので、行レベルでは引数にした列によるフィルターが有効だったからです。

SUMMARIZECOLUMNSに組み込んだ場合
SUMMARIZECOLUMNSでテーブルを作成する際に、グループ化に使った列をISINSCOPEの引数にしたらどうなるでしょうか?
SUMMARIZECOLUMNSで所属列をグループ化し、所属と氏名をそれぞれISINSCOPEの引数にした列を作成します。
メジャーは以下の通りです。
ISINSCOPEでSUMMARIZECOLUMNSテーブル = SUMMARIZECOLUMNS('Persons'[所属],"ISINSCOPE所属列",ISINSCOPE(Persons[所属]),"ISINSCOPE氏名列",ISINSCOPE(Persons[氏名]))
SUMMARIZECOLUMNSで作成したテーブルにおいても、グループ化に使った列であればISINSCOPEが階層と認識していることが分かります。
まとめ
ISINSCOPEは引数で指定した列を含んだビジュアル、もしくは引数で指定した列でグループ化したSUMMARIZECOLUMNSで動く
引数がcolumnNameなので、条件式と組み合わせて使うことになります。
階層によって挙動が違う
上位に下位は含まれる原則はISINSCOPEでも変わりません。
フィルターの状況に応じて動くDAX関数はISINSCOPEの他にもFILTERS、HASONEFILTER、HASONEVALUE、ISCROSSFILTERED、ISFILTERED等があります。
これらの関数はDAX式がどう動いているかを勉強するのにとても役立つので、是非触ってみてください。
ISFILTEREDについては去年記事を書きましたので興味があればどうぞご覧ください。



