Googleフォームの受付終了を自動化|標準設定とGASの使い分け

スポンサーリンク

イベントの申し込みフォームを、締め切り時刻に手動で閉じていませんか。定員に達したかどうかを何度も回答一覧で確かめるのも、地味に手間がかかりますよね。

閉じ忘れると、締め切り後の申し込みが届いてしまいます。一人ずつお断りの連絡を入れることになり、定員を超えた分の調整も担当者の負担になりがちです。

実は2026年1月から、Googleフォームには受付終了を自動化する標準の設定が加わりました。この記事では、まず標準でできることを確認し、足りない部分だけをGAS(Google Apps Script)で補う方法を紹介します。コピペ用のコードもつけていますよ。

結論|Googleフォームの受付終了を自動化するなら、まず標準の締め切り設定を確認

結論から言うと、「日時で締め切る」「回答数で締め切る」のどちらか一方で済むなら、GASは要りません。標準の設定だけで受付終了を自動化できます。

GASが活きるのは、受付開始の予約や残り枠の表示など、標準のヘルプに載っていない運用をしたいときです。まずは標準機能の中身を押さえておきましょう。

標準の締め切り設定でできること

Googleの公式ヘルプで確認できた、標準の設定でできることは次のとおりです。

  • 指定した日時になったら、自動で受付を止める
  • 回答数が上限に達したら、自動で受付を止める
  • 締め切り後に表示するメッセージを編集する
  • 設定を削除して、受付を再開する

この機能は既定でオフになっています。フォームを公開したあとに、作成者が自分で有効にする仕組みです。

対応バージョン: 2026年1月から段階的に提供が始まりました。展開開始は Rapid Release が1月12日、Scheduled Release が1月29日です。どちらも最大15日かけて順次反映されます。対象は Google Workspace の全顧客、Workspace Individual の購読者、個人の Google アカウントです(2026年10月9日時点の公式情報)。

設定場所と手順

日本語の画面では、公開ボタンの中に設定があります。日時で締め切る手順は次のとおり。

  1. 公開済みのフォームを編集画面で開く
  2. 画面右上の公開アイコンをクリックする
  3. 「回答を受付中」の下にある「終了日または回答数の上限を設定」をクリックする
  4. 「特定の日付」を選ぶ
  5. 「日時を選択」から、締め切りの日付と時刻を選ぶ
  6. 「OK」をクリックして確定する

回答数で締め切る場合は、手順4で「回答数で終了」を選び、上限の数を入力します。すでに回答が入っているフォームでは、現在の回答数より大きい値を入れる必要があります。

締め切り後のメッセージの変更も、同じ画面から。「回答が締め切られていることを知らせるメッセージ」の説明の横にある、編集アイコンを押してください。メッセージを入力して「保存」を押せば完了です。

設定をやめたいときは、「回答の受付」の「管理」から「期限を削除」を選びます。受付を再開する方法として、ヘルプで案内されているのもこの手順。英語の画面を使っている場合、設定の入口は “Set close date or response limit” です。

ここでひとつ注意点。公式ヘルプには、複数の人が同時に回答すると、上限に関係なく受け付けられると書かれています。定員ちょうどで止まらない可能性がある、ということですね。

※ 画面の名称は、2026年10月時点の公式ヘルプの表記に合わせています。表示が違う場合は、ヘルプの最新版を確認してください。

標準機能とGASの早見表

標準とGASのどちらで何ができるかを一覧にしました。「ヘルプに記載なし」は、できないと確認できたわけではありません。公式ヘルプで設定項目を確認できなかった、という意味です。

やりたいこと標準の締め切り設定GAS
日時で締め切るできるできる(時間主導トリガー)
回答数で締め切るできるできる(フォーム送信トリガー)
日時と回答数の両方で締め切るヘルプに記載なし2つの処理を組み合わせて可能
締め切り後のメッセージ編集できる締め切りの理由ごとに出し分け可能
受付開始の予約ヘルプに記載なし指定日時に受付を開ける
残り枠の表示ヘルプに記載なしフォームの説明文に書き込める
複数フォームの一括管理ヘルプに記載なしフォームIDを並べて一括処理
同時送信による定員超過上限を超えて受け付けうる送信自体は止められず、超過の検知まで
受付の再開「期限を削除」スクリプトで再開
準備の手間数クリックコードの貼り付けと権限の承認

日時か回答数の片方だけで足りるなら、ここで設定して終わりにしてしまって大丈夫ですよ。

標準機能で足りないケースを整理する

ここからは、GASを使う価値がある場面を具体的に見ていきます。自分の運用が当てはまるか、チェックしてみてください。

定員と日時の併用

「30名に達するか、10月31日の17時になるか、早いほうで締め切りたい」。イベント受付では、こうした条件がよくありますよね。

標準の設定画面は「特定の日付」と「回答数で終了」を選ぶ形になっています。どちらか一方を選ぶ設計に見えますが、併用できるかどうかは公式ヘルプに記載がなく、確認できませんでした。

両方の条件で閉じたいなら、GASで「日時で閉じる処理」と「定員で閉じる処理」を併用する方法があります。後半で紹介する2本のコードは、まさにその組み合わせを想定したものですよ。

締切後メッセージ・残り枠表示・複数フォーム一括

締め切り後のメッセージは、標準でも編集できます。ただし、締め切りの理由ごとに文面を変えられるかは、ヘルプでは確認できませんでした。GASなら「受付前です」「期間が終了しました」「定員に達しました」を状況に応じて切り替えられます。

標準のヘルプでは、次の3つの設定項目も見当たりませんでした。

  • 受付開始の予約: 「11月1日の9時から受付開始」のように、開く日時を決めておく
  • 残り枠の表示: 「残り5名」のような数字を、回答者に見せる
  • 複数フォームの一括管理: 部署別に分けた複数のフォームを、同じ時刻にまとめて閉じる

コードを書かずに済ませたいなら、アドオンを使う手もありますよ。Google Workspace Marketplace には、Form Limiter などが公開されています。アドオンを使うときは、求められる権限を確認してから導入しましょう。

迷ったときの判断フロー(YES/NO)

どちらを使うか迷ったら、次の順に答えてみてください。

  1. 受付開始の予約、残り枠の表示、複数フォームの一括管理のどれかが必要?
  • YES → GASで補う
  • NO → 2へ
  1. 締め切りの条件は「日時だけ」か「回答数だけ」で足りる?
  • YES → 3へ
  • NO(両方の条件で閉じたい)→ GASで2つの処理を組み合わせる
  1. 定員を超えた申し込みを把握する仕組みが欲しい?
  • YES → GASで回答数を数え、超過を記録する
  • NO → 標準の設定で十分。GASは不要

GASを使うと決めたら、標準の締め切り設定はオフのままにしておくのがおすすめです。理由は、記事後半の「うまく動かないときの確認ポイント」で説明します。

GASで日時になったら自動で締める(時間主導トリガー)

ここからはGASの手順です。GASに初めて触る方は、先に入門記事でエディタの基本を見ておくと安心ですよ。

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

準備:フォームIDを確認してプロジェクトを作る

スクリプトからフォームを操作するには、フォームIDが必要です。フォームの編集画面のURLを見てください。

https://docs.google.com/forms/d/【この部分がフォームID】/edit

/d/ と /edit に挟まれた長い英数字がフォームIDです。スクリプトは、フォームの編集権限を持つアカウントで作成してください。

  1. Apps Script のホーム(script.google.com)を開く
  2. 「新しいプロジェクト」をクリックする
  3. 最初から入っているコードをすべて消す
  4. 次の見出しの「コピペ用コード」を貼り付ける
  5. 保存アイコンをクリックする

フォームをまだ作っていない方は、作り方の記事からどうぞ。

Googleフォームの作り方入門|質問設計・回答集計・共有までゼロから解説

コピペ用コード

日時で受付を開け閉めするスクリプトです。受付開始の予約と、複数フォームの一括処理にも対応しています。

// ===== 設定ここから =====
// 対象のフォームID(複数ある場合はカンマ区切りで並べる)
const FORM_IDS = [
  'ここにフォームIDを貼り付け',
];

// 受付開始を予約するなら true、すぐ受け付けるなら false
const USE_OPEN_SCHEDULE = true;

// 受付を開始する日時(月は0始まり。11月なら10と書く)
const OPEN_AT = new Date(2026, 10, 1, 9, 0);

// 受付を終了する日時(例:2026年11月14日 17:00)
const CLOSE_AT = new Date(2026, 10, 14, 17, 0);

// 受付開始前に表示するメッセージ
const NOT_YET_MESSAGE = '受付開始前です。11月1日9時から受け付けます。';

// 期間終了後に表示するメッセージ
const CLOSED_MESSAGE_BY_DATE = '受付期間が終了しました。ご回答ありがとうございました。';
// ===== 設定ここまで =====

// 受付を開始する(トリガーから自動で呼ばれる)
function openFormsByDate() {
  FORM_IDS.forEach(function (id) {
    FormApp.openById(id).setAcceptingResponses(true);
    console.log('受付を開始しました: ' + id);
  });
}

// 受付を終了する(トリガーから自動で呼ばれる)
function closeFormsByDate() {
  FORM_IDS.forEach(function (id) {
    const form = FormApp.openById(id);
    // すでに定員などで閉じている場合は、そのメッセージを残す
    if (form.isAcceptingResponses()) {
      form.setCustomClosedFormMessage(CLOSED_MESSAGE_BY_DATE);
      form.setAcceptingResponses(false);
    }
    console.log('受付を終了しました: ' + id);
  });
}

// 最初に1回だけ手動で実行する(トリガーを作る)
function setupDateTriggers() {
  if (USE_OPEN_SCHEDULE) {
    // 開始日時が未来なら、いったん受付を止めておく
    if (OPEN_AT > new Date()) {
      FORM_IDS.forEach(function (id) {
        const form = FormApp.openById(id);
        form.setCustomClosedFormMessage(NOT_YET_MESSAGE);
        form.setAcceptingResponses(false);
      });
    }
    ScriptApp.newTrigger('openFormsByDate').timeBased().at(OPEN_AT).create();
  }
  ScriptApp.newTrigger('closeFormsByDate').timeBased().at(CLOSE_AT).create();
  console.log('トリガーを作成しました');
}

書き換えるのは「設定ここから」〜「設定ここまで」の間だけです。JavaScriptの new Date() は月を0から数えるので、11月なら 10 と書きます。ここは間違えやすいポイント。

setAcceptingResponses(false) が受付を止める命令です。true を渡すと受付を再開します。

setCustomClosedFormMessage() では、閉じているときに表示するメッセージを決めます。受付開始の予約が要らなければ、USE_OPEN_SCHEDULE を false にしてください。

トリガー設定の最小手順(詳細は別記事へ)

このスクリプトでは、トリガーを作る処理もコードに含めています。エディタから一度だけ実行すれば、準備は完了。

  1. エディタ上部の関数の選択欄で setupDateTriggers を選ぶ
  2. 「実行」をクリックする
  3. 権限の承認を求められたら、内容を確認して許可する
  4. 左側のメニューから「トリガー」を開く
  5. openFormsByDate と closeFormsByDate が1つずつ登録されているか確認する(予約なしなら closeFormsByDate だけ)

時間主導トリガーは、指定した時刻ちょうどに動くとは限りません。公式ドキュメントでは、分を指定する方法(nearMinute())に「±15分」の幅があると説明されています。at() の誤差は明記されていないため、分単位の厳密さは期待しない前提で時刻を決めてください。

締め切り時刻を厳密に守りたいなら、案内する時刻の少し前に設定しておくと安全です。反対に、締め切りまで確実に受け付けたいなら、少しあとに設定しましょう。トリガーの種類や、動かないときの見直し方は次の記事で詳しく解説しています。

GASのトリガーでスプレッドシートの集計・通知を自動化する方法|時間指定・フォーム送信を起点に動かす

GASで定員に達したら自動で締める+締切後メッセージを変える

次は、回答数が定員に達したら閉じるスクリプトです。残り枠をフォームの説明文に表示し、定員到達時は専用のメッセージに切り替えます。

onFormSubmitで回答数を数えて閉じる

フォームに回答が送信されるたびに動く「フォーム送信トリガー」(onFormSubmit)を使います。送信のたびに回答数を数え、定員に達していたら受付を止める仕組みです。

// ===== 設定ここから =====
const FORM_ID = 'ここにフォームIDを貼り付け';

// 定員
const CAPACITY = 30;

// この日時以降の回答だけを数える(月は0始まり)
const COUNT_FROM = new Date(2026, 10, 1, 0, 0);

// フォームの説明文(この下に残り枠が追記される)
const BASE_DESCRIPTION = '11月の社内勉強会の参加申し込みフォームです。';

// 定員に達したときに表示するメッセージ
const CLOSED_MESSAGE_BY_CAPACITY = '定員に達したため受付を終了しました。キャンセル待ちは担当者までご連絡ください。';
// ===== 設定ここまで =====

// フォームが送信されるたびに自動で呼ばれる
function checkCapacity() {
  const lock = LockService.getScriptLock();
  // ほかの送信の処理が終わるまで、最大30秒待つ
  lock.waitLock(30000);
  try {
    const form = FormApp.openById(FORM_ID);
    const count = form.getResponses(COUNT_FROM).length;
    const remaining = Math.max(CAPACITY - count, 0);

    // 残り枠を説明文に反映する
    updateRemaining_(form, remaining);

    // 定員に達していたら受付を止める
    if (count >= CAPACITY && form.isAcceptingResponses()) {
      form.setCustomClosedFormMessage(CLOSED_MESSAGE_BY_CAPACITY);
      form.setAcceptingResponses(false);
      console.log('定員に達したため受付を終了しました');
    }

    // 同時送信などで定員を超えた場合は記録を残す
    if (count > CAPACITY) {
      console.log('定員を ' + (count - CAPACITY) + ' 件超えています。超過分への連絡が必要です。');
    }
  } finally {
    lock.releaseLock();
  }
}

// 説明文を「本文+残り枠」に書き換える
function updateRemaining_(form, remaining) {
  form.setDescription(BASE_DESCRIPTION + 'nn残り枠:' + remaining + '名');
}

// 最初に1回だけ手動で実行する(フォーム送信トリガーを作る)
function setupCapacity() {
  const form = FormApp.openById(FORM_ID);
  ScriptApp.newTrigger('checkCapacity').forForm(form).onFormSubmit().create();
  // 現在の残り枠をすぐに説明文へ反映する
  checkCapacity();
  console.log('トリガーを作成しました');
}

準備の流れは日時のスクリプトと同じです。エディタで setupCapacity を選んで、一度だけ実行してください。

COUNT_FROM は、数え始める日時を決める設定です。getResponses() に日時を渡すと、その時刻以降の回答だけが返ってきます。フォームを次の募集に使い回すときも、この日時を書き換えるだけで済みます。

日時と定員の両方で閉じたい場合は、前章のコードの下に続けて貼り付けましょう。フォームIDは、両方の設定欄に同じものを入れてください。

先に条件を満たしたほうの処理が受付を止める設計です。日時側のコードは、すでに閉じているフォームのメッセージを上書きしません。定員で閉じたときは「定員に達しました」の文面が残ります。

LockServiceで同時送信に備える

コードの冒頭で使っている LockService は、処理の一部を同時に実行させないための仕組みです。getScriptLock() は、全ユーザーで共通のロックを取ります。

送信がほぼ同時に重なると、2つの処理が並行して説明文を書き換えることになります。その結果、残り枠の表示が食い違ったり、閉じる処理が二重に走ったりしかねません。waitLock() で順番待ちにすると処理が1件ずつ進むため、こうした食い違いを防げます。

ただし、LockService が止めるのはスクリプトの処理の重なりです。フォームへの送信そのものを止めるわけではありません。閉じる処理が終わる前に届いた回答は受け付けられるため、定員を少し超える可能性は残ります。

そこでこのコードでは、定員を超えたら超過件数をログに残すようにしています。超過分は「遅く届いた分からキャンセル待ちに回す」と決めておくと、慌てずに済みますよ。担当者へのメール通知を加えたいなら、通知のレシピが参考になります。

Googleフォーム×GASで回答を自動通知・集計する方法|コピペで動く3レシピ

残り枠をフォーム説明文に反映・受付再開

残り枠は、setDescription() でフォームの説明文に書き込んでいます。この命令は説明文を丸ごと置き換えるので、元の本文は BASE_DESCRIPTION に入れておきましょう。フォーム側で説明文を直接編集しても、次の送信で上書きされてしまいます。

表示が更新されるのは、回答が送信されたタイミングです。フォームを開いたまま待っている人の画面は、自動では更新されない前提で考えましょう。あくまで目安として「残り枠」を見せる使い方が向いています。

キャンセルが出て枠が空いたときや、定員を増やしたときは、次の関数で受付を再開します。上の定員のコードと同じファイルの末尾に追加してください。

// 枠が空いたとき・定員を増やしたときに手動で実行する
function reopenForm() {
  const form = FormApp.openById(FORM_ID);
  const count = form.getResponses(COUNT_FROM).length;
  const remaining = Math.max(CAPACITY - count, 0);

  // 残り枠がなければ再開しない
  if (remaining === 0) {
    console.log('残り枠が0のため再開しません。CAPACITY を見直してください。');
    return;
  }

  updateRemaining_(form, remaining);
  form.setAcceptingResponses(true);
  console.log('受付を再開しました。残り枠:' + remaining + '名');
}

reopenForm は、実行した時点の回答数で残り枠を数え直します。キャンセル分の回答をフォームから削除してから実行し、ログの残り枠が正しいか確認してください。定員を増やすときは、CAPACITY を書き換えて保存してから実行します。

日時のコードと組み合わせている場合は、締め切り日時を過ぎてから再開しないよう注意しましょう。予約の受付をカレンダーまで自動でつなげたい方は、こちらの記事もどうぞ。

GASでGoogleフォームの予約をカレンダーに自動登録|会議室・面談予約の受付を自動化

うまく動かないときの確認ポイント

スクリプトが思ったとおりに動かないときは、次の順に確認してみてください。多いのは、権限とトリガーまわりのつまずきです。

権限承認とトリガーの二重登録

権限の承認が済んでいないと、スクリプトはフォームを操作できません。初回の実行で承認画面が出たら、フォームの編集権限を持つアカウントで許可してください。承認せずに閉じた場合は、もう一度セットアップ用の関数を実行します。

セットアップ用の関数を2回実行すると、同じトリガーが2つ登録されます。処理が二重に走るので、ログも重複しがちです。左メニューの「トリガー」を開き、同じ関数のトリガーが複数あれば、1つを残して削除しましょう。

ほかにも、次の点で止まることがあります。

  • 時刻がずれる: プロジェクトの設定にあるタイムゾーンが日本(東京・Asia/Tokyo)になっているか確認する
  • 回答数が多すぎる: COUNT_FROM より前の古い回答まで数えていないか見直す
  • トリガーが作れない: トリガーは1ユーザー・1スクリプトあたり20個が上限

複数フォームそれぞれに送信トリガーを作る場合は、この20個の上限に注意が必要です。トリガーの合計実行時間にも、個人アカウントで1日90分、Workspace で1日6時間の上限があります。いずれも2026年10月9日時点の公式情報で、予告なく変わる場合があります。

標準設定との競合・GAS側で閉じた後の表示

GASを使うときは、標準の締め切り設定と同時に使わない運用をおすすめします。理由は、両者の関係が公式には説明されていないからです。

Apps Script の Form クラスを、公式リファレンスで確認しました(2026年10月9日)。標準の「終了日時」や「回答数の上限」を読み書きする命令は見当たりません。

標準の締め切りが来たあとに、GASで受付を再開できるかも確認できませんでした。標準とGASのメッセージのどちらが優先されるかも、公式の記載はありません。

GASで閉じたあと、標準の「回答を受付中」の表示がどうなるかも未確認です。動作を確かめるときは、フォームの回答用URLを別のブラウザやシークレットウィンドウで開いてみましょう。回答者に見える画面を直接確認するのがいちばん確実です。

GASで再開したのに受け付けない場合は、念のため標準の設定が残っていないか見てください。公開アイコンを開き、「回答の受付」の「管理」から「期限を削除」を選ぶと、標準の設定を外せます。そのうえで、スクリプトから再開を試してみてください。

まとめ|Googleフォームの受付終了は「標準で足りるか」から決める

Googleフォームの受付終了は、2026年1月から標準の設定で自動化できるようになりました。最後に要点を振り返っておきましょう。

  • 日時か回答数の片方だけで締め切るなら、標準の「終了日または回答数の上限を設定」で十分
  • 締め切り後のメッセージの編集と、「期限を削除」による再開も標準でできる
  • 受付開始の予約、両方の条件での締め切り、残り枠の表示、複数フォームの一括管理はGASで補える
  • 同時送信による定員超過は、標準でもGASでも完全には防げない。GASなら超過を検知して記録できる
  • GASを使うなら、標準の締め切り設定とは同時に使わない

まずは標準の設定を開いて、自分の運用で足りるか確かめるところから始めてみてください。締め切り前に回答を促したいなら、リマインドの自動化も相性のいい組み合わせです。

GASで期限リマインド・未対応タスクを自動アラート|Google Chatとメールに通知

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