Power Apps アプリを開いた瞬間、画面には「自分の担当分」だけが表示される。
この絞り込みは、Dataverse が裏で3段のクエリをつないで自動実行した結果だ。
ビューの設定が「正しい」のに動かない場合、どこかの段が欠けている。
3段クエリ(バケツリレー)の全体像
Power Apps のモデル駆動型アプリがビューを描画するとき、Dataverse は次の論理的な3段処理を一連のクエリとして実行する。
【第1区間】ログインユーザー → SystemUser テーブルで GUID 特定
↓ (eq-userid 演算子)
【第2区間】担当者マスタ の Lookup 列を逆引き → 所属 GAコード 取得
↓ (FetchXML link-entity による結合)
【第3区間】代理店マスタ のビューフィルターで GAコード一致のレコードだけ通過
↓ (同一テーブル内の Equal 条件)
【表示】ログインユーザーの所属代理店のレコードだけが画面に出る
「バケツリレー」と呼ぶのは、前の段の出力が次の段の入力になるからだ。
ただし、Dataverse は内部でこれをひとつのリクエストとして最適化実行する。順番に3回送信するのではなく、論理的な3段処理として理解しておく。
第1区間:ログインユーザーを SystemUser で特定する
Dataverse はすべての Power Apps ユーザーのアカウント情報を systemuser(SystemUser テーブル)で管理している。Microsoft Learn の公式仕様によると、このテーブルは削除不可の標準システムテーブルで、ログイン名(メールアドレス)を domainname 列として保持する。ユーザーごとに一意の systemuserid(GUID)が割り当てられており、これが以降の処理の照合基準になる。
FetchXML で「現在のユーザーに等しい」を表現するのが eq-userid 演算子だ。
<condition attribute="ownerid" operator="eq-userid" />
value 属性は不要で、Dataverse が呼び出し元ユーザーの GUID を自動的に埋める。OData Web API でも同機能が EqualUserId 関数として提供されている(Microsoft Learn「EqualUserId Function」)。
カスタムテーブルを User or Team owned で作成すると、ownerid(SystemUser / Team への Lookup)列が自動付与される。この列が eq-userid の標準動作列になる(Microsoft Learn「User and team tables」)。
第2区間:担当者マスタの Lookup 列を逆引きして所属 GAコードを取得する
第1区間で特定した GUID をもとに、担当者マスタテーブルの「ユーザー列」を逆引きする。「このユーザーはどの GA(代理店)コードに属しているか」を取り出す区間だ。
FetchXML では link-entity 要素で関連テーブルを結合し、その中で eq-userid 演算子を組み合わせる。
<entity name="agency_master">
<link-entity name="staff_master" from="staff_id" to="staff_lookup" link-type="inner">
<filter>
<condition attribute="user_lookup" operator="eq-userid" />
</filter>
<attribute name="ga_code" />
</link-entity>
</entity>
ここで重要なのが 「ユーザー列の型」 だ。eq-userid は GUID 型(Lookup 型)の列に対してのみ動作する。テキスト型の列に対しては評価できない(Microsoft Learn「Filter rows using FetchXml」2026年3月更新)。
担当者マスタの「誰が担当か」を表す列を systemuser テーブルへの Lookup 型 にしなければならない理由はここにある。テキスト型でメールアドレスを持っていても、eq-userid はその列を評価できない。
UI の制限について(ここは正直に書く)
ビューデザイナーで関連テーブルフィルターを追加する場合(「Add related table」メニュー)、使える演算子は Contains data のみに限定されている。これは公式ドキュメントに明記されている制限だ(Microsoft Learn「Create or edit filters in model-driven app views」)。Equal 等の値比較はできない。
また、カスタム Lookup 列(「担当者」列など)に対して、ビューデザイナー UI の「Equals Current User」条件が表示されないという報告がコミュニティ複数で確認されている(Power Users Community / Community Dynamics)。公式ドキュメントへの明示記載は現時点でない。
つまり、第2区間の逆引きは FetchXML の内部処理レベルで動いているのであり、「ビューデザイナーの UI でそのまま設定できる」という話ではない。UIの操作と FetchXML の内部処理は別レイヤーで動いている、と理解しておく。
第3区間:代理店マスタのビューフィルターで GAコード一致のレコードを絞り込む
第2区間で取得した GAコードを使って、代理店マスタのビューを絞り込む。この区間はビューデザイナーの通常のフィルター行で設定できる。
設定の構造は2行になる。
| フィルター行 | 種別 | 内容 |
|---|---|---|
| 行1 | 関連テーブルフィルター | 担当者マスタへの Lookup 列 → Contains data |
| 行2 | 同一テーブルフィルター | GAコード列 = 第2区間で取得した値(Equal 等) |
「行1」の関連テーブルフィルターで担当者マスタとの紐付けを確認し、「行2」で GAコードの実際の一致条件を設定する。1行のフィルターで全処理を完結させようとすると、Contains data 制限に引っかかる。
ビューデザイナーの設定手順
Microsoft Learn の公式手順をベースにした流れだ(Microsoft Learn「Create or edit filters in model-driven app views」)。
- ビューのフィルタープロパティパネルで「Edit filters」を選択
- 「Add」→「Add related table」で担当者マスタへの Lookup 列を選択
- 演算子は
Contains dataを選択(これ以外は選べない) - 同じフィルターパネルで「Add」→通常のフィルター行を追加
- GAコード列を選択し、Equal 条件で絞り込み値を指定
注記:手順3でカスタム Lookup 列への「Equals Current User」がビューデザイナー UI に表示されない場合、FetchXML を直接編集して eq-userid 条件を組み込む方法が選択肢になる。Dataverse の FetchXML は Power Apps のビュー定義をテキストとして保持しており、ビューのプロパティから XML として取り出して編集できる。
なぜ Lookup 型が必要か——判断軸の整理
テキスト型 vs Lookup 型の選択は、担当者マスタを設計する段階で決まる。
| 列の型 | eq-userid の動作 | ビューフィルターでの絞り込み |
|---|---|---|
| テキスト型(メールアドレス等) | 動作しない | 静的な値との比較のみ可能 |
| Lookup 型(SystemUser 参照) | 動作する | ログインユーザーと動的に照合できる |
Lookup 型にしておくことで、「誰がアクセスしてもその人の担当分だけ表示される」という動的フィルターが成立する。テキスト型のままでは、条件値を手動で更新しない限り、担当者が変わっても絞り込みが追従しない。
ビューデザイナーを使う場合でも、FetchXML を直接書く場合でも、この列型の選択が3段処理の第2区間を成立させるかどうかの唯一の設計条件になる。
動かないときの確認ポイント
設定したのに絞り込みが効かない場合、以下の順で確認する。
| 確認項目 | 確認内容 |
|---|---|
| 担当者マスタのテーブル所有権 | User or Team owned になっているか(Organization owned では ownerid が存在しない) |
| ユーザー列のデータ型 | SystemUser テーブルへの Lookup 型になっているか(テキスト型ではないか) |
| ユーザーの登録状態 | ログインユーザーが担当者マスタに登録されているか(未登録の場合、第2区間が空振りになる) |
| FetchXML の確認 | ビュー定義の FetchXML に eq-userid 演算子が正しく入っているか |
| GAコードの一致 | 担当者マスタの GAコードと代理店マスタの GAコードがテキストとして完全一致しているか(半角・全角、スペースの違い等) |
| ビューフィルターの行構成 | 関連テーブルフィルター(Contains data)と GAコード一致条件が別行になっているか |
「データはあるはずなのに0件になる」という症状は、第2区間でユーザーが見つからないか、第3区間のテキスト一致が不一致になっているケースが多い。
まとめ
Dataverse のビューフィルターは、ログインユーザー特定(eq-userid)→ 担当者マスタ Lookup 逆引き(link-entity)→ 代理店マスタ テキスト一致という3段の論理処理を通じて、「その人の担当分だけ」を自動で表示する。担当者マスタのユーザー列を Lookup 型にしておくことが、この連鎖を成立させる唯一の設計条件だ。
次の一歩:担当者マスタのテーブル設計から始める。ユーザー列のデータ型を確認し、SystemUser テーブルへの Lookup 型になっていなければ作り直すところから手をつける。FetchXML の確認は、ビューのプロパティから XML を取り出して eq-userid が含まれているかを見るだけで済む。
関連記事