Google Apps Script(GAS)入門|コピペで動くスプレッドシート自動化レシピ5選

スポンサーリンク

Google Apps Script(GAS)入門|コピペで動くスプレッドシート自動化レシピ5選

「毎月同じスプレッドシート作業を繰り返していて、もう限界…」そんな悩みを解決するのが Google Apps Script(GAS)です。Excel でいうマクロ・VBA のスプレッドシート版で、JavaScript の知識ゼロからでも使い始められます。

この記事では、GAS の正体から最初のコード実行までを丁寧に解説します。あわせて、コピペするだけで動く5つの自動化レシピを紹介します。タイムスタンプ自動入力、重複行の一括削除、月別シート分割など、明日から業務で使えるパターンばかりです。

VBA を触ったことがない方でも、画面の通りに手を動かせば最初の自動化が完成します。ぜひ実際にスプレッドシートを開きながら読み進めてください。

  1. Google Apps Script(GAS)とは?|スプレッドシートを自動化する仕組み
  2. GAS でできることとできないこと
    1. GAS が得意なこと
    2. GAS が苦手・できないこと
  3. スクリプトエディタを開く手順|初回の権限承認まで
    1. スクリプトエディタの開き方
    2. 最初のコードを書いて保存する
    3. 初回の権限承認を突破する
  4. 【レシピ1】タイムスタンプを自動入力する
    1. コピペで動くコード
    2. 動かし方
    3. カスタマイズのヒント
  5. 【レシピ2】指定列で重複行を一括削除する
    1. コピペで動くコード
    2. 動かし方
    3. カスタマイズのヒント
  6. 【レシピ3】指定列の合計をポップアップ表示する
    1. コピペで動くコード
    2. 動かし方
    3. ボタンから呼び出せるようにする
    4. カスタマイズのヒント
  7. 【レシピ4】データを月別シートに自動分割する
    1. コピペで動くコード
    2. 動かし方
    3. カスタマイズのヒント
  8. 【レシピ5】入力で行の色を自動変更する
    1. コピペで動くコード
    2. 動かし方
    3. レシピ1と併用したい場合の注意
    4. カスタマイズのヒント
  9. GAS でつまずきやすいポイントとトラブルシュート
    1. つまずき1: onEdit が動かない
    2. つまずき2: 「Exceeded maximum execution time」と表示される
    3. つまずき3: 行・列番号で 0 を指定してエラー
    4. つまずき4: 月の値が1ずれる
    5. つまずき5: 数字を書き込んだのに文字列扱いになる
    6. つまずき6: 実行ボタンを押すと「関数を選択してください」と出る
    7. つまずき7: スクリプトが遅い
  10. 次のステップ|GAS でさらに自動化を広げるには
    1. 定期実行(時間ベーストリガー)
    2. Googleフォームの回答に応じた自動処理
    3. スプレッドシートからのメール自動送信
    4. ライブラリと外部API連携
    5. おわりに

Google Apps Script(GAS)とは?|スプレッドシートを自動化する仕組み

Google Apps Script(GAS、ガス)は、Google が提供する自動化のためのプログラミング環境です。スプレッドシートや Gmail、Googleフォーム、Googleカレンダーなど、Google のサービス全体を操作できます。

VBA との比較で押さえておきたいのは次のポイントです。

項目Excel VBAGoogle Apps Script
言語ベースVBA(Visual Basic for Applications)JavaScript
実行環境ローカルPCの ExcelGoogle のクラウド上
実行方法Excel ファイルを開いて F5 / マクロ実行スクリプトエディタの実行ボタン、ボタン、トリガー
料金Excel に同梱個人の Google アカウントで無料
共有ファイルごとマクロ付きで配布スプレッドシートに紐付くため、共有編集者にも届く

イメージとしては「ブラウザ版の VBA」です。コードを書く場所はスプレッドシートの中にあり、実行は Google のサーバーで行われます。PC のスペックや Office のバージョンに左右されないのが大きな利点です。

なお、Excel VBA とマクロの関係をおさらいしたい方は、Excel VBAとマクロの違いをやさしく整理 も参考にしてください。

GAS でできることとできないこと

GAS が初学者でも実用レベルで使える領域は意外と広く、逆に苦手な領域もはっきりしています。最初に向き不向きを把握しておくと、学習の方向を間違えずに済みます。

GAS が得意なこと

  • スプレッドシートの値の取得・書き込み(行ごとの一括処理が高速)
  • 編集時の自動処理(onEdit などのトリガー)
  • 時刻指定の定期実行(毎朝9時に集計を更新するなど)
  • Gmail 経由でのメール自動送信
  • Googleフォームの回答に応じた自動処理
  • HTTP リクエストで外部 API と連携

GAS が苦手・できないこと

  • ピボットテーブルやチャートの細かい編集(一部は可能だが制限あり)
  • Excel ファイル(.xlsx)独自の機能(条件付き書式の高度な設定、Power Query など)
  • グラフィカルなフォーム UI(簡易ダイアログは作れるが、本格的なアプリは別ツールが向く)
  • ローカル PC のファイル操作(クラウド上で動くため)
  • 1 回 6 分を超える長時間処理(実行時間制限)

業務改善の入り口としては「同じスプレッドシートに対する繰り返し作業」を自動化するのが鉄板です。

スクリプトエディタを開く手順|初回の権限承認まで

最初の関門は「エディタを開いて、サンプルコードを動かしてみる」ところです。ここを越えれば後はコピペでどんどん試せるので、丁寧にやってみましょう。

スクリプトエディタの開き方

任意のスプレッドシートを開いた状態で、上部メニューから次の通り進みます。

  1. メニューバーの 拡張機能 をクリック
  2. 開いたメニューから Apps Script を選択
  3. 別タブでスクリプトエディタが開く

NOTE: 古い記事では「ツール → スクリプトエディタ」と書かれていることがあります。現在のメニュー位置は 拡張機能 配下です。Excel VBA でいう Alt + F11 で VBE を開く操作にあたります。

最初のコードを書いて保存する

エディタを開くと function myFunction() { } という空の関数が用意されています。試しに次のコードに書き換えてみましょう。

function helloGas() {
  // --- スプレッドシートのアクティブセルに文字を書き込む ---
  SpreadsheetApp.getActiveRange().setValue("こんにちは GAS");
}

書き換えたら、上部のフロッピーアイコン(保存)をクリックします。スプレッドシート側で適当なセルを選択した状態に戻し、エディタに戻って実行ボタン(▶)を押してください。

初回の権限承認を突破する

実行ボタンを押すと、初回だけ権限承認の確認が出ます。手順は次の通りです。

  1. 「承認が必要です」ダイアログで 権限を確認 をクリック
  2. 自分の Google アカウントを選択
  3. 「Google で確認されていません」と表示されたら 詳細 をクリック
  4. 一番下の「(プロジェクト名)に移動(安全ではないページ)」をクリック
  5. 必要な権限を確認して 許可 をクリック

「安全ではないページ」という表現にひるみますが、これは自分で書いたスクリプトが Google の審査を受けていないために出るメッセージです。同じプロジェクトでは初回の1回だけ表示され、2回目以降は出ません。

承認が完了すると、スプレッドシート側の選択していたセルに「こんにちは GAS」が書き込まれます。これで実行環境の準備は完了です。

【レシピ1】タイムスタンプを自動入力する

最初のレシピは、A 列に何かを入力したら、同じ行の B 列に入力日時が自動で記録されるしくみです。問い合わせ受付や作業ログのスプレッドシートで、入力者がいちいち日付を打たなくて済むようになります。

コピペで動くコード

スクリプトエディタの中身をすべて消して、次のコードを貼り付けてください。

function onEdit(e) {
  // --- 編集が起きたシートと範囲を取得 ---
  const sheet = e.source.getActiveSheet();
  const range = e.range;

  // --- A列(1列目)の2行目以降が編集された場合のみ処理 ---
  if (range.getColumn() === 1 && range.getRow() > 1) {
    // --- 同じ行のB列(2列目)に現在日時を書き込む ---
    sheet.getRange(range.getRow(), 2).setValue(new Date());
  }
}

動かし方

  1. 上記のコードをスクリプトエディタに貼り付けて保存
  2. スプレッドシート側に戻り、A 列の任意のセルに何か入力
  3. 同じ行の B 列に入力日時が自動で書き込まれる

実行ボタンを押す必要はありません。onEdit という名前の関数は「セルを編集したら自動で動く」予約済みの仕組みです。これを「シンプルトリガー」と呼びます。Excel VBA でいう Worksheet_Change イベントとほぼ同じ役割です。

カスタマイズのヒント

  • B 列ではなく C 列に書き込みたい場合は、getRange(range.getRow(), 2)23 に変更
  • A 列ではなく D 列が編集されたら反応させたい場合は、getColumn() === 114 に変更
  • 日付だけにしたい場合は、new Date() の代わりに Utilities.formatDate(new Date(), "Asia/Tokyo", "yyyy/MM/dd") を使う

NOTE: onEdit はスプレッドシート上で手動編集が起きたときに動きます。他のスクリプトから値を書き換えた場合や、API 経由で更新された場合は反応しないので注意してください。

【レシピ2】指定列で重複行を一括削除する

顧客リストやメールアドレス一覧で、同じ値の行が混ざっているときに使えるレシピです。1 列目(A 列)の値を見て、重複している行を取り除きます。

コピペで動くコード

function removeDuplicates() {
  const sheet = SpreadsheetApp.getActiveSheet();
  const data = sheet.getDataRange().getValues();

  // --- 1行目をヘッダーとして保持 ---
  const header = data[0];
  const rows = data.slice(1);

  // --- A列(1列目)の値で重複を判定 ---
  const seen = new Set();
  const unique = rows.filter(row => {
    const key = row[0];
    if (seen.has(key)) return false;
    seen.add(key);
    return true;
  });

  // --- シートをクリアしてヘッダー+ユニーク行を書き戻し ---
  sheet.clearContents();
  sheet.getRange(1, 1, 1, header.length).setValues([header]);
  if (unique.length > 0) {
    sheet.getRange(2, 1, unique.length, header.length).setValues(unique);
  }
}

動かし方

  1. コードを貼り付けて保存
  2. スクリプトエディタ上部の関数選択ドロップダウンで removeDuplicates を選択
  3. 実行ボタン(▶)をクリック
  4. シートが「ヘッダー + 重複なしの行」だけの状態に整う

カスタマイズのヒント

  • B 列で重複判定したい場合は row[0]01 に変更(配列は0始まりなので、A 列が0、B 列が1)
  • 複数列の組み合わせで重複判定したい場合は const key = row[0] + "_" + row[1]; のように連結

NOTE: 行を1つずつ削除するのではなく、いったん全データを配列で取り出して再書き込みする方式にしている点がポイントです。1000行あると100倍以上の速度差が出るので、自動化のクセとして覚えておくと役立ちます。

【レシピ3】指定列の合計をポップアップ表示する

D 列の数値の合計を、ボタン1つでパッと確認できるレシピです。月次集計の途中チェックや、フィルター後の確認に便利です。

コピペで動くコード

function showTotal() {
  const sheet = SpreadsheetApp.getActiveSheet();
  const lastRow = sheet.getLastRow();

  // --- D2 から最終行までの値を取得 ---
  const values = sheet.getRange(2, 4, lastRow - 1, 1).getValues();

  // --- 合計を計算(数値以外は0として扱う) ---
  const total = values.reduce((sum, row) => sum + (Number(row[0]) || 0), 0);

  // --- ポップアップで表示 ---
  SpreadsheetApp.getUi().alert(`D列の合計: ${total.toLocaleString()}`);
}

動かし方

  1. コードを貼り付けて保存
  2. 関数選択ドロップダウンで showTotal を選び、実行ボタンをクリック
  3. ポップアップで合計値が表示される

ボタンから呼び出せるようにする

毎回スクリプトエディタを開くのは手間なので、スプレッドシート上にボタンを置いてしまいましょう。

  1. スプレッドシートの 挿入 メニューから 図形描画
  2. 適当な四角形を描き、中に「合計表示」と書いて保存
  3. 配置された図形をクリック、右上の3点メニューから スクリプトを割り当て
  4. 入力欄に showTotal と入力して OK

これでシート上のボタンをクリックするだけで合計が表示されます。Excel VBA でフォームコントロールにマクロを登録する操作と同じ感覚です。

カスタマイズのヒント

  • 別の列で合計したい場合は getRange(2, 4, lastRow - 1, 1)4 を変更(C 列なら3、E 列なら5)
  • 平均値を表示したい場合は total / values.length を計算
  • 通貨記号を付けたい場合は ` D列の合計: ¥${total.toLocaleString()} ` のようにテンプレートリテラル内に追記

【レシピ4】データを月別シートに自動分割する

「データ」という名前のシートに日付付きの行データが入っている前提で、A 列の日付の月ごとに別シートへ自動振り分けします。月次レポート作成や売上データの整理で重宝するパターンです。

コピペで動くコード

function splitByMonth() {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const source = ss.getSheetByName("データ");
  const data = source.getDataRange().getValues();
  const header = data[0];
  const rows = data.slice(1);

  // --- 月ごとに行を仕分けるオブジェクトを準備 ---
  const grouped = {};

  rows.forEach(row => {
    // --- A列の日付から月を取得(getMonth は0始まりなので+1) ---
    const date = new Date(row[0]);
    const month = date.getMonth() + 1;
    const key = `${month}月`;

    if (!grouped[key]) grouped[key] = [];
    grouped[key].push(row);
  });

  // --- 月ごとにシートを用意して書き込み ---
  Object.keys(grouped).forEach(sheetName => {
    let target = ss.getSheetByName(sheetName);
    if (!target) target = ss.insertSheet(sheetName);

    target.clearContents();
    target.getRange(1, 1, 1, header.length).setValues([header]);
    target.getRange(2, 1, grouped[sheetName].length, header.length).setValues(grouped[sheetName]);
  });
}

動かし方

  1. スプレッドシートに「データ」という名前のシートを用意し、A 列に日付、B 列以降に任意の項目を入れておく
  2. コードを貼り付けて保存
  3. 関数選択ドロップダウンで splitByMonth を選び、実行ボタンをクリック
  4. 「1月」「2月」「3月」のように月ごとのシートが自動で作られ、データが振り分けられる

カスタマイズのヒント

  • 月ではなく年で分けたい場合は date.getFullYear() を使い、シート名を ${year}年 に変更
  • ソースシート名を変えたい場合は getSheetByName("データ") の文字列を書き換え
  • 元データはクリアせず追加するだけにしたい場合は target.clearContents(); の行を削除し、appendRow(row) で1行ずつ追加する形に書き換え

NOTE: date.getMonth() は1月が0、12月が11と返ってくる JavaScript の仕様です。表示用には必ず +1 してから使ってください。

【レシピ5】入力で行の色を自動変更する

タスク管理シートで C 列に「完了」と入力したら、その行全体に色を付けるレシピです。視覚的な進捗管理が一気にラクになります。

コピペで動くコード

function onEdit(e) {
  const sheet = e.source.getActiveSheet();
  const range = e.range;

  // --- C列(3列目)が編集された場合のみ処理 ---
  if (range.getColumn() !== 3) return;

  const row = range.getRow();
  const lastCol = sheet.getLastColumn();
  const targetRange = sheet.getRange(row, 1, 1, lastCol);

  if (e.value === "完了") {
    // --- 「完了」と入力されたら行全体を黄色に ---
    targetRange.setBackground("#fff2cc");
  } else {
    // --- 「完了」以外なら背景色をリセット ---
    targetRange.setBackground(null);
  }
}

動かし方

  1. コードを貼り付けて保存
  2. スプレッドシートに戻り、C 列のセルに 完了 と入力
  3. 同じ行が黄色く色付けされる
  4. C 列を空にしたり別の文字に書き換えると色が消える

レシピ1と併用したい場合の注意

レシピ1とレシピ5はどちらも onEdit という名前の関数です。同じスクリプト内に両方を貼り付けると、後に書いた方で上書きされてしまいます。両方使いたい場合は、1つの onEdit の中で列ごとに分岐させてください。

function onEdit(e) {
  const sheet = e.source.getActiveSheet();
  const range = e.range;
  const col = range.getColumn();
  const row = range.getRow();

  // --- A列が編集されたらB列にタイムスタンプ ---
  if (col === 1 && row > 1) {
    sheet.getRange(row, 2).setValue(new Date());
  }

  // --- C列が編集されたら行の色を変更 ---
  if (col === 3) {
    const lastCol = sheet.getLastColumn();
    const targetRange = sheet.getRange(row, 1, 1, lastCol);
    if (e.value === "完了") {
      targetRange.setBackground("#fff2cc");
    } else {
      targetRange.setBackground(null);
    }
  }
}

カスタマイズのヒント

  • 色を変えたい場合は "#fff2cc" を別のカラーコードに(薄い緑なら "#d9ead3"、薄い赤なら "#f4cccc"
  • 「完了」以外の文字をトリガーにしたい場合は e.value === "完了" を変更
  • C 列以外で反応させたい場合は col === 3 の数字を変更

GAS でつまずきやすいポイントとトラブルシュート

ここからは、初学者が最初の数本で必ずぶつかるトラブルと対処法をまとめておきます。エラーが出たときに上から確認していけば、たいていの問題は解決できます。

つまずき1: onEdit が動かない

考えられる原因は次の通りです。

  • 関数名が onEdit ではない(綴りミス、OnEdit のような大文字混在)
  • API や別のスクリプトから値を変更している(onEdit は手動編集にのみ反応します)
  • 認証が必要な処理(メール送信など)を onEdit 内で呼び出している
  • 同じファイル内に onEdit が複数あって後から書いた方で上書きされている

つまずき2: 「Exceeded maximum execution time」と表示される

GAS は1回の実行で6分の上限があります。多くは「ループ内で getValue()setValue() を呼んでいる」のが原因です。レシピ2やレシピ4のパターンを参考に、getValues() で配列を一括取得し、JavaScript 側で加工してから setValues() で一括書き戻す形に書き換えてください。

つまずき3: 行・列番号で 0 を指定してエラー

シート操作の getRange(行, 列) は1始まりです。A 列は1、B 列は2、最初の行は1。getRange(0, 0) は無効なのでエラーになります。一方で、getValues() で取得した二次元配列は JavaScript の配列なので0始まりになります。「シート操作は1始まり、配列処理は0始まり」と覚えておきましょう。

つまずき4: 月の値が1ずれる

new Date().getMonth() は1月が0、12月が11と返してくる仕様です。レシピ4のように +1 してから表示や比較に使ってください。

つまずき5: 数字を書き込んだのに文字列扱いになる

setValue("100") のように文字列で渡すと文字列として書き込まれます。数値として扱いたい場合は setValue(Number("100")) のように明示変換するか、シート側のセル書式を「数値」に設定しておきましょう。

つまずき6: 実行ボタンを押すと「関数を選択してください」と出る

スクリプトエディタ上部の関数選択ドロップダウンで、実行したい関数名を選んでから ▶ ボタンをクリックしてください。デフォルトでは最初に書かれた関数が選択されています。

つまずき7: スクリプトが遅い

シート操作 API(getValue, setValue, getRange など)の呼び出しは1回ずつが重い処理です。ループ内で繰り返し呼ぶと一気に遅くなるので、配列でまとめて取得・書き込みするのが鉄則です。

次のステップ|GAS でさらに自動化を広げるには

5つのレシピが動かせたら、もう自動化の入り口は越えています。ここからは、よくある「次に学びたい」テーマを軽く紹介しておきます。

定期実行(時間ベーストリガー)

時刻指定の自動実行は、スクリプトエディタ左側の時計アイコン(トリガー)から設定できます。「毎朝9時に集計を更新する」「毎週月曜にレポートシートを初期化する」といった使い方が定番です。onEdit のようなシンプルトリガーと違い、認証が必要な処理(メール送信など)も呼び出せます。

Googleフォームの回答に応じた自動処理

フォーム × GAS の組み合わせは業務改善の定番です。「フォームに回答が来たら関係者に通知メールを送る」「回答内容を別シートに整形してコピーする」といった処理を自動化できます。フォーム送信トリガーを使えば、回答が来た瞬間に処理が走ります。詳しい手順は別記事で解説する予定です。

スプレッドシートからのメール自動送信

GAS の MailApp.sendEmail() を使うと、スプレッドシートの内容に応じて自動でメールを送れます。請求書の送付、定期レポートの配信、エラー通知など、メールが絡む業務を一気に効率化できます。こちらも別記事で詳しく解説する予定です。

ライブラリと外部API連携

GAS は UrlFetchApp で外部 API を叩けます。Slack 通知、ChatGPT API、その他 SaaS 連携など、応用の幅が一気に広がります。最初は1つのスプレッドシート内で完結する自動化からスタートし、慣れてきたら外部連携に踏み出すと挫折しにくいです。

なお、Excel VBA から本格的にプログラミングへ移行したい方は、マクロ記録から始めるExcel VBA入門 も合わせて読むと、両方の言語の差分が見えて理解が深まります。

おわりに

GAS の本当の強みは「Google のサービス全部に手が届く」ところです。スプレッドシートの自動化を入り口に、Gmail、フォーム、ドライブ、カレンダーへと広げていけば、Excel VBA では届かなかった領域にまで業務改善が届きます。

最初の1本は今日のレシピから。コピペした関数があなたのスプレッドシートで動いた瞬間が、自動化人生のスタートラインです。

タイトルとURLをコピーしました