Power AutomateでCSVテーブルをJSON配列に変換したい
経緯
Power AutomateでJSON配列をCSVテーブルに変換するのは簡単です。
アクション「CSVテーブルの作成」を使用すればいいんですから。
でも、CSVテーブルをJSON配列に変換したいときは?
ないんですよね、これが。逆のアクションがないんです。2025年3月現在でも。
いや、必要でしょ!依然としてシステムの多くはCSVファイルでデータをエクスポートしてくるんだから!そのデータを扱いたいでしょうが!市民開発なら尚のことです。なぜ反対向きのアクションの提供してくれないの!?
なんて、文句を言ってても仕方ありません。
「よーし、ないなら作ってやろうじゃないの!」
ということで、Google検索!CSVテーブルをJSON配列に変換している猛者のブログを参考にフローを組んでみたのですが、
アクションが多すぎるよ、、、
何が困るって、1行ごとにApply to Eachで処理するので、アクションが行数倍実行されるんです。
わずか2アクションで処理しても5000行あったら10000万アクションです。フローごとの 24 時間あたりのアクション要求数を使い切ってしまいますし、処理に時間もかかります。
やりたいことはただの変換なんです。1アクションであっという間に処理してしまいたい。
というわけで、悩んだ挙句、別のアプローチをとりました。
Office スクリプトの利用です。
本来はExcelブックでの作業を再現して自動化するためのもの(ExcelVBAのオンライン版みたいなもの)なんですが、Power Automateから実行して、結果をPower Automateに返すこともできます。
公式に以下のシナリオが公開されています。


CSVファイルをExcelブックに変換できて、ExcelテーブルデータをJSONとして出力できるわけなんですから、CSVテーブルをJSON配列に変換することもできるはず!
解決方法
ということで、前置きが長くなってしまいごめんなさい。
CSVテーブルをJSON配列に変換するOfficeスクリプトはこちらです。
解説
このコードは、CSVデータをJSON配列に変換し、その結果をPower Automate用の文字列として返すものです。それぞれの関数を詳しく解説します。
1. main 関数
main はエントリーポイントとなる関数です。
workbook(ExcelScript.Workbook 型)は使用していませんが、存在しないとエラーが発生するので、仕方なく記載しています。csv はCSV形式の文字列データです。convertCSVToJSON(csv) を呼び出してCSVデータをJSONオブジェクトの配列に変換します。
JSON.stringify でJSON配列を文字列化し、最終的な結果を文字列として返します。
2. convertCSVToJSON 関数
csv.replace(/\r/g, "");
Windowsの改行コード(\r\n)をUnix形式(\n)に統一するため、\r(キャリッジリターン)を削除します。
const rows = csv.split("\n").filter(row => row.trim() !== "");
CSVデータを改行(\n)で分割して配列にし、空行を除外します。
if (rows.length < 2) return [];
最低でも1行目にヘッダー、2行目以降にデータが必要なため、行数が2未満の場合は空の配列を返します。
const headers = splitCSVLine(rows[0]);
最初の行(ヘッダー行)をsplitCSVLine関数で分割し、カラム名(キー)を取得します。
const jsonData: object[] = rows.slice(1).map(row => { ... });
2行目以降のデータをループ処理してJSONオブジェクトの配列を作成します。
const values = splitCSVLine(row);
データ行をカンマ区切りで分割し、values 配列を作成します。
let obj: { [key: string]: string } = {}; で空のオブジェクトを作成します。
headers.forEach((header, index) => { obj[header] = values[index] || ""; });header(カラム名)と対応するデータ値をセットし、オブジェクトを作成します。
値がない場合は空文字("")をセットします。
return jsonData;
最終的に、JSON形式のオブジェクト配列を返します。
3. splitCSVLine 関数
const regex = /(?:^|,)(?:"([^"]*(?:""[^"]*)*)"|([^,]*))/g;
CSVの各フィールドを適切に分割するための正規表現。"..." で囲まれた値はそのまま取り出し、ダブルクオート("")はエスケープとして解釈。,(カンマ)で区切られた非クオート値も正しく取得。
let values: string[] = [];
抽出した値を格納する配列。
let match: RegExpExecArray | null;while ((match = regex.exec(line)) !== null) { ... }regex.exec(line) を使って line の中で次にマッチするフィールドを取得する。RegExpExecArray とは:exec() の戻り値で、マッチした詳細情報を含む配列オブジェクト。
マッチしない場合は null を返すため、match: RegExpExecArray | null として型を宣言。
let value = match[1] !== undefined ? match[1].replace(/""/g, "\"") : match[2] || "";
match[1] に値がある場合(クオートされたフィールド)、match[1].replace(/""/g, "\"")""(エスケープされたダブルクオート)を " に変換
それ以外(通常の値)の場合、match[2] || ""match[2] に値があればそのまま使う。match[2] が undefined の場合は ""(空文字)を代入。
values.push(value);
取得した値を配列に追加。
return values;
CSVの1行を配列として返す。
全体の流れ
main関数がconvertCSVToJSONを呼び出す。convertCSVToJSONが CSV データを適切にパースし、JSON オブジェクトの配列を作成。splitCSVLineが、カンマ区切りやクオートの処理を適切に行い、1行のデータを正しく分割。- JSON配列を
JSON.stringifyで文字列化し、Power Automate で扱いやすい形にして返す。
結果として何をしているのか
このコードは CSVデータをJSON形式の文字列に変換する処理 を行っています。
CSVのデータが "name,age\nAlice,30\nBob,25" だった場合、以下のようなJSONが生成されます:
[
{ "name": "Alice", "age": "30" },
{ "name": "Bob", "age": "25" }
]
そして main 関数によって、これが文字列として返されます:
"[{\"name\":\"Alice\",\"age\":\"30\"},{\"name\":\"Bob\",\"age\":\"25\"}]"
この結果はPower Automateなどのツールで処理しやすい形になっています。
感想
めちゃくちゃ疲れました。1行ずつよく読めば分かるし興味深いけど、やっぱりOfficeスクリプトは苦手です。ローコードツールを使うために、コーディングするのも受け入れがたい。そんなに英語も得意じゃないし、そもそも最終目的はJSON配列に変換することじゃないんですよね。JSON配列を利用して何かがしたいわけです。
だから、上記のOfficeスクリプトが書かれている.ostsファイルも置いておきます。
変換方法は分からなくていいから、とりあえず変換がしたいという方はそのままOneDriveかSharePointにアップロードして、Power Automateから呼び出してみてください。返ってくる文字列をJSON()関数で配列にすることをお忘れなく。
