Googleフォームの回答をGASで高度に処理するテクニック

GASGoogleフォーム自動化
Googleフォームの回答をGASで高度に処理するテクニックのサムネイル

みなさん、こんにちは。GASおじです。今回は中小企業の経営者やフリーランスの方々に向けて、Googleフォームの回答データをGoogle Apps Script(以下GAS)で安全かつ効率的に処理するテクニックを紹介するぞ。

「データの誤削除は避けたい」「効率よくバッチ処理したい」「バックアップやロールバックも考慮したい」そんなニーズに応える内容になっている。コストもきっちり抑えつつ、Googleアカウントの利用枠内で動かす方法だ。専用SaaSの追加料金は一切不要だが、Apps Scriptのquotaや実行上限はあるからそこは注意してくれ。


初期設定と必要な権限

まず、Googleフォームと連携するスプレッドシートを用意しよう。フォームの回答はスプレッドシートに自動で集約される設定にしておくのが基本だ。GASでそのスプレッドシートにアクセスし、データの読み書きを行う。

GASを初めて使う人はスクリプトエディタを開き、プロジェクトを作成しよう。Googleフォームの回答スプレッドシートに対して以下の権限が必要だ。

  • スプレッドシートの閲覧・編集権限
  • Googleドライブのファイル作成権限(バックアップ用ファイルを生成するため)

また、トリガーを使う場合は「installable trigger」の設定が必要だ。これによりフォーム送信時や時間ベースで自動処理を実行できる。


入力検証とバッチ処理で効率化

フォームの回答は必ずしも完璧とは限らない。たとえば日付形式が崩れていたり、必須項目が空欄だったりすることもある。そんな場合はスクリプト側でしっかり入力検証をしてから処理するのがおじさん流だ。

また、回答が大量に来る場合は1件ずつ処理するより複数件をまとめて処理(バッチ処理)するほうがAPI呼び出し回数を減らせて効率的だ。

以下はフォーム回答の最新の未処理分を取得し、日付形式の検証を行い問題なければ別シートにまとめて書き出す例だ。

function processFormResponses() {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const formSheet = ss.getSheetByName('フォーム回答');
  if (!formSheet) {
    Logger.log('フォーム回答シートが見つかりません');
    return;
  }

  // 処理済み行を記録する列番号(例: G列=7)
  const processedCol = 7;

  const data = formSheet.getDataRange().getValues();
  const headers = data[0];
  const responses = data.slice(1);

  // 新規処理分だけ選別(processedColが空の行)
  const newResponses = responses.filter(row => !row[processedCol -1]);

  if (newResponses.length === 0) {
    Logger.log('新しい未処理データはありません');
    return;
  }

  // 入力検証: 日付列は3列目(インデックス2)と仮定
  const validResponses = [];
  const invalidResponses = [];
  newResponses.forEach(row => {
    const dateVal = row[2];
    if (Object.prototype.toString.call(dateVal) === '[object Date]' && !isNaN(dateVal)) {
      validResponses.push(row);
    } else {
      invalidResponses.push(row);
    }
  });

  // バッチ書き込み先の新規シートを作成(日時付き)
  const timestamp = Utilities.formatDate(new Date(), Session.getScriptTimeZone(), 'yyyyMMdd_HHmmss');
  const outputSheetName = '処理済み_' + timestamp;
  const outputSheet = ss.insertSheet(outputSheetName);

  // ヘッダー書き込み
  outputSheet.getRange(1, 1, 1, headers.length).setValues([headers]);

  // 有効データをまとめて書き込み
  if (validResponses.length > 0) {
    outputSheet.getRange(2, 1, validResponses.length, validResponses[0].length).setValues(validResponses);
  }

  // 元シートの処理済みフラグを更新(バッチ処理なのでまとめて)
  newResponses.forEach((row, idx) => {
    if (validResponses.includes(row)) {
      formSheet.getRange(idx + 2, processedCol).setValue('済');
    } else {
      formSheet.getRange(idx + 2, processedCol).setValue('入力エラー');
    }
  });

  Logger.log(`有効データ: ${validResponses.length}件、入力エラー: ${invalidResponses.length}件 処理完了`);
}

バックアップとロールバックの考え方

データを直接上書き・削除するのは怖いものだ。だからおじさんは既存データは直接更新せず、新しい日時付きシートか新規ファイルを作って書き出すスタイルを推奨している。こうすることで誤操作によるデータ損失リスクを減らせる。

バックアップはGoogleドライブ内に「バックアップ」フォルダを作って、定期的に処理済みデータや元データのコピーを保存しておくと安心だ。万が一の際はバックアップファイルから復元すればいい。

ロールバックは単純にそのバックアップファイルを再度スプレッドシートとして開いて、必要なデータをコピーし直す運用を想定している。GASの自動処理で元に戻す仕組みを組むことも可能だが、コストや開発工数と相談しよう。


コスト削減額の仮定と計算例

例えば、フォーム回答の手動整理に1件あたり3分かかっていたとしよう。1日50件、月20営業日で計算すると、

3分 × 50件 × 20日 = 3000分 = 50時間/月

仮におじさんの時間単価を3,000円/時間とした場合、

50時間 × 3,000円 = 150,000円/月

これが自動化で50%削減できれば、

150,000円 × 0.5 = 75,000円/月のコスト削減

あくまで仮定の数字だが、効率化による効果は見込める。Googleアカウントの利用枠内で動かし、追加の専用SaaS料金なしでここまでできるのがGASの強みだ。


個人情報の取り扱いと復元手順

フォームに個人情報が含まれる場合は取り扱いに注意が必要だ。スクリプトの権限管理に気をつけ、不要な範囲へのアクセスを避ける。ログに個人情報を出さないことも重要だ。

復元手順は、誤ってデータを消したりミスがあった場合は、バックアップフォルダ内の該当日時のファイルを開き、必要なデータをコピーし直す。Googleドライブのバージョン履歴機能も併用できる。


GASでGoogleフォームの回答を高度かつ安全に処理して、業務効率アップを狙いたい方はぜひ挑戦してみてほしい。初期設定や入力検証、バッチ処理、バックアップの考え方がポイントだぞ。

最後に、GASおじラボのメンバーシップでは今回のような実践的なツールを500種類以上使い放題で提供している。興味があればこちらからどうぞ!

GASおじラボで500ツール使い放題 →