PowerAutomateで、アレイをGroup Byして合計を求めよう！

## はじめに

いやぁ、毎日暑い。こう暑いと、現実逃避癖がついつい顔をだす。
そんなこんなで会社のPower Platformのコミュニティを覗いていたら、
面白そうな質問というか相談が上がっていたので、ついつい現実逃避のアテに

それは、次のような相談というか質問(どっちでもいいが)
```
[
  {    "商品": "A",    "数量": 10  },
  {    "商品": "B",    "数量":  5   },
  {    "商品": "A",    "数量": 15  },
  {    "商品": "C",    "数量":  7  },
  {    "商品": "B",    "数量":  3  }
]
```
こんな配列を商品別に数量計を求めることができますか？って

ようするに、Aが25、Bが8、Cが7になるような計算ってどうするのかってこと。

なかなか、おもしろそうやん。
こういうのを見ると、会社入りたての頃、汎用機使って、固定長のファイルをガリガリ処理していたのを思い出す。はい、構造化プログラミングってヤツですね。当時はSQL使って、RDBを扱うようなことがなかったから、Group Byなんて出来なかったわけですよ。

### Power AutomateでGroup Byするアクションは？

うーん、念の為、データ操作のアクションを確認したけど、とうぜん、Group Byなんて無いわけで、じゃぁ仕方がない。ちまちま作るかってことで、頭の体操にチャレンジ

### 処理のイメージは

『ユニークにした商品でループさせてフィルタした値を合計して...』みたいな感じ？

![スクリーンショット 2024-07-26 191010.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272254/8967da84-f641-b27c-1022-4f12992be91b.png)
出来たー！いやぁ、昔取った杵柄だねー、だいたい15分ぐらいで出来ました。

## 解説

ここからは、フローを順におって解説していきます。

### まず初期化

何はともあれ初期化が大事です。
実際は、作りながら、おっと、こんな変数がいるって付け足していくわけですが
![スクリーンショット 2024-07-26 191321.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272254/aa3b9a30-d6a1-2980-adac-a52990adcb4d.png)

こんな感じで、合計(商品別小計)を入れる変数と
結果を格納するアレイ型の配列を用意し、データ操作の作成アクションで元データを準備します。

### ユニークな商品一覧の作成

元データから商品名だけを抜き出します。
![スクリーンショット 2024-07-26 191828.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272254/bd1fa79b-599e-8f2a-8976-fc94cf59416c.png)

データ操作の選択アクションをフロー二追加し、次のようにセット
|     |セットするもの|式で表すと|
|:----:|:-----------:|:--------|
|開始|元の配列の結果| @{outputs('作成(元の配列)')} |
|マップ|商品|@{item()['商品']}|

この処理の結果は次のようになります。
```
{
    "body": [
        {
            "商品": "A"
        },
        {
            "商品": "B"
        },
        {
            "商品": "A"
        },
        {
            "商品": "C"
        },
        {
            "商品": "B"
        }
    ]
}
```
なんとなく、いい感じですが、まだ重複しているので、これをユニークにします。

Power Automateで、データをユニークにする方法をご存知ですか？

```
@{union(body('選択'),body('選択'))}
```
こんなふうに、union関数に同じ値を２つ渡すと何故かユニークになります。

https://learn.microsoft.com/ja-jp/azure/logic-apps/workflow-definition-language-functions-reference#union

結果は次のようになっています。
```
[
    {
        "商品": "A"
    },
    {
        "商品": "B"
    },
    {
        "商品": "C"
    }
]
```

ここまでが前準備で、いよいよここから商品ごとの合計を求める処理が始まります。

### 商品ごとにループを回そう！

Apply to eachでユニークにした商品ごとに、ループを回します。
![スクリーンショット 2024-07-26 194515.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272254/420c967e-6f3a-0161-55ad-7bd5050f9b84.png)
この例だと、商品A,B,Cと３回ループが回ることになります。
Apply to eachに渡した出力は、もちろんユニークな商品作成の値となります。
```
@{outputs('ユニークな商品作成')}
```
こんな式ですね。

では、順番にApplyt to eachの中のアクションを解説していきます。

#### アレイのフィルター処理
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272254/99446c84-e973-1ac7-ba5a-7e34ff138765.png)

うーん、どれもこれも、"出力 x"で、さっぱりわかりませんね😅

一旦、詳細設定モードに切り替えて編集してみましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272254/c3cf0f40-dc4e-1c6a-8a1c-f53dc90e70c0.png)

これで、少し判るかな？
差出人にセットする式は @outputs('作成(元の配列)')。
元データの配列を渡しています。

次にフィルター式は次のようにしています。
```
@equals(item()['商品'], items('Apply_to_each')['商品'])
```
ユニークな商品A,B,Cを渡して、元データの配列から、商品の値(商品名)が等しいものを抽出しています。
結果は、ループ一回目(商品="A")
```
{
    "body": [
        {
            "商品": "A",
            "数量": 10
        },
        {
            "商品": "A",
            "数量": 15
        }
    ]
}
```

ループ２回目(商品="B")
```
{
    "body": [
        {
            "商品": "B",
            "数量": 5
        },
        {
            "商品": "B",
            "数量": 3
        }
    ]
}
```

ループ３回目(商品="C")
```
{
    "body": [
        {
            "商品": "C",
            "数量": 7
        }
    ]
}
```
どうです？順番に対象の商品分だけがフィルター出来ているでしょ？
あとは、それぞれの結果をさらにループさせて数量を加算していけばいいわけです。

#### 商品別金額計の計算

![スクリーンショット 2024-07-26 201819.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272254/ba6444ad-4994-b8f6-8f5b-93ff3d8ab0bc.png)

まず、合計用の変数をゼロクリアします。
これをしないとAのあとにBの値を追加していくことになりますからね。

そして、Apply to eachを使って、合計変数の値に、1行データごとの数量を足し込みます。

#### 結果のアレイへの追記
それぞれの商品ごとに数量計を計算出来たら、結果をアレイ形式で追記していきます。
![スクリーンショット 2024-07-26 202339.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272254/e32b0a3a-febc-83e3-587b-28800ef1be0f.png)

配列変数に追加する値の式も紹介しておきましょう。
```
{
  "商品": @{items('Apply_to_each')['商品']},
  "数量計": @{variables('合計')}
}
```

こんな感じですね。

#### 結果の確認
これでGroup Byの処理は完了です。

念の為、データ操作のHTMLテーブルの作成を追加して、正しく商品ごとの数量計が計算されていることを確認します。
![スクリーンショット 2024-07-26 202739.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272254/84f8886d-c10a-0771-0853-a7a7bb45b47b.png)


## まとめ

まとめるほどもありません。ちょっと視点を変えれば、このような処理だって組めるということがわかっていただけましたでしょうか。

わかってしまうと簡単なのですが、意外と思いつくまでがたいへんなコロンブスの卵かもしれません。

![コロンブスのたまご.png](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizoqef3Ps38TmxGAS7Xr1VfHWgKfPlLRXruzbaAJHJhWb-lH3LQRWSzIofjoKw-KAhzmD7qVkN3Lzl53GPQJVrTRYiTiCvQT3VqvC70FkVs9yZuecuaffBfMlgLxefqb27FnVjQSRHN_p_/s800/columbus_egg.png)

今後も、こういう面白い事例を紹介していければと思います。