【Power Automate】DataverseからCSVへエクスポート時にJSONの解析・csvテーブルの作成でエラーが発生する

Dataverseデータをcsvにエクスポートする際発生した、
初歩的ですがエラー判断が難しい部分で詰まったのでナレッジとして残します。

# この記事のサマリ（AI要約）
・やりたいこと: Dataverseから取得したデータをCSVにエクスポートし、SharePointに保存するフローを作成する。

・詰まったエラー➀: JSONの解析でスキーマに必須項目が設定されていたが、データに該当値がなくエラー発生。スキーマを修正し必須項目を解除することで解消。

・詰まったエラー➁: CSV作成時、値がない列へのアクセスでエラー発生。JSONスキーマの変更後にCSVアクションの設定を更新しなかったのが原因。

・エラー➁の解決方法: CSVアクションの設定を再入力し、「?」記号を自動的に付与させることで、値がない場合にエラーを回避可能。

・教訓: フローを修正した際は関連アクションも更新し、最新の設定が反映されていることを確認する必要がある。



# やりたいこと
Dataverseベース構築されるモデル駆動型アプリのソリューションである、
Microsoft Sustainability Manager [Microsoft Cloud for Sustainability] (以下 MSM) のデータを
csvファイルにエクスポートしてSharePointに格納するフローを作成します。
※対象のテーブルがMSM独自のテーブルですが、通常のテーブルでも同様です。

# 構築したフロー
全体像
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3795074/5c6accaa-d2d1-3580-87ed-22cda646fdb3.png)

➀「工業プロセス」テーブルからデータを取得します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3795074/3a642629-349f-965d-ba6e-5f13accdbd6f.png)


➁ 一度テストでフローを回し、①で出力されたJSONスキーマをサンプルスキーマとして「JSONの解析」アクションを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3795074/11e11bdf-2060-e006-ca38-cb3d8df5648d.png)

スキーマ （わかりやすいよう今回取り扱う列のみに抜粋して記載しています)
```
{
    "type": "array",
    "items": {
        "type": "object",
        "properties": {
            "msdyn_name": {
              "type": "string"
            },
            "msdyn_description": {
              "type": "string"
            }
        },
        "required": [
            "msdyn_name",  
            "msdyn_description"
        ]
    }
}
```


➂JSONの解析で読み取ったフィールドを「CSVテーブルの作成」アクションで指定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3795074/c14d61a6-4b06-6135-7e67-dd0d9cae4e71.png)



➃SharePointの「ファイルの作成」アクションでcsvファイル格納先とファイル名を指定します。ファイルコンテンツは以下の関数指定をしています。（UTF-8での作成のため)
```
concat(decodeUriComponent('%EF%BB%BF'),body('CSV_テーブルの作成_-_工業プロセス'))
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3795074/d3ec4ff9-bfe4-6bc6-d2e6-c249bbd00fd5.png)


# 詰まったところ➀ JSONの解析
➁のJSONの解析時、以下のエラーで失敗しました。

:::note alert
【エラー内容】
ValidationFailed
The schema validation failed.
:::

:::note warn
【Copilotによるエラー原因推測 (翻訳)】
このエラーは、解析された JSON オブジェクトに必要なプロパティ、具体的には 'importsequencenumber'および'msdyn_description'に関連するいくつかのパラメータが欠落していることを示しています。この問題は、前の操作から返されるデータにこれらの必須フィールドが含まれていないことが原因である可能性があります。これを解決するには、データ ソースがこれらのプロパティを返すように正しく構成されているかどうかを確認するか、返される実際のデータを反映するようにスキーマを調整する必要があるかどうかを検討してください。
:::

### 原因と解決
Copilotの記載通り「JSONの解析」アクションにおいて必須(required)指定をしている列に値が入っていないことが原因でした。
Dataverseで出力したデータをサンプルスキーマとした場合、デフォルトですべての列が必須(required)指定されますが、"msdyn_description"は説明欄なので状況によっては値が入らない場合があります。
そのためスキーマを修正し、列の必須を解除することにすることでエラーが解消しました。

修正前
```
    "required": [
        "msdyn_name",  
        "msdyn_description"
    ]
```

修正後
```
    "required": [
        "msdyn_name"
    ]
```


# 詰まったところ➁ CSVテーブルの作成
➂のCSVテーブルの作成時、以下のエラーで失敗しました。

:::note alert
【エラー内容】
The column values could not be evaluated: 'The template language expression 
'item()['msdyn_description']' cannot be evaluated because property 'msdyn_description' doesn't exist…(略)
:::

:::note warn
【Copilotによるエラー原因推測 (翻訳)】
発生しているエラーは、フローが、前の操作の出力に存在しない「msdyn_description」というプロパティにアクセスしようとしていることを示しています。この問題は、リストされている使用可能なプロパティに「msdyn_description」が含まれていないために発生します。これは、スペルミスがあるか、返されるデータの一部ではない可能性があることを示唆しています。使用可能な別のプロパティ (「msdyn_name」など) を使用するか、使用可能なプロパティのリストにある別の関連プロパティを使用するつもりでしたか?
:::

### エラー原因の調査
エラーの発端はDataverseから取得したデータにおいて「msdyn_description」列の値が入っておらず、項目ごと削除したデータを返したことに起因します。

JSONの解析の出力イメージ
```
[
    {
        "msdyn_name": "ボールペンの製造",
        "msdyn_description": "赤・青・黒色の多色ボールペン"
    },
    {
        "msdyn_name": "えんぴつの製造",
    }
]
```
「えんぴつの製造」を含む行においては「msdyn_description」列に説明の記載がないため、
「"msdyn_description":」の項目ごと削除されています。


するとCSVテーブルの作成において、指定された「msdyn_description」の項目が見つからずエラーとなる仕組みのようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3795074/aa293ba0-4507-42f5-3036-bb2bfc37db02.png)


ただし同様のフローを組んでも、エラーにならない場合が大半です。
別途同じ完成形のフローを作成してもエラーにならず正常に実行されたことがあったことから今回問題の解決に至りました。

### 原因
本当の原因はこれまでの作業プロセスにありました。
本フローは一度全てをある程度仮組みしてからデバックして精度を上げていくよう構築していたのですが、「詰まったところ➀ JSONの解析」にてJSONのスキーマを変更したのにも関わらず「CSVテーブルの作成」アクションのitemを更新しなかったのが原因でした。

ヒントは「CSVテーブルの作成」アクションのコードビューにありました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3795074/a57328ba-7b80-f2cb-d822-fd8723e4625f.png)
エラーとなっている「CSVテーブルの作成」アクションのコードビュー
```
{
  "type": "Table",
  "inputs": {
    "from": "@body('JSON_の解析_-_工業プロセス')",
    "format": "CSV",
    "columns": [
      {
        "header": "名前",
        "value": "@item()['msdyn_name']"
      },
      {
        "header": "説明",
        "value": "@item()['msdyn_description']"
      },
    ]
  },
  "runAfter": {
    "JSON_の解析_-_工業プロセス": [
      "Succeeded"
    ]
  }
}
```

別途フローを作成し正常成功した「CSVテーブルの作成」アクションのコードビュー
```
{
  "type": "Table",
  "inputs": {
    "from": "@body('JSON_の解析_-_工業プロセス')",
    "format": "CSV",
    "columns": [
      {
        "header": "名前",
        "value": "@item()['msdyn_name']"
      },
      {
        "header": "説明",
        "value": "@item()?['msdyn_description']"
      },
    ]
  },
  "runAfter": {
    "JSON_の解析_-_工業プロセス": [
      "Succeeded"
    ]
  }
}
```

違いはitem()の後に「?」が含まれているかどうかになります。
```diff_json
-        "value": "@item()['msdyn_description']"   
+        "value": "@item()?['msdyn_description']"
```

たかが「?」ですがこれには重要な意味があり、
「値が見つからない場合にエラーをスローするのではなくnull 値を返す」
という意味を持ちます。（詳細は以下コミュニティ投稿が分かりやすかったので是非)

https://community.powerplatform.com/forums/thread/details/?threadid=1e69d474-b574-458d-9c0f-1e5b0df9e93e

この「?」がエラーになったフローではついておらず、同じ形に作成したフローではついていたのかというと、この「?」はどうやらJSONの解析アクションにおける「required」部分を参照して自動で付与されているようです。

そのため以下の動きとなります。
・JSONの解析アクションで「required」となっている列を参照 → item()[列名] 
・JSONの解析アクションで「required」となっていない列を参照→ item()?[列名]

つまり簡単に表現すると、JSONの解析アクションでの「required」部分を判断してCSVテーブルの作成アクション側で
・「required」となっている項目は値が確定で入るからエラーハンドリングはしない
・「required」となっていない項目は値の有無がわからないのでエラーハンドリングする
という判断のもとに自動で付与されているのだと思います。

### 解決方法
CSVテーブルの作成アクションに設定したitem項目を削除して、再度同じ値を入れてあげればOKです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3795074/7752eb3c-8db9-83eb-bd0c-00cd7236f88b.png)

その後コードビューを見て、しっかりと「？」が付与されていることを確認しましょう。
```
"value": "@item()?['msdyn_description']"
```

これで万事解決です。


# おわり
ローコードでシステムが良しなに設定してくれるからこそ、システムに逆らって途中を変更すると後続処理が意図しない動作になるときがあることが分かりました。
アクションで生成されたアイテムはそのアクションを修正したらできるだけ最新に更新してあげることを心に留めておくことが大切ですね。画面表示は変わらなくても中身は変わっていることがあることに気を付けましょう。