Microsoft Flow で JSON 配列をちょっと賢く作りたい

# はじめに
JSON データは文字列でそれっぽく編集すればできるけど、なんか芸がない...(誰でもシステム開発者になれるという意味では良いところなんだ)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230264/ceafcabf-b256-3baf-ae59-109d703cac18.png)

けど、もうちょっと賢く作りたい...(いちおうシステム屋さんという葛藤)

で、処理フローとその内容を忘れそうなので、備忘録として残しておこう。

# 処理の手順
1. データを用意する (今回は CSV 形式のデータを用意)
2. JSON 形式に変換する際に必要な変数を定義する
3. 基となるデータの行数分ループ
    1. 行単位で編集する際に必要な変数を初期化する
    2. 基となるデータの列数分ループ
        1. 列の値を取り出す
        2. 列の名前と列の値を紐づける
4. 処理結果を確認する (今回は HTML テーブルを出力)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230264/53537804-9490-3eb4-9e72-1c2a9bca8271.png)


# 1. データを用意する
今回は文字列で CSV 形式のデータを用意しました。
1 行目はヘッダー、2 行目以降にレコードを格納します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230264/42d753d4-7bda-420f-f958-6a638160ebe5.png)

そして、上記の CSV データを行ごとに分割します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230264/0b136e07-4326-9735-cd30-054dc2d90e8a.png)

```
split(outputs('作成_-_夏休みの天気'),variables('改行コード'))
```

区切り文字として改行コード (\n) を指定してもうまく分割してくれないので、改行コードだけの文字列変数を用意してそれを指定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230264/ecd6a645-b9c1-0831-e2b2-e0bbba72711d.png)

[参考：Microsoft Flow上で複数行文字列を改行で分割する](https://qiita.com/kojisaiki/items/d7fb7932e6f20e1e6628)

# 2. JSON 形式に変換する際に必要な変数を定義する
大きく分けて以下に関する変数を定義します。

- ヘッダー行
- データ部

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230264/5d14742b-e74e-ec68-fd17-40d5c980a3f3.png)

## ヘッダー行
行ごとに分割した配列の 1 番目の要素をカンマ区切りで分割して配列に入れます。これが列の名前となります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230264/1cb9ee8a-3763-acb5-3397-8d0aa7886601.png)

```
split(outputs('作成_-_Table')[0],',')
```

## データ部
行単位に編集するために使う変数 (JSONItem) とその編集した結果を格納する配列 (JSONBody) を用意します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230264/f6a8b529-48ac-e996-f38b-9df64316fd30.png)

それと、列単位に編集するので現在の列位置を把握するためのインデックスを用意します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230264/7cf3ab54-ef99-ff7a-43a0-6d3c752894ff.png)


# 3. 基となるデータの行数分ループ
行ごとに分割した配列の 2 番目の要素から繰り返します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230264/3af34024-beec-c602-5985-29a3255597a2.png)

```
skip(outputs('作成_-_Table'),1)
```

## 3-1. 行単位で編集する際に必要な変数を初期化する

- 現在行を取り出す
- 行単位に編集するために使う変数 (JSONItem) を初期化する (初期値は「'{}'」)
- 現在の列位置を把握するためのインデックスを初期化する (初期値は「0 (ゼロ)」)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230264/5d0c0b9d-a5be-272f-7749-ba89b9da5868.png)

## 3-2. 基となるデータの列数分ループ
行ごとに分割した配列の 1 番目の要素をカンマ区切りで分割した配列の要素 (列の名前) 数分、繰り返します。
ループ終了後、行単位で編集した結果を配列に格納します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230264/e12abb7d-6dc1-e5f9-0938-35deb28eafee.png)

### 3-2-1. 列の値を取り出す
列の名前とそれに一致する値を取り出します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230264/55b9a0aa-91f7-d697-4e05-89c2b440be6d.png)

```
split(outputs('作成_-_現在行'),',')[int(variables('IndexProp'))]
```

### 3-2-2. 列の名前と列の値を紐づける
列の名前と値を紐づけるためには「addProperty 関数」を使い、行単位に編集するために使う変数 (JSONItem) を更新します。
そして、現在の列位置を把握するためのインデックスに「1」加算して次のループを行います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230264/326eb8eb-4fa7-2a05-5a9e-a91bde2d26a2.png)

```
addProperty(variables('JSONItem'),item(),outputs('作成_-_プロパティの名前と値を紐づけ'))
```

[参考：Azure Logic Apps および Microsoft Flow でのワークフロー定義言語の関数リファレンス > addProperty](https://docs.microsoft.com/ja-jp/azure/logic-apps/workflow-definition-language-functions-reference?WT.mc_id=AZ-MVP-5003113#addproperty)


# 4. 処理結果を確認する
このフローをテスト実行すると、以下のように JSON 配列が出力され、無事 HTML テーブルに変換されていることが確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230264/a9542f0a-73fe-3324-bf22-82951a8bbf1a.png)


[参考：MICROSOFT FLOW (ADVANCED) TUTORIAL : CREATING A CSV TO JSON CONVERTER FROM SCRATCH](https://sergeluca.wordpress.com/2018/10/28/microsoft-flow-advanced-tutorial-creating-a-csv-converter-from-scratch/)