PowerAppsで複数リストへの同時登録 (1:N)

最近PowerApps Communityでよく見かける質問に、「リスト１とリスト２に同時にデータを登録したい。なお、リスト２は"詳細テーブル"のように使いたい」というものがありました。
今回の投稿では、PowerAppsで、1:Nの関係をもつ複数のリストに対して、データを同時登録する方法を解説します。
リストの表示方法は？とか、編集方法は？とかありますが、簡単のために新規登録のみを取り扱います。
なお、データソースはSharePoint Onlineのカスタムリストを利用します。

#データ構成
今回は商品の発送を管理するようなアプリを例にします。
データ構成（リスト構成）は以下の図のとおりです。
![リスト構成.PNG](https://qiita-image-store.s3.amazonaws.com/0/202779/60939b38-f86e-d3f8-94df-fb94c3cfcb7f.png)

データの構成としては発送の基本情報を格納する「発送リスト」１に対して、発送する商品情報を格納する「発送詳細リスト」がNの構成になります。

#画面構成
発送情報と発送詳細情報を登録する画面の構成は以下の通りです。
![画面構成.PNG](https://qiita-image-store.s3.amazonaws.com/0/202779/6be0956a-f4da-8a5b-d3a7-62c4b4ac7708.png)
画面左部は基本情報を入力する部分、これは発送リストのフォームを利用します。(SubmitとFrom.LastSubmitを利用したかったため）
一方右部ですが、発送する商品の商品名と数量を登録・表示しています。N個の商品を発送する想定なので、一度Collectionに商品を登録して、最後に一括登録します。

#作り方
##発送商品一覧側
発送商品は商品名と数量をドロップダウンから選択します。本来は商品名は商品マスターから選択させたいのですが、今回は割愛します。
商品と数量の一覧への追加は、Collect関数で行います。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/202779/e4c92990-3615-6fdb-2786-6b29f307c3dc.png)

```Collect
If(
    IsBlank(
        LookUp(
            colCartItem,
            Name = ItemName.Selected.Name
        ).Quantity
    ), //まずは同一商品がリストにあるか検索
    Collect(
        colCartItem,
        {
            Name: ItemName.Selected.Name,
            Quantity: Value(ItemCount.Selected.Value)
        }
    ),//なければ商品と数量をCollectionに追加
    UpdateIf(
        colCartItem,
        Name = ItemName.Selected.Name,
        {
            Name: ItemName.Selected.Name,
            Quantity: Value(ItemCount.Selected.Value)
        }
    ) //存在すればUpdate
)
```

これで追加すると、collectionに基づいてGalleryを表示できます。商品一覧です。後ほどこのCollectionをリストに一括登録します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/202779/c74877ac-cac5-85e0-b701-24605168e655.png)

##基本情報側
発送先の基本情報を入力するフォームは特に何もしていません。
発送登録画面なので、```DefaultMode → New```に変更していることと、OrderGuid列に関して以下のようにDefaultをGUID関数で設定しているくらいです。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/202779/53f31dfd-a276-c6b0-6293-a55099c9e704.png)

##登録処理
今回のメインである登録処理について説明します。
登録処理は緑の登録ボタンで行います。
処理の流れは：
1. ボタンクリックでフォームの内容を登録
2. フォームのOnSuccessで、Collectionの内容をPatch
となります。
###1. フォームの内容を登録
登録ボタンでフォームをサブミットするだけです。

```Button.OnSelect
SumitForm(Form1)
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/202779/47177170-41e9-cc45-2721-e947b99c3658.png)
このサブミットの成功をもって、次の処理に移ります。

###2. collectionの内容をPatch
発送する商品の名前と数量をリストに一括登録するために、ForAllとPatchを利用します。
発送基本情報のIDと各商品のレコードを結びつけるために、1.でサブミットした際のIDが必要になりますが、これは@yamad365 さんに教えてもらいました。
Form1のOnSuccessに以下のように記述します。

```Form1.OnSuccess
ForAll(
    colCartItem,
    Patch(
        OrderDetail,
        {
            Title: Name,
            orderid: Form1.LastSubmit.ID,//ここがポイント！
            Amount: Quantity
        }
    )
)
```
サブミットした際に発行されたID（を含むレコードの情報）は、```Form1.LastSubmit.*列名*``` で取得できます。これを用いて関連付けを行います。

以上で、2つのリストに対して、1:Nの関係にあるデータを一括登録できました。


#動作イメージ
Twitterでつぶやいた動画です。
商品数量の修正はカートマークのボタンで、Collectionのアイテム削除はごみ箱マークで行います。
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">データソースをSharePointカスタムリストで、オーダーリスト、オーダー詳細リストを作り、商品発送管理アプリを作成してみました。 <a href="https://twitter.com/hashtag/PowerApps?src=hash&amp;ref_src=twsrc%5Etfw">#PowerApps</a> <a href="https://t.co/QICen9jFN1">pic.twitter.com/QICen9jFN1</a></p>&mdash; ながちん(Hiro)  #PowerAddict (@mofumofu_dance) <a href="https://twitter.com/mofumofu_dance/status/1093155964205686785?ref_src=twsrc%5Etfw">2019年2月6日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

#おまけ
商品発送の詳細リストには、出荷されたアイテムの数量と名前、出荷入荷区分が入っています。
これを利用すると在庫管理アプリを作ることも可能です。
こちらは1リストで完結するのでほとんどなにもすることはないので、後日投稿します。