【Googleスプレッドシート】Apps Scriptで配列を高速処理!getValues→処理→setValues

【Googleスプレッドシート】Apps Scriptで配列を高速処理!getValues→処理→setValues
🛡️ 超解決

スプレッドシートで大量のデータを処理するとき、セルを1つずつループで更新すると、とても時間がかかってしまいます。Apps Scriptでは、getValuesで一括取得した配列をJavaScriptで高速に処理し、setValuesで一括書き戻すことで、処理時間を大幅に短縮できます。この記事では、getValuesとsetValuesを使った配列一括処理の具体的な手順と注意点を解説します。これを覚えれば、日常のスプレッドシート作業が格段に速くなります。

【要点】getValues→配列処理→setValuesの3ステップで高速処理を実現します

  • getValues: シートのデータを二次元配列として一括で取得します。セル1つずつ読み込むよりも高速です。
  • 配列処理: JavaScriptのmapやforEachを使って配列内のデータを一括変換します。ループの負荷が軽減されます。
  • setValues: 処理後の二次元配列をシートに一括書き込みます。セル1つずつ書き込むよりも圧倒的に速いです。

ADVERTISEMENT

getValuesとsetValuesで高速処理ができる仕組み

スプレッドシートのセルにアクセスするたびに、Apps Scriptとシートの間で通信が発生します。セルを1つずつループで操作すると、通信回数が多くなり処理が遅くなります。一方、getValuesで範囲を一括取得すると、1回の通信でデータが二次元配列として手に入ります。同様にsetValuesで一括書き込みするのも1回の通信です。このため、通信回数が劇的に減り、処理速度が向上します。特に数千行・数百列のデータを扱う場合、体感できるほど速くなります。

getValues→処理→setValuesの基本手順

ここでは、A列の数値に10を加算してB列に書き込む簡単な例を使い、手順を説明します。実際のコードはGoogle Apps Scriptのエディタで作成します。

データを取得する(getValues)

  1. スクリプトエディタを開く
    スプレッドシートのメニューから「拡張機能」→「Apps Script」を選択します。
  2. 取得したい範囲を指定する
    データがA1:A10にある場合、getRange(‘A1:A10’)で範囲を指定します。
  3. getValuesで二次元配列を取得する
    const data = sheet.getRange(‘A1:A10’).getValues(); と記述します。dataは[[1],[2],[3],…]のような二次元配列になります。

配列をJavaScriptで処理する

  1. mapメソッドで各要素を変換する
    const processed = data.map(row => [row[0] + 10]); と書きます。row[0]は元の値、それに10を加えた新しい配列を作ります。
  2. 条件分岐を含めることも可能
    if文を使って特定の値だけ変換するなど、自由に処理を加えられます。
  3. 元の配列を直接書き換えない
    mapは新しい配列を返すので、元のデータは保持されます。必要に応じてforEachで直接変更も可能です。

処理結果を書き戻す(setValues)

  1. 書き込み先の範囲を取得する
    結果をB1:B10に書き込む場合、 getRange(‘B1:B10’) と指定します。
  2. setValuesで一括書き込みする
    sheet.getRange(‘B1:B10’).setValues(processed); と記述します。processedの行数と列数が範囲と一致している必要があります。
  3. 実行して結果を確認する
    スクリプトエディタで再生ボタンをクリックすると、B列に10加算された値が表示されます。

この3ステップが基本の流れです。実際にはさらに複雑な処理も可能で、例えば複数列をまとめて取得して変換することもできます。

実践的なコード例と応用

次に、複数列のデータを処理する例を紹介します。A列に名前、B列に金額があり、金額に消費税を加えてC列に書き込むケースです。

複数列の一括処理

  1. データを取得する
    const data = sheet.getRange(‘A1:C100’).getValues(); とします。dataは[[name, amount, ”], …]のような二次元配列です。
  2. mapでC列に計算結果を追加する
    const result = data.map(row => {
    const tax = row[1] * 0.1;
    return [row[0], row[1], tax];
    }); とします。
  3. 結果を書き戻す
    sheet.getRange(‘A1:C100’).setValues(result); で一括書き込みします。

大量データのフィルタリング

例えば、売上データから特定の条件を満たす行だけを取り出して別シートに転記する場合も、配列操作が便利です。filterメソッドを使って条件を満たす行だけを抽出し、setValuesで書き込めば、高速に処理できます。

ADVERTISEMENT

よくある失敗と注意点

配列の行数と書き込み範囲が一致しない

setValuesで書き込むとき、配列の行数と列数が書き込み範囲と完全に一致していないとエラーになります。例えば、10行のデータを5行の範囲に書き込もうとするとエラーです。必ず同じサイズの範囲を指定してください。

二次元配列の構造を間違える

getValuesは常に二次元配列を返します。1列だけでも[[1],[2]]のような形式です。処理後も二次元配列のままsetValuesに渡す必要があります。一次元配列を渡すとエラーになるので注意してください。

空のセルがundefinedになる

getValuesで空のセルは空文字列”ではなくundefinedになることがあります。処理する前にundefinedの場合は空文字に変換するなど、データを整えてから計算するようにしましょう。

処理に時間がかかる場合

配列処理自体は高速ですが、数十万行のデータになるとJavaScriptのループにも時間がかかります。その場合は、スプレッドシートのQUERY関数やARRAYFORMULAを併用することも検討してください。

セル単位ループと配列一括処理の比較

項目 セル単位ループ 配列一括処理
通信回数 セルの数だけ通信 2回(get,set)
速度(1000行程度) 数秒〜数十秒 1秒未満
コードの複雑さ シンプル やや複雑(配列操作に慣れが必要)
メモリ消費 少ない データを一括保持するためやや多い
エラー発生時のリスク 一部分だけの変更で済む 全データが書き換わるので注意が必要

表からわかるように、大量データを扱う場合は配列一括処理が圧倒的に有利です。ただし、データ量が非常に少ない場合や、途中でエラーが起きても影響を最小限にしたい場合は、セル単位ループも選択肢になります。

まとめ

getValuesでデータを一括取得し、JavaScriptの配列メソッドで処理してからsetValuesで書き戻す方法を解説しました。この手法を使えば、通信回数が減り、大量データの処理時間を大幅に短縮できます。特に毎日数百行以上のデータを扱う業務では、スクリプトの実行時間が数十分から数秒に改善されることもあります。ぜひ実際のスプレッドシートで試し、繰り返し処理を自動化してください。応用として、IMPORTRANGEで取り込んだデータの整形や、QUERY関数では難しい条件処理にも活用できます。


ADVERTISEMENT

この記事の監修者
✍️

超解決 第一編集部

疑問解決ポータル「超解決」の編集チーム。正確な検証と、現場視点での伝わりやすい解説を心がけています。