【ワンランク上のPower Apps】 Tips – コピー機能の作り方

# はじめに
こんにちは。ヨウセイです。
Microsoft Power Apps Advent Calendar 2022 カレンダー３が出来ていたので、Power AppsでのちょっとしたTipsをご紹介しようと思います。カレンダー３の12/24用の記事です。今回は短くいきます。

ワンランク上のおっさんはコピー機能を魅力的にかつドラマチックに語ることができる～～！
ということで今回はひとつ前の記事でも載せていたレコードのコピー追加機能です。
※さや侍もすきだったなー

# 実装サンプル 
※この中でコピー機能を使ってます。　
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">dataverse for teamsスマホ版 <a href="https://t.co/t7FKJVuDg9">pic.twitter.com/t7FKJVuDg9</a></p>&mdash; ヨウセイ (@youseibubu) <a href="https://twitter.com/youseibubu/status/1605885340702720001?ref_src=twsrc%5Etfw">December 22, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# コピー追加機能について
レコードを追加する際に０からすべて入力するのは手間ですよね。
たまに登録や1日一回レベルならまだいいですが、1日に数回登録する場合や項目が多数ある場合などは、以前のデータをもとに一部を修正して登録したい。という声はよく聞きます。
Webアプリなどでは大体こういった機能が存在しますよね。ユーザーの使いやすさの向上のためにも欠かせない機能かなと思います。

実装のパターンとしては、
①元のデータを変数に詰めてDefaultに指定する。フォームモードはNewでSubmitFormで登録
概要は以下のような感じかと（作ってないのであくまでイメージです）
・各項目用の変数を用意する
・元のレコードにコピーボタンを付ける（ギャラリーかフォーム上）
・コピークリック時、CopyMode的な変数をTrueにし元のフォームの各項目を各変数に詰める
・フォームをNewモードで開きDefaultには変数を指定しておく。※CopyModeかどうかでこれを使うか切り替える
・適宜フォーム上で項目を修正してSubmitFormする

もうひとつは、
②元とするフォームにコピーボタンを付け、クリック時はPatchを使って新規で登録させる
・特に用意は不要。SubmitFormは使わずPatch用の実装を行う

という感じかと。今回は②の作り方をご紹介します。

# コピー追加機能 概要
ひとつ前の記事で紹介した自社で利用している経費精算アプリでの実装を紹介します。
前の記事はこちら[【ワンランク上のPower Apps】 スマホ対応レスポンシブレイアウト](https://qiita.com/youseibubu/items/97f94cfc66f1bbcedc65)

・元のレコードを表示する（12/1のレコード）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249807/50d4ad00-41cf-2120-da6a-c777465a9b38.png)
・日付を変更して「コピー追加」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249807/304795e5-5cb2-2baf-2c42-67929c20a58c.png)
・新しいレコードとして保存される（12/23のレコード）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249807/9c44ce47-3267-10de-2e98-e164f02a0932.png)
動きはこんな感じです。
# コピー追加機能 実装ポイント

+ コピーボタンのOnSelect
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249807/7c7b2171-81c2-82cc-cfa9-4ececdfacd5f.png)
```
// 独自の処理入っているのでポイントのみ抜粋。Patchの新規登録の構文を書く
Patch(CurrentKeihiList,Defaults(CurrentKeihiList),KeihiForm.Updates);
```
+ 簡単にはこれだけです。
SubmitFormではなくPatchとするのは、既存レコードを開く際はフォームのモードはEditとなっており、SubmitFormだと更新しかされないためです。フォームモードをNewの状態でSubmitFormしないと新規登録されません。
じゃあ、登録前にEditからNewに変更するか。としてもNewにしたら初期化されるので入っているものも空になります。Patchだとフォームモードは関係ないので構文を新規登録用にすればOKとなります。

**★今回は上記の実装のみですが本来はポイントがあります。**
それはPatchだとSubmitFormのようにフォームのチェックをしてくれないことです。必須項目が空のままSubmitFormすれば自動でチェックしてくれますよね？あれがありません。
ですので、本来は事前にチェックが必要となりますが、今回のやつは必須が埋まらないとボタンを活性化しないようにしてますのでチェック不要。なのでPatchだけで済んでます。

事前にチェックする場合、Validate関数でチェックしたりとカスタム処理が必要です。またエラーをフォームに表示したいのでその辺もカスタムが必要だったりします。
```
例：Validate( Scores, EditRecord, Gallery.Updates )	
https://learn.microsoft.com/ja-jp/power-platform/power-fx/reference/function-validate
```
が、以前調べた際に外人さんがとてもよいやり方を載せていてくれたので自分は次の方法でそれをやっています。

# PatchでのSubmitFormを利用したチェックの実装
SubmitFormをすれば自動で必須などのチェックをやってくれて、アラートと対象列にエラーメッセージまで出してくれます。これをわざわざカスタムして再現するのは時間かかります。

なのでSubmitFormを使います。 
ってPatchじゃないの？となりますよね。
正確には、エラーとなる場合のみSubmitFormをする。エラーにならない場合はPatchする。です。
+ FormのValidを使い入力エラーがあるかチェックする
+ FormのValidがFalse（エラーあり）の場合はSubmitFormする。True（エラーなし）の場合はPatchする
+ エラーありの場合にSubmitFormすれば標準機能のチェック＆アラート＆メッセージを表示してくれる！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249807/a9093358-4ec3-cc09-ae6a-3bc818dea111.png)
```
// ポイントのみ抜粋。ValidでSubmitFormするかPatchするか　
→SubmitFormはエラー時のみやるので、エラー表示してくれるだけ。正常時はPatchで保存となる。
If(!KeihiForm.Valid,
    SubmitForm(KeihiForm)
    ,
    Patch(CurrentKeihiList,Defaults(CurrentKeihiList),KeihiForm.Updates);
)
```
上記の実装を入れて値を空にしてクリックしてみます。（コピーボタンは常に活性化に調整）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249807/f3d246dc-fa2c-bc3e-88e1-a2dc7a23a349.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249807/d2df2b88-faa6-02bb-fc29-24b147d64f57.png)
上記のとおり、入力エラーでSubmitFormしているのでその挙動となってくれます。
正常値の場合はPatchをするので目的通りコピー追加ができます。

# おまけ フォーム関連の便利なプロパティ
上記で利用しているようにフォームには便利なプロパティがあります。
代表的なものをいくつかご紹介します。

+ フォーム.Updates  → フォーム上の項目を取得できる（編集中の値含め）
今回のようにPatchで使う際はいちいちJSON書かずにこれでフォーム上の値を取って使える。スマートです。
その他、編集後に内容確認用の別フォーム（閲覧モード）を表示する場合にもItemにこれをはめれば一発（の記憶）

+ フォーム.Valid   → フォーム上でエラーがないか判定できる
今回も使ってますね。実はボタンの活性、非活性の判定にも使ってます。スマートです。
```
ボタンに以下入れればチェックOKの場合のみ活性化となる
If(フォーム.Valid ,DisplayMode.Edit,DisplayMode.Disabled)
```
+ フォーム.LastSubmit   → フォーム上で最後にSubmitした内容が取れる
例えばSPOの場合は新規登録後に一意のID列ができます。登録後にそのIDを使ってフローを動作させたい、次の処理に使いたいという場合は、SubmitForm後にフォーム.LastSubmit.ID でIDを使えます。もちろん他の項目も利用可能です。

+ Patchの結果取得方法   → Patchを変数に詰めれば結果がとれます。フォーム.LastSubmit同様に登録内容を次の処理に利用可能です。
```
Set(PatchResult,Patch(CurrentKeihiList,Defaults(CurrentKeihiList),KeihiForm.Updates));
PatchResult.ID　などで利用可能
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249807/7c1d4902-9195-8dac-3774-e1eee7aedf03.png)
公式には以下が参考となるかと
https://learn.microsoft.com/ja-jp/power-apps/maker/canvas-apps/controls/control-form-detail

# おわりに
この例のように交通費などの入力だと、日付以外おんなじなのに毎回全部同じことを打ち込むのがつらい。エクセルのほうがいい。となったりします。
今回のような感じのコピー機能を追加すればかなり使いやすくなります。ユーザーが使いずらいアプリだと負荷となりますし定着しずらいので、業務に合わせた使いやすい機能、便利な機能を用意することはとても大事だと思います。
また、併せてご紹介したフォーム関連の便利プロパティもうまく使えば実装がスマート＆できる幅が広がると思います。

**★他のアドベントカレンダー投稿記事はこちらです**
12/5[【ワンランク上のPower Apps】 CSVインポート その① パターン紹介編](https://qiita.com/youseibubu/items/dac102f67993413c3428)
12/6[【ワンランク上のPower Apps】 CSVインポート その② Automateで解析・登録編](https://qiita.com/youseibubu/items/1068b4e1e3ec0f36a5d8)
12/11[【ワンランク上のPower Apps】 CSVインポート その③ Automateで解析・Appsで登録編 ＆プログレス表示](https://qiita.com/youseibubu/items/b04358342098648326eb)
12/23[【ワンランク上のPower Apps】 スマホ対応レスポンシブレイアウト](https://qiita.com/youseibubu/items/97f94cfc66f1bbcedc65)