Power Apps × DataverseのギャラリーをDropdownで絞り込む|ルックアップ列フィルターの書き方

Dataverse のルックアップ列を Filter 関数の条件にするとき、SharePoint のルックアップ列と同じ書き方をしても動きません。GUID による一致という仕組みを理解すると、詰まることなく実装できます。

Dataverse のルックアップ列をフィルター条件にするときの特殊性

SharePoint のルックアップ列であれば、Filter 関数の条件式に列名と表示名(文字列)の一致を書けば動きます。ところが Dataverse のルックアップ列(リレーション列)は、文字列ではなくレコード型を返します。表示名での比較を試みても一致しないため、絞り込みが機能しません。

この問題でつまずく方は非常に多いです。私自身、SharePoint で慣れた書き方をそのまま使って動かず、しばらく原因がわからなかったことがあります。Dataverse のフィルターは GUID の一致で行う、と最初に知っておくだけで無駄な時間を省けます。

テーブル名.テーブル名 が GUID を返す仕組み

Dataverse のルックアップ列(たとえば 担当者 列がユーザーテーブルを参照している場合)を参照すると、Power Apps はそのリレーション先のレコードを返します。さらにそのレコードに対してリレーション先のテーブル名をドット記法で続けると、プライマリキー(GUID)が返ってきます。

Tasks テーブルに 担当者 というルックアップ列があり、それが Users テーブルを参照している場合、次のように書くと担当者の GUID が取得できます。

ThisItem.担当者.Users

末尾の Users はリレーション先のテーブル名で、これが GUID(一意識別子)を返します。Dataverse の GUID についてはDataverseにIDがない理由|GUIDとは何かで解説しているので、仕組みを先に理解しておくとスムーズです。

Dropdown.Selected.テーブル名 との一致でフィルターする

仕組みを理解したら、実際の Filter 関数を書きます。Dropdown のデータソースを Users テーブルに設定している場合、Dropdown で選択されたレコードの GUID は次のように取得できます。

Dropdown1.Selected.Users

これをギャラリーの Items の Filter 関数に組み込みます。

Filter(
    Tasks,
    担当者.Users = Dropdown1.Selected.Users
)

左辺の 担当者.Users がレコード側の GUID、右辺の Dropdown1.Selected.Users が Dropdown で選択された行の GUID です。同じ型同士の比較になるため、正しく一致判定が行われます。

Dropdown の Items に Users テーブルを設定する

Dropdown の Items プロパティには Users テーブルをそのまま指定します。

Users

画面上は名前が表示されていても、内部では GUID で比較しているのがポイントです。Dropdown の DisplayFields プロパティで表示列を氏名列などに設定すると、ユーザーには名前が見えた状態で GUID フィルターを実現できます。

名前一致ではなく GUID 一致を使う理由

名前(文字列)での一致が使えないのには設計上の理由があります。Dataverse のルックアップ列は、表示名ではなくリレーション先レコードの一意識別子(GUID)で関係を管理しているからです。

たとえば同姓同名の担当者が2人いる場合、名前で比較すると両方がヒットしてしまいます。GUID はレコードごとに必ず異なるため、正確な絞り込みができます。Dataverse がリレーションを GUID で管理している設計上、フィルターも GUID で行うのが唯一の正しいアプローチです。

Filter 関数の基本では SharePoint を前提にした条件式を解説しています。Dataverse を使う場合はこの違いを意識しながら書くようにしてください。

IsBlank と Or で全件表示に対応する

Dropdown で何も選ばれていないとき全件表示に戻す実装も追加しておきましょう。Or と IsBlank を使った全件表示パターンと同じ考え方で書けます。

IsBlank 方式(Allow empty selection)

Dropdown の Allow empty selection をOnにしておくと、未選択時に Dropdown1.Selected.Users が Blank になります。

Filter(
    Tasks,
    IsBlank(Dropdown1.Selected.Users) Or 担当者.Users = Dropdown1.Selected.Users
)

IsBlank が true のとき Or 全体が true になり、全件が返ります。Dataverse を使う場合、All の選択肢を別途追加するより IsBlank 方式の方が型変換の問題が起きにくく、個人的にはこちらをよく使います。

SharePoint のルックアップ列との比較

比較項目SharePoint ルックアップ列Dataverse ルックアップ列
フィルターの比較対象表示名(文字列)でも可GUID(一意識別子)で行う
値の取得方法ThisItem.列名.ValueThisItem.列名.テーブル名
Dropdown の Items 設定Choices 関数・手動リストDataverse テーブルを直接指定
型の扱いテキスト型として扱えるレコード型・GUID 型

SharePoint に慣れた状態で Dataverse を使い始めると、この違いで必ずつまずきます。反対にいえば、GUID での比較という概念さえ理解すれば、その後は迷わず書けます。Dataverse のテーブル設計全体についてはSharePointと違うDataverseのテーブル作成フローでまとめているので、合わせて読んでおくと理解が深まります。

まとめ

Dataverse のルックアップ列フィルターのポイントは、名前ではなく GUID で比較する、という1点に尽きます。ThisItem.列名.テーブル名 と Dropdown1.Selected.テーブル名 を一致させる書き方を覚えれば、どのルックアップ列でも同じパターンで対応できます。

SharePoint から Dataverse に移行するとき、最初のハードルのひとつがこのフィルターの書き方です。仕組みを理解した上で実装すれば、詰まることなく完成まで進めます。楽しみながら開発を進めましょう。

ギャラリーの使い方を一覧でまとめた記事はこちらからご覧ください。

Xでフォローしよう