こんな人向けの記事です
- CSVファイルを取り込んで処理したいが適当なアクションが見つからない
- ループ処理で取り込んでいるけれど永遠に終わらない
なぜかCSVファイルの取り込みが難しい
クラウドフローでデータの処理を行おうとすると、ほぼ確実に出くわすのがCSV取り込み問題ではないでしょうか?
Microsoftの標準コネクターにはなぜか専用のCSVパーサーがないため、これを行おうとすると「ファイルコンテンツを取得」→「テキスト分割」→「行ごとの処理」のようなことを行う必要があります。
この方法については、以前にこちらの記事で紹介したことがあるので参考にしてください。
読んでいただいてわかる通り、こちらの方法ではCSVファイルの中に書かれたテキストを行の数だけApply to eachでぐるぐると回して配列にしていきます。
しかし、ご存じのとおり、Apply to eachは動作がとても遅く、可能な限りループを使わないのが定石です。
今回の記事では、ループを使わずに、CSVファイルの取り込み処理の高速化する方法を紹介したいです。
下準備
CSVファイルのサンプルとして、今回は気象庁が提供している「最新の気象データ」から拝借します。
日本の各都市の直近1時間の気象状況をCSVファイルで毎時提供してくれている素晴らしいオープンデータです。(このサイトを参照するだけで天気予報アプリが作れてしまいますね!)
今回はこのファイルを適当なSharePointサイトに保存して「パスによるファイルコンテンツの取得」を行い、その結果をテキスト変数に投げ込みます。
テキストが文字化けしてしまいました。今回参考にしたCSVファイルはShift-JISで記録されていましたので、テキストエディタを使って UTF-8(BOM付き)で保存しなおしました。再度SharePointサイトにアップロードしてみます。
よしよし。
「作成」のなかには、上記の改行文字列で区切った配列にするため、Split関数を使って以下のように指定しましょう。
split(variables('CSV生テキスト'),variables('改行'))
「作成」をわかりやすいように「生データ」に書き換えて実行してみました。各行が1つの要素になった配列に変換されました。
ヘッダー部とデータ部に分けて「選択」でJSON化する
以前に紹介したCSVのパース処理でつかっていた Aplly to eachで1行ずつ処理するかわりに、「選択」アクションをつかってJSONの形にパースする方法です。
ヘッダーの先頭行を配列化する
先ほどの「生データ」の先頭要素がヘッダーなので、先頭要素だけを取り出して、カンマ区切りを再びsplit関数で区切ってヘッダー配列を作りました。
split(first(outputs('生データ')),',')
データ部だけを配列化する
次にデータ部も取り出します。生データからskip関数を使って2要素目からのデータだけを取りだします。
テスト実行してみると、データだけの配列が出来上がっていることがわかります。

「選択」をつかってデータ部を列ごとにJSONの要素に配置する
先ほど取り出したデータ配列を「選択」アクションの入力にしてやります。
手始めに、マップの左辺には適当な文字を配置し、右辺にはデータの1要素をカンマで配列し、さらにその先頭要素(0番目)だけを取り出すようにします。
split(item(),',')[0]
テスト実行すると、CSVファイルの1列目の値を取れたことが見えてきます。

ヘッダーをJSONのキーに設定する
さきほどすでにヘッダーは配列化してありましたので、何番目(何列目)の要素なのかを指定してやれば「選択」アクションの左辺に設定してやります。ここがこの処理のポイントでしょう。
テスト実行してみると、1つ目のヘッダー名とその値が設定されたJSONが1行1要素の配列として作成されていることがわかります。
ここまでくればご想像の通り。1列目は0番目の配列ですから、2列目以降も「選択」アクションの両辺に要素番号をつけて列数の分だけ指定してやればよいのです。
でもエラーが出るよね・・・
2番目の要素、添え字1を入れて実行してみると。エラーですね。


原因は配列の一番最後の要素が空っぽであることです。「選択」アクションでsplit関数を使っても、カンマがないので2つ目の要素が作られず。結果的に「選択」アクションで要素がないためにエラーになってしまうのです。

空っぽの行を取得してしまうのは、「データ」をテキストから取得した際に最後の行を取り込んでしまっているから。この対策が必要です。
最初にテキストを配列に変換している箇所「生データ」の式のなかで、trim関数を使ってテキストの前後にある空文字を取り除きます。
split(trim(variables('CSV生テキスト')),variables('改行'))
あとは、ひたすら「選択」アクションの左辺と右辺に添え字を1つずつ増やしていくだけです。ちなみに、今回のサンプルデータは29列あります。頑張ります。
JSONパース方式を実行してみる
スコープに入れて実行してみました。29列1286行のデータをなんと1秒で処理できてしまいました!

比較してみます
2次元配列にCSVの中身を配置するApply to eachを2重ループにしたものと、先ほど作成したJSONに「選択」を使って取り込んだ方式を並列実行して速度の差を確認してみます。本来なら配列変数にマッピングすればよいのですが、簡易的に「作成」に添え字がわかる表にだけしてみました。
1つめのAplly to each の入力
skip(split(variables('CSV生テキスト'),variables('改行')),1)
2つめのApply to eachの入力
split(item(),',')
実行してみるとその差は歴然。同じ29列×1285行のCSVファイルを取り込んだとき、今回紹介したJSONパース方式は1秒。Apply to eachのループ方式は30分たっても終わりません。
配列は添え字が大切なのでコンカレンシー制御もできず。ループを1重にすることもできますが、それでも「選択」アクションをうまく作ったJSONパースの圧勝だとわかっていただけるでしょう。
QiitaのPower AutomateでCSVを入力として使う記事でループを排除する画期的を紹介している人はなかなかいないべ? と思って探してみたら。いた!ヨウセイさんさすがっす。
この方法、考え方自体は簡単だし、選択もアレイのフィルターもitem() の扱い方はApply to eachと同じとわかれば理解しやすいです。
CSVはあらゆるシステムの出力に使われているので、Power Automateで活用するには必須のテクニックだと思います。こういう方法があるよ!と知って使ってもらえればありがたいです。
第2弾はPower BIで
この記事は2025年のアドベントカレンダー向けに作成しました。CSVの取り込みについて、もうひとつPower BIを使った取り込みについてアイディアを別の記事に書いてみますので、そちらも参考にしていただけると嬉しいです。
Power BIアドベントカレンダー 2025/12/10 に登録してます。
こんな人が書いてます。
職場でPower Platformの管理者さんをしています。ブログではPower AutomateのTipsのようなものを書いています。QiitaではPower BIとクラウドフローのちょこ技を記事にしています。そちらも読んで「いいね」などしていただけるととっても喜びます。
大阪開催Power Platform系のイベントやオンラインの集まりには時々参加していますので、こちらのアイコンを見かけたら声をかけていただけると嬉しいです。















