Power Automateを使えばSPOやOnDriveで管理されているExcelファイルを開いて内容を読み込むことができます。
データ取得のためしばしば利用するアクションは "テーブル内に存在する行を一覧表示" です。
数件から数十件のデータを扱っているうちはこれでよいのですが、数百件数千件のデータを扱い始めるとすぐに問題が生じます。
Problem
PowerAutomateにおける他の複数データ処理系アクションと同じく、 "テーブル内に存在する行を一覧表示" にも処理できる件数の上限があります。他の方の記事でも言及されている通り、設定やライセンスにもよりますが、ようするに上限があることに変わりありません。数百数千件のデータ処理のシーンでこの制限があることは煩わしいものです。
Solution
解決策には "テーブル内に存在する行を一覧表示" の改ページ設定を用いるものや、 "Do Until" アクションを用いるものなども考えられますが、「目的のためには手段を選ばない」ということならば、 "スクリプトの実行" による解決策の採用も選択肢に入ってきます。
まずスクリプトを作成します:
function main(workbook: ExcelScript.Workbook, tableName: string)
{
const table = workbook.getTable(tableName);
const columns = table.getColumns().map(c => c.getName());
return JSON.stringify(
table.getRangeBetweenHeaderAndTotal().getValues().map(row => {
const map = {};
columns.forEach((colName, colIdx) => {
map[colName] = row[colIdx];
});
return map;
})
);
}
main
関数内では、引数で名前指定されたテーブルからすべてのレコード(ヘッダーと集計行を除く)を取得しています。
このままではまだ二重配列です。
イメージ: [ [ "R1C1 value", "R1C2 value", "R1C3 value" ], [ "R2C1 value", "R2C2 value", ... ], ... ]
これでよければ map()
関数呼び出しは不要で JSON.stringif()
に結果を渡すだけで終わりです。
ただし今回この例の元になったデータ利用シーンではレコードが連想配列である必要があったので、 map()
関数を呼び出して変換処理を行っています。
イメージ: [ { "col1": "R1C1 value", "col2": "R1C2 value", ... }, { ... }, ... ]
そして結果を JSON.stringif()
に渡してJSON文字列を生成して返します。
OfficeScriptsの main
関数ではプリミティブの配列を戻すことはできるのですが、オブジェクトの配列を戻すことができません。このためJSON文字列に変換(シリアライズ)してやる必要があります。
こうして作成したスクリプトを使うフローは次のような構成になります:
"作成" アクションで json()
関数を用いて JSOM文字列からオブジェクトの配列への変換(デシリアライズ)を行っています。
json(outputs('スクリプトの実行')?['body/result'])
これでアクションによる件数の制約なしにテーブルのデータを読み取ることができます。
いうまでもなくこの方法は「推奨される」ものではありませんが、件数が膨大、フローを複雑にしたくないなど、あれこれ考慮した末に残る選択肢の1つではあります。