Power Apps でユーザーフィルターを実装する|SharePoint・Dataverse 別 全パターン解説

Power Appsのビジネスアプリでは、ほぼ必ずユーザーフィルターが必要になります。自分の申請だけ表示したい、自分宛の承認依頼だけ出したい。こうした要件を実現するための実装パターンを、SharePointとDataverseそれぞれで整理します。

ユーザーフィルターが必要な場面

申請管理アプリを作るとき、一覧画面には全員分のデータが表示されます。ところが実際の運用では、自分が出した申請だけを見たい、自分が承認者になっている案件だけを確認したい、という要件がほぼ必ず出てきます。ロールに応じた表示の切り替えは、ビジネスアプリの基本中の基本です。

実装自体はシンプルです。ただし、データソースによって使えるプロパティが違うため、同じ感覚で書くと動かないことがあります。まずSharePoint、次にDataverseの順で順番に整理します。

フィルター式を書く前に列の型を目で確認する

フィルター式を組み立てるときに最初にやるべきことがあります。左辺、つまりデータがどういう型で保存されているかを先に目で確認することです。これをやらずに式を書き始めると、型のミスマッチで動かないまま時間を使うことになります。

確認手順はシンプルです。ギャラリーのItemsに対象のデータソースをそのまま設定して実行し、ラベルコントロールのTextプロパティに ThisItem.'Created By' を入れます。すると画面上に値が表示されます。さらに .Email まで掘ると、メールアドレスの文字列が出てきます。これで左辺がどんな値を持っているかが目視できます。ギャラリーの基本操作が初めての方はそちらを先に確認しておくとスムーズです。

SharePointのユーザーフィルター

Created By のプロパティはどれを使うか

SharePointの Created By 列は、展開するといくつかのプロパティを持っています。Email、Claims、DisplayName、Department などです。どれを使えばいいか悩むところですが、結論から言うとEmailの一択です。

Claimsはi:0#.f|membership|user@domain.comのような形式で値が入っています。組織の設定によって形式が変わることがあり、式の中で扱うのに向いていません。DisplayNameは表示名なので、同姓同名がいる組織では正しくフィルターできません。結果として、SharePointでユーザーフィルターを組むときはEmailに絞って考えるのが現実的です。SharePointのCRUD操作の基礎と合わせて読むと、列の扱いについての理解が深まります。

Filter式の完成形

User()関数は現在ログインしているユーザーの情報を返す関数です。持っているプロパティはEmail、FullName、EntraObjectId、Imageの4つです。SharePointのCreated ByにはEntraObjectIdが存在しないため、EmailとEmailで合わせることになります。

// SharePointのユーザーフィルター
Filter(Employees, 'Created By'.Email = User().Email)

左辺の 'Created By'.Email が SharePoint 側のメールアドレス、右辺の User().Email がログインユーザーのメールアドレスです。同じ型・同じ形式で比較しているので委任も問題ありません。Filter関数はSharePointに委任できるので、件数が多くても全件から正しく絞り込めます。委任の仕組みについては委任とデータの欠落について解説した記事を参照してください。

Emailを使う場合の弱点

Emailを識別子として使う場合、一点だけ覚えておく必要があります。メールアドレスは変わることがあるということです。結婚による改姓、社名変更、M&Aによるドメイン移行など、組織の都合でアドレスが変わるケースは珍しくありません。

アドレスが変わると、変更前に登録されたレコードの Created By.Email と、変更後のUser().Email が一致しなくなります。過去の申請が一覧から消える、という状況が起きます。利用者が少なく、組織変更もほとんどないチームのアプリなら許容範囲です。ただし長期運用を前提にした重要業務のアプリなら、後述するObject IDを使う設計を最初から採用した方がいいです。

DataverseのユーザーフィルターはObject IDを使う

Created ByはUsersテーブルへのルックアップ

DataverseをデータソースにしたときのCreated Byは、SharePointとは構造が違います。DataverseのCreated Byは、Usersテーブルへのルックアップ列です。アプリにDataverseのテーブルを追加すると、Usersテーブルも自動的に追加されます。初めて見ると驚きますが、正常な動作です。Dataverseがリレーションを自動で解決している結果です。

Azure AD Object IDで合わせる

Created Byを展開すると、Azure AD Object IDというフィールドが出てきます。これはEntra Object IDと同一の値です。Azure Active DirectoryがMicrosoft Entraに名称変更された関係で、古い名称が残っています。右辺にはUser().EntraObjectIdを使います。

// DataverseのユーザーフィルターはObject IDで合わせる
Filter(ChewyDoggyData, 'Created By'.'Azure AD Object ID' = User().EntraObjectId)

GUIDと呼ばれる識別子の形式で値が入っています。GUIDについての詳細はDataverseのGUIDとIDの違いを解説した記事にまとめています。

Object IDが最強な理由

Object IDはメールアドレスとは違い、改名しても、ドメインが変わっても、絶対に変わりません。Microsoft Entraが発行する一意のIDであり、ユーザーが組織に存在し続ける限り固定です。SharePointでEmailを使う場合と比べて、データの一貫性が段違いに高くなります。

個人的にも、Dataverseを使う案件では必ずObject IDでフィルターを組むようにしています。Emailで組んで後から直す手間を考えれば、最初から設計を正しくしておく方が圧倒的に楽です。

自前の列に承認者・担当者を保存するときもObject IDで

Created Byではなく、自前で作った列に担当者や承認者を保存するケースもよくあります。このとき、メールアドレスで保存している設計をよく見かけます。上で説明した通り、メールアドレスは変わる可能性があります。最初からEntra Object IDで保存しておくことをすすめます。

フォーム送信時やPatch実行時に、User().EntraObjectIdを一緒に保存しておく実装です。保存の書き方についてはPatch関数で新規レコードを保存する方法を参考にしてください。

// 申請フォーム送信時にObject IDも一緒に保存する例
Patch(
    申請テーブル,
    Defaults(申請テーブル),
    {
        Title: TextInput_title.Text,
        申請者ID: User().EntraObjectId,
        申請者名: User().FullName
    }
)

こうしておけば、後からフィルターするときに Filter(申請テーブル, 申請者ID = User().EntraObjectId) で正確に絞り込めます。アドレス変更の影響を受けない設計が最初から完成します。

パターンの考え方まとめ

ユーザーフィルターを実装するときは、次の手順で考えると迷いません。まずギャラリーで列の値を目視確認して左辺を確定します。次に User() のどのプロパティと型が合うかを確認して右辺を決めます。あとはFilterで等号でつなぐだけです。

データソース左辺右辺注意点
SharePoint'Created By'.EmailUser().Emailアドレス変更リスクあり
Dataverse'Created By'.'Azure AD Object ID'User().EntraObjectId変更に強く長期運用向き
自前列(任意)保存した列名User().EntraObjectId保存時からObject IDで設計する

ハードコード(特定のメールアドレスを直接式に書く)は絶対に避けましょう。ユーザーが変わるたびにアプリを修正することになります。User()関数を使うことで、誰がログインしても正しく動くアプリになります。

まとめ

SharePointならEmail、DataverseならObject ID、自前列でもObject IDが基本です。データソースによって使えるプロパティが違うので、最初に左辺の型を目視確認する習慣をつけておくことが大切です。

ユーザーフィルターは地味ですが、使い勝手に直結する重要な実装です。設計段階から正しい方法で組んでおくと、後から修正する手間が省けます。楽しみながら、丁寧に作っていきましょう。

Xでフォローしよう