【多品一葉のデータ】をひとつのリストだけを使ってPower Appsで扱うひとつの方法

## はじめに
現実世界の中では、*一品一葉*のデータというのは、ほとんど存在せず、たいてい多品一葉のデータになっているかと思います。

なにか具体的なサンプルで見てみましょう。

お手元にレシートがあればそれを、なければ下のイメージをご覧ください。
![IMG_3851.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272254/bd461926-69a0-f64a-aaf5-5b86f72a2680.jpeg)
これは、とある居酒屋さんで私が仲間と昼飲みしていたときのレシートの一部ですが、飲み物も酒の肴も一品ずつ精算したりレシートをもらったりすることはないですよね。

つまりお客様グループ単位で複数の種類の注文を複数個、複数回にわたって取引するというのが一般的な商売の形態でデータの姿だと考えます。

では、このように当たり前すぎる伝票形式のデータを Power Appsで扱うにはどうするのでしょうか。
今回は、ひとつの例をご紹介いたします。


### ごく普通の考え方

通常、このようなデータを取り扱う場合は、ヘッダーと明細の２つのデータテーブルを用意するのが一般的かと思います。

すなわち次のようなデータ構造となるでしょう。![スクリーンショット 2024-07-22 144744.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272254/e1c41a58-a5b1-2701-1dd9-7d76b0aab0aa.png)

もちろん、この持ち方にはたくさんのメリットがあるので、一般的にこのような形式でデータを管理するわけですが、我々、市民開発者がローコードであるPower Platformを使って作成するアプリケーションのために、シェアポイントリスト上にヘッダー、明細、それぞれのリストを作成し、あたかもリレーションがあるかのように取り扱うのは、些かハードルが高いかと思います。ましてや、そのアプリの目的が、単に情報を伝達するためのものの場合は尚更です。



### 今回ご紹介する方法は...

そこで、今回は、ひとつのリストだけで明細も含めた取引の情報を管理することはできないかを考えてみました。

そのため、1件ごとのデータの中に明細データをその特定の列の中に格納する方法を複数行テキスト形式の列で実現したいと考えます。

|取引No|精算日|精算時間 |レジ番号| 担当者番号|   明細    |
|:---:|:-----:|:------:|:-----:|:---------:|:---------:|
|20240721132535954|2024/07/21|16:18:00|0002|0001|`(各明細行)`|
|20240721175531534|2024/07/21|19:32:00|0002|0002|`(各明細行)`|

#### 各明細データ
そして、各明細のデータは、明細列の中にjson形式で次のように持つことにします。

```
[
 {"No":1,"PrdName":"ハッピー焼餃子",       "UnitP":125, "Qty":12, "Amt":1500},
 {"No":2,"PrdName":"ハッピー 生ビール中",  "UnitP":299, "Qty":10, "Amt":2990},
 {"No":3,"PrdName":"香港エビマヨ",         "UnitP":680, "Qty":2,  "Amt":1360},
 {"No":4,"PrdName":"パリパリ揚春巻き",     "UnitP":460, "Qty":2,  "Amt":920},
 {"No":5,"PrdName":"小エビの唐揚げ",       "UnitP":450, "Qty":1,  "Amt":450},
 {"No":6,"PrdName":"ザーサイの葱生姜和え", "UnitP":350, "Qty":1,  "Amt":350},
 {"No":7,"PrdName":"ハッピーレモンサワー", "UnitP":299, "Qty":2,  "Amt":598},
 {"No":8,"PrdName":"酢もつ",               "UnitP":350, "Qty":1,  "Amt":350}
]

```
Json形式で持つメリットは、次のようなものかと考えます。
* 複数の項目を扱える
* 項目名も自由に決めることができる
* 複数行のデータを扱える
* テキストなので、デバッグするときも簡単



#### シェアポイントリストの準備
まず、データを保管するリストは、次のように作成します。
ポイントとしては、前記したとおり、明細を保管する列は複数行テキスト型にしています。
![スクリーンショット 2024-07-22 161131.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272254/b64a200d-8077-1357-471e-e3c4dd41890e.png)

#### 完成したアプリのイメージ
次に、完成したアプリのイメージを共有いたします。
![スクリーンショット 2024-07-22 173224.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272254/d099448e-9bf8-55a4-c3bb-001627b62c11.png)
今回はサンプルとして、上部のギャラリーで選択したリストのDetails列に登録されたJsonデータを下部のテーブルビューに表示させるアプリを作成しています。
これを題材としてポイントとなるところをご紹介します。

### 作成方法

#### 明細列に登録されたJsonを解析する。

ギャラリーで選択した列の値は、次のようにして取り出すことができます。
```
CheckedGallery.Selected.Details
```
ただ、取り出したデータは、次のように単純な文字列です。
これではアプリにしたときの視認性が非常に悪いので、項目ｘ行の配列のようにする必要がありそうです。
|CheckedGallery.Selected.Details|
|:-------------|
|[ {"No":1,"PrdName":"ハッピー焼餃子",       "UnitP":125, "Qty":12, "Amt":1500}, {"No":2,"PrdName":"ハッピー 生ビール中",  "UnitP":299, "Qty":10, "Amt":2990}, {"No":3,"PrdName":"香港エビマヨ",         "UnitP":680, "Qty":2,  "Amt":1360}, {"No":4,"PrdName":"パリパリ揚春巻き",     "UnitP":460, "Qty":2,  "Amt":920}, {"No":5,"PrdName":"小エビの唐揚げ",       "UnitP":450, "Qty":1,  "Amt":450}, {"No":6,"PrdName":"ザーサイの葱生姜和え", "UnitP":350, "Qty":1,  "Amt":350}, {"No":7,"PrdName":"ハッピーレモンサワー", "UnitP":299, "Qty":2,  "Amt":598}, {"No":8,"PrdName":"酢もつ",               "UnitP":350, "Qty":1,  "Amt":350}]|

Power Appsでは、Jsonデータを解析するためにParseJson関数というのが用意されています。
記述方法は、次の通り、シンプルです。
```
ParseJSON( CheckedGallery.Selected.Details)
```
ですが、この結果は、UntypeedObjectとなりますので、このままでは使えません。
そこで、さらにTable関数で囲みます。
```
Table(ParseJSON( CheckedGallery.Selected.Details))
```
これでデータの型はテーブル型になりましたので、ギャラリーコントロールのitemsに設定することが可能です。

試しにギャラリーをひとつ追加して、この式をitemsにセットしてみます。
![スクリーンショット 2024-07-22 184955.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272254/d66781c1-b17e-ea0c-0add-ddad5b48c1cd.png)

ギャラリー上の項目(例：商品名)は次のように指定しています。
```
ThisItem.Value.PrdName
```
このようにValue.(Json上の名前)という形で指定することで、値を扱うことができます。

この方法でもアプリによっては問題ないかと思いますが、今回はさらに視認性が良いように
テーブルビューを使って表形式で表示したいと思います。

#### テーブルビューに表示させるための準備
テーブルビューの場合、単純にitemsに追加すると列の指定ができません。
そこで、まず、Jsonデータを解析して、テーブル形式に変換したデータから、さらに項目を指定してコンテキスト変数にセットし、そのコンテキスト変数をitemsに指定します。



次の式を上部のデータを選択すギャラリーのOnSelectに記載します。
```
UpdateContext(
           {
               dataTable: ForAll(
                   Table(ParseJSON(CheckedGallery.Selected.Details)),
                   {
                   // ThisRecord.Value.<フィールド>の<フィールド>部分は手入力する。
                       番号: Text(ThisRecord.Value.No),
                       商品名: Text(ThisRecord.Value.PrdName),
                       単価: Value(ThisRecord.Value.UnitP),
                       点数: Value(ThisRecord.Value.Qty),
                       金額: Value(ThisRecord.Value.Amt)
                   }
               )
           }
       );
```
こうすることで、ギャラリーで選択したタイミングで、OnSelectに記載されたこの式が実行され、dataTable変数に番号、商品名、単価、点数、金額という項目のデータが複数件テーブル形式で登録されます。

試しにギャラリーで一行選択し変数の状態を確認してみましょう。
次のようにコンテキスト変数に、複数項目x多行の２次元配列データとしてデータが登録されていることが確認できます。
![スクリーンショット 2024-07-22 193318.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272254/7637a7ee-0d97-554b-ea56-218c74c61b4b.png)


あとは、テーブルビューのitemsに コンテキスト変数：dataTableを設定し、表形式で表示するフィールドを指定します。

![スクリーンショット 2024-07-23 092044.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272254/42aecded-ce1e-0d15-7d99-0b7c5d090bd3.png)

これで、完成です。

### おわりに

もともと、一つのリストに２次元配列のデータを登録できないかを考えたきっかけは、汎用的な承認ワークフローのテンプレートを作成したい思い、承認者の名前、メールアドレス、それぞれのステータスを管理するにはどうしたらよいかと、ぼんやり考えていたことがはじまりです。
ちょうどそのタイミングで社内のコミュニティに多品一葉のデータをPower Appsで扱うにはどうしたらよいかという相談があり、なるほど、そういうニーズもあるかもなと思って試行錯誤してみました。

ただ、思いのほか情報が過多となりコミュニティを運営するTeamsで紹介するには文量的に大変だったこともありコミュニティのオーナーにQiitaのようなノウハウやナレッジを共有する方法はないかと相談したところ、それだったら、いっその事Qiitaにあげてしまえば？とアドバイスをもらったことからQiita初デビューになりました。

至らぬ点も多々あるかと思いますが、今後もいろいろ発信していければと考えます。

あと、このアプリ、表示だけにフォーカスしたので、肝心のリストにJsonデータを登録することは端折っています。
~~ニーズがあれば、リストに登録する方法についても紹介したいと思いますのでコメントください。~~
登録方法については、次のリンクを参考にしてください。
https://qiita.com/yamachan67/items/0918f2640299f92fde8b