はじめに
ノーコードでWeb APIを利用してみようと思い、Power Automate Desktop(以下PAD)を使ってみています。PADにはWeb APIの返すJSONをカスタムオブジェクトに変換する「JSON をカスタム オブジェクトに変換」アクションがあり、PAD内で利用するには十分です。しかしJSONの中のリストをCSVとして保存しようとしたところ苦労しましたのでその内容を記事にしました。
環境
OS: Windows 11 Home
PADバージョン: 2.39.00239.23332
本文
概略
以下の手順でJSONをCSVとして保存します。
1. リストを含むJSONを用意します。
2. JSONをカスタムオブジェクトに変換します。
3. リストカスタムオブジェクトの1番目の要素をJSONテキストに変換します。
4. キーのリストを正規表現で要素のJSONテキストから取得します。
5. キーのリストから空のデータテーブルを作成します。
6. リストカスタムオブジェクトをFor eachでループし、データテーブルに行を追加します。
7. データテーブルをCSVファイルに書き込みます。
手順
JSONテキストを変数に設定する
ダミーのJSON文字列です。ここではこれを使用します。
「変数設定」アクションの値に貼り付けます。
{
"users": [
{
"_id": 1,
"name": "Alice",
"gender": "female",
"age": 25
},
{
"_id": 2,
"name": "Bob",
"gender": "male",
"age": 32
},
{
"_id": 3,
"name": "Charlie",
"gender": "male",
"age": 28
}
]
}
JSONをカスタムオブジェクトに変換する
「JSON をカスタム オブジェクトに変換」アクションに先ほどのJSONテキストを入力します。
リストの要素1つをJSONテキストに変換する
カスタムオブジェクトからキーのリストを取り出す方法としてJSONテキストを解析する方法を選択しました。そのためJSONオブジェクトから要素を取り出してJSONテキストに変換しています。
キーのリストを取得する
ここが今回の肝です。
JSONテキストからキーを取り出すために「テキストの解析」アクションを利用します。
正規表現は以下の通り、{"
または,"
と、":
の間の最短文字列を取得するようにしています。
(?<=[{,]").+?(?=":)
正規表現である
をONにし、最初の出現箇所のみ
はOFFにします。また、一致する結果を変数ColumnNames
としています。
データテーブルを作成します
下記のようにリストの頭に^
を付けると列名として指定することができます。
%{ ^ColumnNames }%
リストの中の文字列を列名とした空のデータテーブルが作成されます。
データテーブルに要素を追加します
For eachを入れ子にしてそれぞれ行と列をデータテーブルとリストに追加しています。様々な列数に対応するためこのようにしています。
カスタムオブジェクトから値を取り出すのにCurrentItem
にブラケットでColumnName
を指定して値を取り出します。
%CurrentItem[ColumnName]%
CSVファイルとして保存します
作成したCSV
うまいこと保存されました。今回のサンプルではわかりませんが、ちゃんとエスケープも処理されます。
全体フロー
SET Json TO $'''{
\"users\": [
{
\"_id\": 1,
\"name\": \"Alice\",
\"gender\": \"female\",
\"age\": 25
},
{
\"_id\": 2,
\"name\": \"Bob\",
\"gender\": \"male\",
\"age\": 32
},
{
\"_id\": 3,
\"name\": \"Charlie\",
\"gender\": \"male\",
\"age\": 28
}
]
}'''
Variables.ConvertJsonToCustomObject Json: Json CustomObject=> JsonAsCustomObject
Variables.ConvertCustomObjectToJson CustomObject: JsonAsCustomObject.users[0] Json=> CustomObjectAsJson
Text.ParseText.RegexParse Text: CustomObjectAsJson TextToFind: $'''(?<=[{,]\").+?(?=\":)''' StartingPosition: 0 IgnoreCase: False Matches=> ColumnNames
SET DataTable TO { ^ColumnNames }
LOOP FOREACH CurrentItem IN JsonAsCustomObject.users
Variables.CreateNewList List=> Row
LOOP FOREACH ColumnName IN ColumnNames
Variables.AddItemToList Item: CurrentItem[ColumnName] List: Row
END
Variables.AddRowToDataTable.AppendRowToDataTable DataTable: DataTable RowToAdd: Row
END
Folder.GetSpecialFolder SpecialFolder: Folder.SpecialFolder.Personal SpecialFolderPath=> MyDocuments
File.WriteToCSVFile.WriteCSV VariableToWrite: DataTable CSVFile: $'''%MyDocuments%\\sample.csv''' CsvFileEncoding: File.CSVEncoding.UTF8 IncludeColumnNames: True IfFileExists: File.IfFileExists.Overwrite ColumnsSeparator: File.CSVColumnsSeparator.SystemDefault
おわりに
今回は結構強引に処理しましたがいずれリストカスタムオブジェクトをデータテーブルに変換するアクションが作られるものと思います。(だったらいいな)
いまのところ、たかだかJSONからCSVに変換するだけで10行以上も使います。もっとノーコードが便利になるといいですね。