GASのforEach徹底解説!配列操作から二次元配列処理・アロー関数活用まで

Google Apps Script(GAS)を使うと、スプレッドシートやドキュメントの操作を自動化できます。その中でも配列処理によく登場するのが「forEach」です。コードを簡潔に書ける便利な関数ですが、実は「非推奨」という声もあり、使い方によっては効率が落ちることもあります。本記事では、forEachの基本から二次元配列やアロー関数での活用まで、ビジネス現場で役立つ使い方を徹底的に解説します。


目次

forEachを使うメリットと非推奨とされる理由は何か

forEachはJavaScript由来の配列メソッドで、配列の各要素に対して順番に処理を行います。GASでも同様に使えるため、スプレッドシートのデータ処理に便利です。ただし「gas foreach 非推奨」と検索されることもあり、注意点があります。

forEachが便利な理由

  • コードが短くなる
    ループ処理をfor文で書くよりもすっきりし、読みやすさが増します。
  • 可読性が高い
    「配列に対して順番に処理している」と一目でわかるのが大きな利点です。
  • コールバック関数で柔軟に処理できる
    関数を渡して処理を組み立てやすくなります。

非推奨とされる場面

しかし、すべての状況で最適というわけではありません。業務で扱うデータが数千行を超えるようなケースでは、forEachよりも従来のfor文の方が処理速度が安定します。その理由は、forEachが関数呼び出しを繰り返す仕組みのため、オーバーヘッドが大きくなるからです。

実際の事例

ある企業では、毎朝5,000件以上の売上データをGASで処理していました。最初はforEachを使っていましたが、処理が3分以上かかり、タイムアウトすることもありました。for文に切り替えたところ、処理時間が半分以下に短縮されたという事例があります。
つまり、小規模な配列には便利ですが、大量データでは向かないのです。

他業種・海外での比較

海外のエンジニアブログでも、forEachは「教育用・コードの可読性重視には向くが、ビッグデータ処理には不向き」とされています。これはExcel VBAやPythonのpandasでも同様で、大量データ処理にはループを避け、まとめて処理する方法が推奨されています。

失敗事例

初心者がよく陥るのは「forEachの中でbreakを使おうとする」ケースです。GASのforEachはbreakをサポートしていないため、処理を途中で止められません。この点も非推奨とされる一因です。


配列をforEachで処理する具体的な方法

では、実際にどのようにforEachを使えば効率的なのでしょうか。ここでは基本から応用まで、配列処理の実践例を紹介します。

基本の書き方

let fruits = ["apple", "banana", "orange"];
fruits.forEach(function(item, index) {
  Logger.log(index + ": " + item);
});

このコードでは、配列の各要素を順に取り出してログに表示します。第一引数は要素そのもの、第二引数はインデックス番号です。

アロー関数を使った簡潔な書き方

近年は「gas foreach アロー関数」で検索する人も増えています。アロー関数を使うとさらにシンプルです。

fruits.forEach((item, index) => Logger.log(`${index}: ${item}`));

コード量が減り、モダンな書き方として推奨されます。

ビジネス現場での事例

例えば営業リストを配列に格納しておき、各営業担当者に割り当てメールを送る処理をforEachで実装できます。可読性の高いコードにすることで、他のメンバーがメンテナンスしやすくなる効果があります。

メリットとデメリット

  • メリット:可読性・保守性が高い
  • デメリット:大量データでは処理速度が落ちる

実践手順

  1. 配列を準備する
  2. forEachを使って一要素ごとに処理を書く
  3. アロー関数で短縮できる部分は省略する
  4. 大量データの場合はfor文やmapとの使い分けを検討する

この流れを守るだけで、初学者でも安全に配列処理を行えます。


二次元配列をforEachで処理するときのコツ

スプレッドシートを扱うGASでは、二次元配列の処理が欠かせません。getValues()で取得したデータは必ず二次元配列として返されるためです。

二次元配列の扱い方

let data = sheet.getDataRange().getValues();
data.forEach(function(row) {
  Logger.log(row[0] + " - " + row[1]);
});

このコードでは、各行を配列として取り出し、1列目と2列目をログに出力します。
つまり、外側のforEachで「行」をループし、内側のインデックス指定で「列」にアクセスする形です。

実際の業務での利用

人事部で従業員リストを管理しているケースを考えてみましょう。数百人分の名前と部署をスプレッドシートにまとめ、そのデータをforEachで一行ずつ読み取り、自動的に部署ごとのメールリストを作成することができます。

注意点

ただし、ここでもデータ量が多い場合は注意が必要です。1万行以上のデータをforEachで処理すると処理落ちすることがあるため、二次元配列を一度に処理せず、必要な列だけを抽出してまとめて加工する方が効率的です。

他業種との比較

海外の開発者は「二次元配列はmapやreduceを使うと効率的」と紹介しています。特にPythonユーザーからは「forEach的な逐次処理よりもベクトル処理を意識せよ」という声が多く、GASでも同じ考え方が有効です。

失敗事例

二次元配列をforEachで処理する際、row[1]のように列を指定することを忘れてしまい、意図しない「行全体」を出力してしまうケースがよくあります。これでは正しい集計ができません。インデックス指定を必ず確認しましょう。

forEachでbreakできないときの対処法

GASでforEachを使っていると、「途中で処理を止めたい」と思う場面が出てきます。しかしご存じの方も多いように、forEachにはbreakreturnでループ全体を抜ける仕組みがありません。そのため「gas foreach break」で検索する方も多いのです。

なぜbreakできないのか

forEachは「配列の全要素を順に処理する」ことを前提に設計されています。そのため、途中で処理を止めるという概念がないのです。これが可読性や安全性を保つための設計意図ですが、大量データを扱うビジネスシーンでは不便に感じることもありますよね。

実際の業務での失敗例

営業部で売上データを検索する処理をforEachで書いた社員がいました。最初に見つけた条件一致のデータだけを取得したかったのですが、forEachでは全件走査してしまい、無駄に時間がかかってしまったのです。結局、for文に書き直すことで解決しました。

解決策のパターン

  • for文に書き換える
    breakを使いたい場合はfor文を選択するのが王道です。処理速度の面でも有利になります。
  • some()やevery()を活用する
    これらの関数は条件に応じて途中でループを抜けられるため、breakの代替になります。
  • filter()やfind()を使う
    配列から条件に合う要素を取り出したい場合は、専用のメソッドを使う方が効率的です。

まとめ

forEachを万能だと思って使うと「breakできない」という落とし穴にはまります。意図に合わせて他のループ処理やメソッドを選択することが、ビジネス現場での効率化につながりますよ。


for文やfor…inとの使い分け

forEachと並んでよく使われるのがfor文やfor…inです。これらをどう使い分ければいいのかを整理しておきましょう。

for文の特徴

  • メリット:breakやcontinueが使えるため、処理を柔軟に制御できる
  • デメリット:コード量が少し長くなる

for文は特に「途中で処理を止めたい」「一部だけスキップしたい」ときに有効です。

for…inの特徴

for…inはオブジェクトのプロパティをループするための構文です。配列にも使えますが、順序が保証されないため業務データ処理には不向きです。

実務での事例

ある経理部門では、数万件の会計データを処理するスクリプトを作成していました。最初はforEachで組んでいたものの、不要なループが発生して処理が遅延。for文に切り替えたところ、処理時間が約30%削減されたのです。

比較まとめ

  • forEach:読みやすさ重視、小規模データ向け
  • for文:制御が必要、大規模データ向け
  • for…in:オブジェクト操作向け

シンプルに言うと、読みやすさを取るならforEach、パフォーマンスや制御を取るならfor文、という使い分けが良いですよ。


アロー関数で効率化する方法

GASはES6以降の記法をサポートしているため、forEachとアロー関数を組み合わせると、さらに効率的に書けます。

書き方の違い

通常のforEach:

fruits.forEach(function(item, index) {
  Logger.log(index + ": " + item);
});

アロー関数を使った書き方:

fruits.forEach((item, index) => Logger.log(`${index}: ${item}`));

コード量が減り、可読性も向上します。

実際の業務での効果

人事部の担当者が、従業員名簿から条件に合う社員を抽出するスクリプトを書いたとき、アロー関数で記述することで行数が半分になり、メンテナンスがしやすくなったという声もあります。

注意点

ただし、アロー関数には「this」の扱いが通常の関数と異なる点があり、初心者は混乱することがあります。スプレッドシート操作のように「this」を意識しない処理では問題ありませんが、オブジェクトを扱う際は注意しましょう。

海外の開発者の声

海外のGASエンジニアブログでは「ビジネスでのスクリプトはメンテナンス性が大事なので、アロー関数で簡潔に書くのは有効」という意見が多く見られます。特にチームでの開発では短いコードの方が理解しやすく、エラーのリスクも減らせるからです。


まとめ

GASでのforEachは、配列や二次元配列を直感的に扱える便利なメソッドです。アロー関数と組み合わせることで効率的に書けますが、大量データや途中でループを止めたいケースでは不向きです。その場合はfor文や他の配列メソッドを選択するのが賢い方法です。

  • forEachは可読性重視
  • for文は制御や速度重視
  • アロー関数で効率化可能
  • breakが必要ならfor文や他メソッドを選ぶ

つまり、業務の規模や目的に応じて「道具を選ぶ」ことが一番大切です。この記事を読んだあなたが、明日からのGAS開発で最適なループ処理を選択できるようになれば嬉しいです。

今週のベストバイ

おすすめ一覧

資料ダウンロード

弊社のサービスについて詳しく知りたい方はこちらより
サービスご紹介資料をダウンロードしてください