本サイトはアフィリエイト広告(A8.net/もしもアフィリエイト/アクセストレード等)を利用しています
GASループfor文5種類使い分け完全マスター|for/for…of/forEach/while徹底比較
📂 GAS入門

GASループfor文5種類使い分け完全マスター|for/for…of/forEach/while徹底比較

📅 ⏱ 読了 約8分 ✍️ 凛

💡 本記事には広告(アフィリエイトリンク)が含まれる場合があります。

こんにちは、凛です。2児のママで現役ナース。夜勤明けの細切れ時間を副業GASに投じ、月5〜8万円の副収入を継続中。「看護師でもコードは書ける」を合言葉に、家事育児とプログラミングを両立する等身大の情報を発信しています。本記事のコードは静的検証済みです(構文・API仕様・ロジックを確認)。今日は「GASのfor文」について、5種類の書き方とその使い分けをがっつり解説します。ループが書けるようになると、スプレッドシートの自動処理が一気に楽になりますよ。

「GAS for文」で検索してここに来た方が、読み終わったあとすぐコードに戻れるレベルを意識して書いています。

こんな悩みありませんか?

  • for文は書けるけど、forEachとの違いがモヤっとしてる」
  • for...offor...inってどっちを使えばいいの?」
  • 「ループの書き方が毎回同じで、コードがダサい気がする」
  • forEachで途中で抜けたいのにbreakが効かない」
  • 「無限ループになってGASが強制終了した…」

私も昔は全部for (var i = 0; i < arr.length; i++)でゴリ押ししてました。でも配列操作ばかりの勤怠集計を書くうちに、「これforEachにしたほうが読みやすいな」「これはfor...ofが自然だな」と気づいたんです。

GASで使える5種類のループ全体像

書き方向いている場面break/continue
forインデックスが必要/途中でbreakしたい
for...of配列の要素を順に使いたい
for...inオブジェクトのキーを回したい
forEach配列に対して関数を適用したい
while終了条件が回数で決まらない

全部使えるようになる必要はありません。実務で日常的に使うのは for / for...of / forEach の3つで十分です。まずはこの3つを使いこなせるようになると、コードがグッと読みやすくなります。

主役3種類の使い分け

1. 古典的なfor:インデックスが主役

スプレッドシートの2次元配列を回すときの定番。

function sumColumn(values) {
  let total = 0;
  for (let i = 0; i < values.length; i++) {
    total += values[i][0]; // 1列目を合計
  }
  return total;
}

iというインデックスが使えるので、**「最初の行だけスキップ」「途中でbreak」**みたいな制御も自由自在。ヘッダー行を飛ばしたいならi = 1から始めればOK。

for (let i = 1; i < values.length; i++) {
  // ヘッダーを除いて処理
}

forbreakcontinue

途中で抜けたいときはbreak、その回だけスキップしたいならcontinue

for (let i = 0; i < values.length; i++) {
  if (values[i][0] === '') continue; // 空行はスキップ
  if (values[i][0] === 'END') break;  // ENDで打ち切り
  // 本処理
}

2. for...of:要素が主役

インデックスが要らないときはfor...ofがスッキリ。

const names = ['長女', '次女', '三女'];
for (const name of names) {
  console.log(name + 'さんに連絡する');
}

forより短くて読みやすい。breakcontinueも使えるので、途中で抜ける処理もOKです。

2次元配列×分割代入が最強コンビ

スプレッドシートから取ったvaluesは2次元配列なので、for...of+分割代入で1行ずつ取り出すのが一番読みやすいです。

const values = sheet.getDataRange().getValues();
for (const [name, age, shift] of values) {
  console.log(`${name}(${age}): ${shift}`);
}

列名で取り出せるので、row[0]row[1]みたいな数字だらけのコードから卒業できます。

3. forEach:関数型っぽく書く

配列のメソッドとして関数を渡す書き方。

const prices = [100, 200, 300];
prices.forEach((price, index) => {
  console.log(`${index}番目:${price}円`);
});

第2引数にindexが取れるので、「何番目の要素か」も扱えます。

最大の注意点:forEachbreakできません。最後まで回し切ります。途中で止めたいならforfor...ofを選びましょう。returnを書いても、その1回分がスキップされるだけで次の要素に進みます。

prices.forEach((price) => {
  if (price > 200) return; // その回だけスキップ(continueと同等)
  console.log(price);
});
// breakはできないので、大きな配列を途中で切り上げたい時は不向き

残り2つ:for...inwhile

for...inはオブジェクト向け

const user = { name: '佐藤', role: 'ナース', shift: '夜勤' };
for (const key in user) {
  console.log(key + ': ' + user[key]);
}

配列に使うと順番が保証されないケースがあるので、配列にはfor...offorEachを推奨。for...inはオブジェクトのキー列挙専用と覚えるのが安全です。

whileは条件ループ

回数が決まっていない処理に。

let row = 1;
while (sheet.getRange(row, 1).getValue() !== '') {
  row++;
}
// 最初の空セルの行番号がrowに入る

スプレッドシートで「値がある行だけ処理」みたいなケースで使えます。

無限ループ対策:GASの6分制限とセットで覚える

whileは本当に無限ループに注意。ナイトシフトで無限ループを仕込んでGASが6分で強制終了した経験、私あります…。

対策は3つ。

  1. 最大回数を必ず用意する
let count = 0;
while (condition) {
  if (count++ > 10000) break; // 保険
  // 処理
}
  1. 条件に確実に変化する処理を書く:ループ内で条件変数が更新されるか毎回確認

  2. 開発中はconsole.logで周回数を確認

while (condition) {
  console.log('loop count:', count);
  count++;
}

GASには6分の実行時間上限があるので、無限ループは即トリガー失敗になります。詳しくは GAS6分制限を回避する3パターン完全解説 で。

実務で迷ったときの選び方フローチャート

状況選ぶループ
2次元配列を行ごとに回すfor(インデックスが要るとき)or for...of+分割代入
配列の中身だけ見るfor...of
各要素に同じ処理を適用するforEach
途中で抜けたいforfor...offorEachは不可)
回数が決まっていないwhile
オブジェクトのキーが欲しいfor...in

パフォーマンスの豆知識

大量データを扱うときは ループ内でSpreadsheet APIを叩かないのが鉄則です。

// ❌ 遅い:ループの中で毎回 setValue
for (let i = 0; i < data.length; i++) {
  sheet.getRange(i + 1, 1).setValue(data[i]); // 毎回API呼び出し
}

// ✅ 速い:配列にまとめて最後に setValues
const output = data.map((v) => [v]);
sheet.getRange(1, 1, output.length, 1).setValues(output); // 1回だけ

1,000行あれば、前者は数十秒、後者は1秒以下で終わります。GASのAPI呼び出しは1回あたりのオーバーヘッドが大きいことを覚えておきましょう。

まとめ

  • インデックスが欲しいならfor、いらないならfor...of
  • 要素に処理を適用するだけならforEach(ただしbreak不可)
  • オブジェクトのキーはfor...in、条件で回すならwhile
  • 2次元配列にはfor...of+分割代入が鉄板
  • whileは必ず脱出保険を入れる。6分制限に注意
  • 大量データはループ内でAPIを叩かず、最後に一括setValues

5種類と聞くと身構えますが、日常で使うのはfor/for...of/forEachの3つです。ここさえ押さえれば、GASのループで困ることはまずありません。

関連記事


この記事を書いた人:凛

2児のママで現役ナース。夜勤明けの細切れ時間を副業GASに投じ、月5〜8万円の副収入を継続中。「看護師でもコードは書ける」を合言葉に、家事育児とプログラミングを両立する等身大の情報を発信しています。本記事のコードは静的検証済みです(構文・API仕様・ロジックを確認)。