GASの範囲一括更新は大事という話

2025/01/04に公開

この記事の概要

GASにはタイムアウトの時間が設定されており、一度の実行時間は最大6分までと決められています。
GASはスプレッドシートで使うことが多く、何かしらをスプレッドシートに出力することが多くあると思いますが、
Excel(VBA)の感覚でセルを走査⇒出力するとなかなか時間がかかり、痛い目を見ることがちょくちょくあります。

じゃぁ実際どれだけ違うのか?ということを簡単に検証してみました。

実際に試してみた

プログラムはGemini君に書いてもらいました。
10000列ただ数字を羅列するだけの簡単なお仕事です。
開始時刻と終了時刻を記録し、結果をmsgBoxで出力します。

走査する場合

outputToSheet.gs
function outputToSheet() {
  // 処理開始時刻を記録
  var startTime = new Date().getTime();

  // シートを取得 
  var sheet = SpreadsheetApp.getActiveSheet();

  // 10000個の要素を持つ配列を作成 (例)
  var data = [];
  for (var i = 1; i <= 10000; i++) {
    sheet.getRange(1,i).setValue(i);
  }
  // 処理終了時刻を記録
  var endTime = new Date().getTime();

  // 処理時間を計算し、アラートで表示
  var elapsedTime = endTime - startTime;
  Browser.msgBox("処理時間: " + elapsedTime/1000 + " 秒");
}


31.123秒かかりました。
これだけの処理内容なのに、意外と時間がかかる。

一括出力する場合

setValuesは一次元配列を受け入れないため、二次元配列に変換しています。

outputToSheet.gs
function outputToSheet() {
  // 処理開始時刻を記録
  var startTime = new Date().getTime();

  // 10000個の要素を持つ配列を作成 (例)
  var data = [];
  for (var i = 1; i <= 10000; i++) {
    data.push(i);
  }

  //2次元配列化
  var data_2d = [data]

  // シートを取得
  var sheet = SpreadsheetApp.getActiveSheet();

  // A1セルからデータの行数分だけ範囲を指定し、データを書き込み
  sheet.getRange(1, 1, data_2d.length, data_2d[0].length).setValues(data_2d);

  // 処理終了時刻を記録
  var endTime = new Date().getTime();

  // 処理時間を計算し、アラートで表示
  var elapsedTime = endTime - startTime;
  Browser.msgBox("処理時間: " + elapsedTime/1000 + " 秒");
}


0.4秒でした。
歴然の差がありますね。

終わりに

走査する場合:31.123秒
一括出力する場合:0.4秒
⇒その差、およそ30秒!

今回は数字をただ出力するだけでしたが、
実際はもっといろんな処理を実装しますし、これを意識するだけでかなり処理実行時の快適さが変わってくると思われます。
ぜひ意識してみてください。

おまけ

Excel(VBA)でも同じことをやってみました。
結果そんなにGAS程差異はないですが、積み重ねかもしれません。

走査する場合


0.13秒でした。

一括出力する場合


0.01秒でした。
(全部数字が1になっているのはご愛敬。
 きっと影響はないでしょう。。。)

Discussion