
複数画面にまたがる入力フォームで「途中まで入力して後で続ける」を実現したいなら、下書き保存の仕組みが必要です。難しそうに見えますが、status列・varRecord・条件付きPatchの3つを押さえれば実装できます。
下書き保存が必要なシーン
下書き保存が必要になるのは、現場での点検入力で途中に呼び出しが入るケース、複数画面にまたがる申請フォームで一度に全部入力できないケース、承認フローに回す前に内容を確認しながら段階的に埋めたいケースなどです。
いずれも共通しているのは「入力途中の状態を安全に保持したい」という要件です。フォームを閉じてもデータが消えず、次回開いたときに続きから始められることが求められます。アプリの変数だけで管理しようとすると、アプリを閉じた瞬間に状態が消えてしまいます。これを防ぐためにデータソース側にstatus列を持たせます。
status列をテーブルに追加する
下書き保存の核心はstatus列です。SharePointリストやDataverseテーブルに「draft / open / in progress / closed」のような選択肢を持つ列を追加します。アプリのユーザーはこの列を直接触る必要はありません。あくまでアプリ側が制御するための内部管理列です。
なぜこの列が必要かというと、「このレコードがまだ提出されていない」という状態をデータ側で識別するためです。列があることで「draft状態のレコードだけギャラリーに編集アイコンを出す」「draftでないレコードはすべて入力不可にする」といった分岐ができます。

新規ボタンでdraftレコードを即座に作成する
新規ボタンが押されたタイミングで、空のdraftレコードをその場で作成します。そのレコードをvarRecordに格納することが大切です。
Set(
varRecord,
Patch(
IncidentManagement,
Defaults(IncidentManagement),
{ Status: Status.Draft }
)
);
Navigate(InfoAndCategoryScreen)
Patch関数は成功すると作成されたレコードを返します。それをSetでvarRecordに格納するのがポイントです。これにより「今どのレコードを編集しているか」が全画面で共有されます。
Navigateはセミコロンで繋いでPatchの後に書きます。先にNavigateを書くとPatchが完了する前に画面が切り替わるため、必ずPatch→Navigateの順番を守ってください。Patch関数の返り値をSetで受け取るパターンは既存レコード更新編のvarRecordとも共通する設計です。

画面遷移ボタンでPatch→Navigateの順に実行する
各画面の「次へ」ボタンにはPatchとNavigateをセットで書きます。statusはまだdraftのままです。変えるのはそのページで入力した列だけです。
Set(
varRecord,
Patch(
IncidentManagement,
varRecord,
{
Title: inpTitle.Text,
Description: inpDescription.Text,
Category: ddCategory.Selected.Value
}
)
);
Navigate(LocationAndPriorityScreen)
「Patchして変数を更新してからNavigate」という構造が全ページ共通です。PatchはvarRecordを返すので、Setで再びvarRecordに格納することで変数が常に最新状態に保たれます。
戻るボタンも基本的に同じ構造です。ただし「draftのときだけPatchする」という条件分岐を追加する必要があります。これは次のセクションで解説します。
draftのときだけPatchする条件分岐
提出済みのレコードを閲覧モードで開いているとき、「次へ」ボタンを押してもPatchが走ると不要なデータ変更が発生します。これを防ぐには、PatchをIf文で囲んでdraftのときだけ実行します。
If(
varRecord.Status = Status.Draft,
Set(
varRecord,
Patch(
IncidentManagement,
varRecord,
{ Title: inpTitle.Text }
)
)
);
Navigate(LocationAndPriorityScreen)
NavigateはIf文の外に置きます。これにより、draft以外のレコードを閲覧しているときもボタンで画面遷移はできます。Patchだけがdraftのときに限定されます。全ての「次へ」ボタンと「戻る」ボタンにこのパターンを適用します。
送信ボタンはstatusをopenに変えるだけ
最終画面の送信ボタンはシンプルです。途中画面でデータは全部保存済みなので、最終画面ではstatusをopenに変更するだけで済みます。
Patch(
IncidentManagement,
varRecord,
{ Status: Status.Open }
);
Navigate(WelcomeScreen)
全列を再度Patchする必要はありません。statusを1列だけ更新してホーム画面に戻ります。これでそのレコードはdraftではなくなるので、次回ギャラリーで開いても閲覧モードになります。
ギャラリーでdraftと非draftを見た目で区別する
一覧ギャラリーのアイコンをstatus別に切り替えると、どのレコードが編集可能かが一目でわかります。
// ギャラリー内のIconプロパティ
If(
ThisItem.Status = Status.Draft,
Icon.Edit,
Icon.View
)
draftには鉛筆アイコン、提出済みには目のアイコン。これだけで「編集できるかどうか」が視覚的に伝わります。色分けを加えるとさらに直感的になります。OnSelectは両方とも共通で「varRecordにThisItemを格納してNavigate」でよいです。
表示専用モードを1か所でコントロールする
提出済みのレコードを開いたとき、全フィールドを入力不可(閲覧のみ)にする必要があります。全コントロールのDisplayModeに同じ式を書くのは非効率なので、1つのコントロールだけに式を書いて、他はそれを参照させます。
// inpTitle のDisplayModeプロパティ(ここだけ式を書く)
If(
varRecord.Status = Status.Draft,
DisplayMode.Edit,
DisplayMode.Disabled
)
// 他のすべてのコントロールのDisplayModeプロパティ
inpTitle.DisplayMode
このやり方だと50個のフィールドがある画面でも変更箇所は1か所だけです。status判定ロジックを後から変えたくなったときも修正が1か所で済みます。これは地味ですが保守性を大きく上げるテクニックです。1コントロールにロジックを集約してほかはそれを参照するという考え方は、変数の一元管理と同じ発想です。

応用:空白ドラフトのクリーンアップ
新規ボタンを押してそのまま何も入力せずホームに戻ると、タイトルすら入力されていない空白のdraftレコードがテーブルに残ります。これを放置するとデータが汚れるので対処が必要です。
1つ目はギャラリーのItemsでFilter関数を使い、タイトルが空のdraftを非表示にする方法です。
Filter(
IncidentManagement,
Title <> "" || Status <> Status.Draft
)
2つ目はホームへの戻るボタンでRemoveIfを使い、空白draftを物理削除する方法です。確実にデータをきれいに保てますが、誤操作で入力途中のレコードが消えるリスクも考慮が必要です。どちらを選ぶかはアプリの要件次第ですが、まずはFilter方式から試すのが安全です。
まとめ
下書き保存の実装はstatus列・varRecord・条件付きPatchの3点が核心です。複雑に見えますが、「新規作成でdraftレコードを作る→途中画面でdraftのままPatch→送信時にopenに変える」という流れに沿ってコードを書けば整理できます。
下書き保存を含むPatch関数の応用パターン全体はPatch関数 応用ガイドでまとめています。各テーマの詳細解説へのリンクもそちらから辿れます。
Patch関数の基本がまだ不安な方は新規レコード作成編や既存レコード更新編を先に読んでおくとスムーズです。下書き保存はPatchと変数の組み合わせの最も実践的な応用例です。一度作れてしまえば、どんな複雑な入力フォームでも同じパターンで対応できます。