Power Pages で挿入フォームと編集フォームを動的に切り替える
はじめに
Power Pages で親テーブルに対して 1 対 1 のリレーションをしたい場合があります。たとえばログイン ユーザーに対して複数のデータを登録させたくないなどのシナリオが該当します。この場合は、データがなければ挿入フォームを表示し、データがあれば編集フォームを表示する、という方法で実現できそうです。しかし、ノーコードでは設定できないため、カスタマイズで実現する必要があります。
実行手順
ログイン ユーザー (取引先担当者) に 1 対 1 で紐づく取引先担当者プロフィールという自己紹介列を含むテーブルを作成します。ログイン ユーザーが自己紹介を記入できるように、動的に挿入フォームと編集フォームを切り替える方法を説明します。
Dataverse
テーブル
取引先担当者の子テーブルとなる 取引先担当者プロフィール を作成します。

自己紹介 列を追加します。

取引先担当者 列を追加します。これは取引先担当者とリレーションを設定します。

フォーム
Power Pages で表示するためのフォームを追加します。

Power Pages
挿入フォーム
挿入フォームを作成します。

保存時にログインユーザーと関連付けをするように設定します。

編集フォーム
編集フォームを作成します。クエリ文字列として id を受け取るようにします。

テーブルのアクセス許可
取引先担当者プロフィール に対するアクセス許可を追加します。アクセス許可の種類 を 取引先担当者アクセス に設定します。これにより自分のレコードのみ参照できるようになります。

ページ
適当なページ (今回は ホーム を編集します) を選択し コードの編集 をクリックします。Visual Studio Code で HTML ファイルを選択します。
{% assign id = request.params["id"] %}
{% if id.size > 0 %}
{% if id == "00000000-0000-0000-0000-000000000000" %}
<div class="row sectionBlockLayout text-left" style="display: flex; flex-wrap: wrap; margin: 0px; min-height: auto; padding: 8px;">
<div class="container" style="padding: 0px; display: flex; flex-wrap: wrap;">
<div class="col-md-12 columnBlockLayout" style="flex-grow: 1; display: flex; flex-direction: column; min-width: 300px;">
{% entityform name: '取引先担当者のプロフィール挿入フォーム' %}
</div>
</div>
</div>
{% else %}
<div class="row sectionBlockLayout text-left" style="display: flex; flex-wrap: wrap; margin: 0px; min-height: auto; padding: 8px;">
<div class="container" style="padding: 0px; display: flex; flex-wrap: wrap;">
<div class="col-md-12 columnBlockLayout" style="flex-grow: 1; display: flex; flex-direction: column; min-width: 300px;">
{% entityform name: '取引先担当者のプロフィール編集フォーム' %}
</div>
</div>
</div>
{% endif %}
{% else %}
{% fetchxml query %}
<fetch mapping="logical">
<entity name="cr818_contactprofile">
<attribute name="cr818_contactprofileid"></attribute>
<link-entity name="contact" to="cr818_contact">
<filter type="and">
<condition attribute="contactid" operator="eq" value="{{ user.id }}"></condition>
</filter>
</link-entity>
</entity>
</fetch>
{% endfetchxml %}
{% if query.results.entities.size > 0 %}
{% assign result = query.results.entities[0] %}
<script type="text/javascript">
window.location = window.location + "?id={{ result.cr818_contactprofileid }}";
</script>
{% else %}
<script type="text/javascript">
window.location = window.location + "?id=00000000-0000-0000-0000-000000000000";
</script>
{% endif %}
{% endif %}
このコードで実施している内容は次の通りです。
- id パラメーターがない場合、FetchXML を使用して現在のログインユーザーに紐づけられているレコードを取得する。ある場合はその ID を、ない場合は
00000000-0000-0000-0000-000000000000を指定してリダイレクトする - id パラメーターがある場合、
00000000-0000-0000-0000-000000000000であれば挿入フォームを、それ以外は編集フォームを表示する
実行結果
データがない状態で表示したときは id=00000000-0000-0000-0000-000000000000 にリダイレクトされ挿入フォームが表示されます。

この状態で保存し再度表示すると id={{contact-profile-id}} にリダイレクトされ編集ができるようになります。

おわりに
Liquid テンプレートの entityform が ID を受け取れれば問題ありませんが、クエリ文字列しか受け取る方法がないため、このような実装となっています。もちろん entityform を使わない方法や、Liquid テンプレートではなく Web API を利用する方法もあります。開発者のスキルや要件に応じて、最適な方法を選択してください。
Discussion
フォームの切り替えはできませんが、以下の設定でクエリパラメータを使わずにログインユーザが関連付けられたレコードを特定し表示することができるかもしれません。
関連付け名には、挿入時にログインユーザを関連付けた列を指定しています。
コメントありがとうございます。参考になります。その方法だと Power Automate などと連携して空のデータを作ってあげればフォームの切り替えをしなくてもよくなりそうですね。