GASで月40時間の事務作業が「ゼロ」になる?

ミドリ: タツヤさん、最近「GAS」ってよく聞くんですけど、あれってエンジニアじゃないと使えないやつですよね?

タツヤ(nodding): いい質問だね。結論から言うと、プログラミング未経験者でも十分使いこなせるよ。GASっていうのは「Google Apps Script」の略で、Googleが提供する無料のスクリプティング環境のこと。

ミドリ: 無料なんですか!

タツヤ(nodding): そう、Google Workspaceのアカウントがあれば追加費用ゼロ。しかもクラウドベースだから、ソフトのインストールも不要。ブラウザさえあればすぐ始められる。

ミドリ(confused): でも、具体的に何ができるんですか?

タツヤ: たとえば「毎日のデータ集計に30分かかってる」「毎週のレポート送信を忘れる」「フォームの回答を手動で別シートに転記してる」……こういう日常の小さな非効率、心当たりない?

ミドリ: めちゃくちゃあります……。

タツヤ: これらが積み重なると膨大な時間ロスになる。仮に1日30分の定型作業を自動化できたら、月間で約10時間、年間で約120時間の削減。フルタイム社員の約1ヶ月分の労働時間に相当するんだ。

GASでできること

ミドリ(smiling): 月40時間削減って、すごい数字ですね。具体的にどんなことが自動化できるんですか?

タツヤ: Google Workspaceの各サービスを「プログラムで操作する」イメージだね。主なものを挙げると——

ミドリ(surprised): えっ、Slackとかfreeeとも連携できるんですか?

タツヤ: できるよ。GASの守備範囲はかなり広い。

GASの5つの利点

ミドリ(surprised): なんでそんなに便利なのに、もっと使われてないんですかね?

タツヤ: 「プログラミングが必要」っていう心理的ハードルが大きいんだと思う。でも実際はかなり敷居が低い。5つの利点を整理しておこう。

  1. 無料 — Google Workspaceのアカウントがあれば追加費用なし。無料のGoogleアカウントでも基本機能は使える
  2. クラウドベース — インストール不要。作成したスクリプトはGoogleのサーバーで実行されるから、自分のPCが起動してなくても自動実行される
  3. Google Workspace完全統合 — スプレッドシート、Gmail、カレンダーなどと直接連携。APIキーの取得や複雑な接続設定は不要
  4. 学習コストが低い — JavaScriptベースで、豊富なテンプレートやチュートリアルが公開されてる。ChatGPTにコード生成を頼めばさらにハードルが下がる
  5. トリガー機能 — 「毎日朝9時に実行」「スプレッドシートが編集されたら実行」といった自動実行の条件を簡単に設定できる

ミドリ: 5番のトリガー機能、めちゃくちゃいいですね。「毎朝レポート送って」みたいなことが自動でできるってことですよね。

タツヤ(nodding): その通り。じゃあ実際に動かしてみよう。

3ステップで最初のスクリプトを動かす

ステップ1:GASエディタを開く

タツヤ(nodding): まず、Googleスプレッドシートを開いて、メニューバーから「拡張機能」→「Apps Script」をクリック。スクリプトエディタが新しいタブで開く。

ミドリ: え、それだけですか?

タツヤ: それだけ。特別なソフトのインストールは一切不要。

ステップ2:最初のスクリプトを書く

タツヤ: 以下のコードをエディタに貼り付けて、「実行」ボタンをクリックしてみて。スプレッドシートのA1セルに現在の日時が書き込まれるよ。

function writeCurrentDate() {
  const sheet = SpreadsheetApp.getActiveSheet();
  sheet.getRange("A1").setValue(new Date());
}

ミドリ(surprised): おお、本当にA1セルに日時が入った! たった3行で!

ステップ3:トリガーを設定して自動実行する

タツヤ: 次に、手動で「実行」ボタンを押す代わりに、トリガーを設定しよう。

  1. エディタの左側メニューから「トリガー」(時計アイコン)をクリック
  2. 「トリガーを追加」をクリック
  3. 実行する関数、実行タイミング(時間ベース、イベントベースなど)を選択
  4. 「保存」をクリック

ミドリ: 「毎朝8時に実行」みたいに設定すれば、毎日自動で動くんですね。

タツヤ: そういうこと。じゃあ次は、もっと実践的な例を見ていこう。

実践例1:売上データの自動集計

ミドリ: 実務で使えるやつが知りたいです!

タツヤ: 営業チームが日々入力する売上データを自動集計して、サマリーを別シートに出力するスクリプトだ。

function autoSummarizeData() {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const dataSheet = ss.getSheetByName("売上データ");
  const summarySheet = ss.getSheetByName("サマリー");

  // 売上データを取得
  const data = dataSheet.getDataRange().getValues();
  const headers = data[0];

  // 担当者別の売上を集計
  const salesByPerson = {};
  for (let i = 1; i < data.length; i++) {
    const person = data[i][1];  // B列: 担当者名
    const amount = data[i][3];  // D列: 売上金額
    if (salesByPerson[person]) {
      salesByPerson[person] += amount;
    } else {
      salesByPerson[person] = amount;
    }
  }

  // サマリーシートに出力
  summarySheet.clear();
  summarySheet.getRange("A1").setValue("担当者");
  summarySheet.getRange("B1").setValue("売上合計");
  summarySheet.getRange("C1").setValue("集計日時");

  let row = 2;
  let grandTotal = 0;
  for (const person in salesByPerson) {
    summarySheet.getRange(row, 1).setValue(person);
    summarySheet.getRange(row, 2).setValue(salesByPerson[person]);
    summarySheet.getRange(row, 3).setValue(new Date());
    grandTotal += salesByPerson[person];
    row++;
  }

  // 総合計を最終行に追加
  summarySheet.getRange(row, 1).setValue("【総合計】");
  summarySheet.getRange(row, 2).setValue(grandTotal);
}

ミドリ: これを日次トリガーで動かせば、毎日自動で最新の集計が更新されるってことですか?

タツヤ(nodding): その通り。手動で集計表を作ってた場合、1日あたり15〜30分の時間を節約できるよ。

実践例2:レポートメールの自動送信

ミドリ: レポートの送信も自動化できるんですか?

タツヤ: もちろん。スプレッドシートの業務データを取得して、HTML形式のきれいなレポートメールを自動送信するスクリプトがこれだ。

function sendDailyReport() {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const sheet = ss.getSheetByName("日報データ");
  const data = sheet.getDataRange().getValues();

  // 本日の日付でフィルタリング
  const today = new Date();
  const todayStr = Utilities.formatDate(today, "Asia/Tokyo", "yyyy/MM/dd");

  let completedTasks = 0;
  let totalTasks = 0;
  let taskDetails = "";

  for (let i = 1; i < data.length; i++) {
    const taskDate = Utilities.formatDate(
      new Date(data[i][0]), "Asia/Tokyo", "yyyy/MM/dd"
    );
    if (taskDate === todayStr) {
      totalTasks++;
      if (data[i][3] === "完了") {
        completedTasks++;
      }
      taskDetails += "<tr><td>" + data[i][1] + "</td>"
        + "<td>" + data[i][2] + "</td>"
        + "<td>" + data[i][3] + "</td></tr>";
    }
  }

  // HTML形式のメール本文を構築
  const htmlBody = "<h2>日報レポート(" + todayStr + ")</h2>"
    + "<p>本日のタスク数: " + totalTasks + "件</p>"
    + "<p>完了タスク: " + completedTasks + "件(完了率: "
    + Math.round(completedTasks / totalTasks * 100) + "%)</p>"
    + "<table border='1' cellpadding='5'>"
    + "<tr><th>タスク名</th><th>担当者</th><th>ステータス</th></tr>"
    + taskDetails + "</table>";

  // メール送信
  GmailApp.sendEmail(
    "[email protected]",
    "【日報】" + todayStr + " タスク進捗レポート",
    "HTML非対応のメーラーでは表示できません",
    { htmlBody: htmlBody }
  );
}

ミドリ: 毎日18時に自動実行するトリガーを設定すれば、日報の作成も送信も完全自動化ですね!

タツヤ: そういうこと。「報告のための報告」に時間を使う必要がなくなる。

実践例3:フォーム回答の自動処理

ミドリ: お問い合わせフォームの対応も自動化できますか?

タツヤ: できるよ。フォームの回答を受け取ったら、自動返信メールを送信して、同時にSlackに通知するスクリプトだ。

function onFormSubmit(e) {
  const responses = e.namedValues;
  const name = responses["お名前"][0];
  const email = responses["メールアドレス"][0];
  const inquiry = responses["お問い合わせ内容"][0];

  // 自動返信メールを送信
  const replySubject = "【自動返信】お問い合わせを受け付けました";
  const replyBody = name + " 様\n\n"
    + "お問い合わせいただきありがとうございます。\n"
    + "以下の内容で受け付けました。\n\n"
    + "---\n"
    + inquiry + "\n"
    + "---\n\n"
    + "担当者より2営業日以内にご連絡いたします。\n";

  GmailApp.sendEmail(email, replySubject, replyBody);

  // Slackに通知(Webhook URLは事前に設定)
  const slackWebhookUrl = "YOUR_SLACK_WEBHOOK_URL";
  const slackPayload = {
    text: "新規お問い合わせ\n"
      + "名前: " + name + "\n"
      + "内容: " + inquiry
  };

  UrlFetchApp.fetch(slackWebhookUrl, {
    method: "post",
    contentType: "application/json",
    payload: JSON.stringify(slackPayload)
  });
}

ミドリ: フォーム送信時トリガーに設定すれば、フォームが送信されるたびに自動返信とSlack通知が同時に走るんですね。初回応答が爆速になる!

タツヤ: 問い合わせへの初回応答時間を大幅に短縮できるから、顧客満足度の向上にも直結するよ。

本格運用に向けた5つのTips

ミドリ: 実際に本番で使うときに気をつけることってありますか?

タツヤ(nodding): いい質問。5つのTipsを押さえておこう。

Tip 1:エラーハンドリングを実装する

タツヤ: 本番運用するスクリプトには、必ずエラー処理を入れること。エラーが起きたら管理者にメールで通知するようにしておくと安心だ。

function safeFunction() {
  try {
    // メインの処理
    autoSummarizeData();
  } catch (error) {
    // エラーが発生した場合、管理者にメール通知
    GmailApp.sendEmail(
      "[email protected]",
      "【GASエラー】スクリプト実行エラー",
      "エラー内容: " + error.message + "\n発生日時: " + new Date()
    );
  }
}

Tip 2:実行時間の制限に注意する

タツヤ: GASには1回の実行あたり最大6分という制限がある。Google Workspace有料プランでは30分。大量のデータを処理する場合は、バッチ処理を検討しよう。

ミドリ: 6分って、データ量が多いとすぐ引っかかりそうですね。

タツヤ: だからこそデータを分割して複数回に分けて処理する設計が大事になる。

Tip 3:ログを活用してデバッグする

タツヤ: Logger.log()console.log() で処理の途中経過を記録しておくと、問題が起きたときに原因を特定しやすくなるよ。

Tip 4:スプレッドシートへのアクセスを最小化する

タツヤ: スプレッドシートの読み書きは処理速度のボトルネックになりやすい。getValues() でデータを一括取得して、配列上で処理してから setValues() で一括書き込みするのが効率的。

Tip 5:バージョン管理を行う

タツヤ: スクリプトエディタの「プロジェクトの履歴」機能を活用して、変更履歴を管理しよう。修正したら動かなくなった、ってときに戻せるようにしておくこと。

よくある質問

ミドリ: 読者の方から来そうな質問にも答えておきましょうか。

タツヤ: いいね。

ミドリ: まず、「プログラミング経験がまったくなくても大丈夫ですか?」

タツヤ: 大丈夫。本記事のサンプルコードをテンプレートとして活用すれば、未経験でも業務自動化を始められる。Googleの公式チュートリアルも充実してるし、ChatGPTにGASのコード生成を頼めばさらにハードルが下がる。まずは「セルの値を読み書きする」っていう基本操作から始めてみて。

ミドリ: 「セキュリティは大丈夫ですか?」

タツヤ(thinking): GASはGoogleのセキュリティ基盤の上で動作するから、基本的なセキュリティは確保されてる。ただし外部サービスとの連携時にはAPIキーの管理に注意が必要。GASの「プロパティサービス」を使ってAPIキーをスクリプト内に直書きせず、安全に管理すること。アクセス権限も必要最小限にしよう。

ミドリ: 「有料プランでないと使えない機能はありますか?」

タツヤ: 基本機能は無料のGoogleアカウントでも利用可能。ただし無料プランでは1日あたりのメール送信数が100通、スクリプト実行時間が6分に制限される。Workspace有料プランならメール1,500通、実行時間30分と大幅に緩和されるから、本格運用するなら有料プランがおすすめだね。

まとめ

ミドリ: 今日の話をまとめると、どうなりますか?

タツヤ: GASは、プログラミングの専門知識がなくても始められる、最もコスパの高い業務自動化ツールの1つだということ。無料で使えて、Google Workspaceとシームレスに連携でき、トリガー機能で完全自動化が実現できる。

ミドリ: データ集計、レポート送信、フォーム回答処理……日々の定型業務を自動化するだけで、月間10〜40時間の工数削減ですもんね。

タツヤ(nodding): まずは1つの小さな自動化スクリプトから始めて、効果を実感しながら適用範囲を広げていくのがコツだよ。


次のアクション

ミドリ: 読者の方がまずやるべきことは何ですか?

タツヤ: 3つ提案しておこう。