Googleフォームは画面操作だけで作れますが、「参加形式で質問を出し分ける」「メール形式を自動チェックする」といった複雑なフォームは、画面操作だけでは大変です。この記事では、無料のGoogle Apps Script(GAS)で、5ページ・分岐・入力チェックつきの参加申込フォームをコードから作る方法を解説します。掲載コードは実行検証済みです(記事末に検証方法)。
GASとは?コードで作るメリット
GASは、Googleが無料提供する「フォーム・スプレッドシート・Gmailなどをプログラムから操作する環境」で、ブラウザだけで動きインストール不要です。2026年現在もGoogle Workspaceの標準サービスとして運用されています(Workspace Updates(2026年6月))。コードで作るメリットは次の4つです。
1.同じフォームを実行だけで数秒で再現できる
2.複雑な分岐を一括で設定できる
3.入力ミスを自動チェックで防げる
4.回答と同時のメール送信などに自動化できる
準備:スクリプトエディタを開く(約2分)
1.Googleフォームを新規作成(forms.new)
2.フォームの「拡張機能」→「Apps Script」をクリック

3.エディタのコードを下記で置き換えて保存(Ctrl+S)
実践コード(コピペ用・全文)
今回作るのは「2026年 秋のオフィス交流会」の参加申込フォーム(5ページ構成)です。コード内の日本語コメントを確認しつつ、そのままコピーしてください。
// 交流会フォーム生成スクリプト(参加申込+アンケート一体型)
// 使い方: フォーム→「拡張機能」→「Apps Script」で貼り付け、
// 関数「createEventForm」を選び▶実行(初回は自分のアカウントで承認)。
// 実行後、ログに「編集用URL」「回答用URL」が表示されます。
function createEventForm() {
// ---- ① フォームの作成と基本設定 ----
var form = FormApp.create('【参加申込】2026年 秋のオフィス交流会(現地/オンライン)');
form.setDescription('現地・オンラインのどちらでも申し込めます。回答はイベント運営(名簿作成・連絡)にのみ使用します。');
form.setProgressBar(true); // 進捗バー
form.setCollectEmail(false); // メールは設問として後で聞く
form.setLimitOneResponsePerUser(false);
form.setAllowResponseEdits(false); // 送信後の訂正は不可
form.setPublishingSummary(false); // 集計は回答者に見せない
form.setShowLinkToRespondAgain(false);
form.setConfirmationMessage('お申し込みありがとうございました。詳細は後日メールでご連絡します。');
// 回答をスプレッドシートに自動保存(失敗してもフォーム作成は継続)
try {
var sheet = SpreadsheetApp.create('交流会_回答_' + new Date().toISOString().slice(0, 10));
form.setDestination(FormApp.DestinationType.SPREADSHEET, sheet.getId());
} catch (e) {
Logger.log('スプレッドシート連携はスキップ: ' + e.message);
}
// ---- ② 1ページ目: 基本情報(分岐ポイント)----
form.addPageBreakItem().setTitle('1. 基本情報').setHelpText('当日の連絡に使う情報です。');
form.addTextItem().setTitle('お名前').setHelpText('例)山田 太郎').setRequired(true);
form.addTextItem().setTitle('メールアドレス').setHelpText('受付完了メールをお送りします。').setRequired(true)
.setValidation(FormApp.createTextValidation().requireTextIsEmail().build()); // メール形式チェック
var qDept = form.addListItem().setTitle('所属部署').setRequired(true);
qDept.setChoiceValues(['営業部', '開発部', '人事部', '経理部', '広報部', 'その他']); // プルダウン
var qType = form.addMultipleChoiceItem().setTitle('参加形式').setHelpText('現地→交通手段、オンライン→接続環境の質問へ。').setRequired(true);
// ---- ③ 2ページ目: 現地参加の詳細 ----
var pb2 = form.addPageBreakItem().setTitle('2. 現地参加の詳細');
form.addMultipleChoiceItem().setTitle('交通手段').setChoiceValues(['電車・バス', '自家用車', 'レンタカー', 'その他']).setRequired(true);
form.addParagraphTextItem().setTitle('アレルギー・食べられないもの').setHelpText('ある方のみ。例)えび、卵').setRequired(false);
// ---- ④ 3ページ目: オンライン参加の詳細 ----
var pb3 = form.addPageBreakItem().setTitle('3. オンライン参加の詳細');
form.addCheckboxItem().setTitle('使用端末(複数選択可)').setChoiceValues(['パソコン', 'タブレット', 'スマートフォン']).setRequired(true);
form.addCheckboxItem().setTitle('参加したい企画(複数選択可)').setChoiceValues(['基調講演', '座談会', '表彰式', 'じゃんけん大会']).setRequired(true);
// ---- ⑤ 4ページ目: アンケート(現地・オンライン合流点)----
var pb4 = form.addPageBreakItem().setTitle('4. イベント内容のアンケート');
form.addSectionHeaderItem().setTitle('■ 全員にお答えください');
form.addGridItem().setTitle('各企画への参加予定').setRows(['基調講演', '表彰式', '懇親会']).setColumns(['参加する', '参加しない', '未定']).setRequired(true); // 行x列の表
form.addCheckboxGridItem().setTitle('日程候補の都合').setRows(['10月10日', '10月17日', '10月24日']).setColumns(['参加できる', '参加できない']).setRequired(false); // 複数回答可の表
form.addScaleItem().setTitle('期待度(1〜5)').setBounds(1, 5).setLabels('低い', '高い').setRequired(true); // 段階評価
form.addTextItem().setTitle('参加合計人数').setHelpText('1〜10を半角数字で。').setRequired(true)
.setValidation(FormApp.createTextValidation().requireNumberBetween(1, 10).build()); // 範囲チェック
// ---- ⑥ 5ページ目: 最終確認 ----
form.addPageBreakItem().setTitle('5. 最終確認');
form.addMultipleChoiceItem().setTitle('イベント中の写真の掲載について').setChoiceValues(['掲載してよい', '顔がはっきり写るものは掲載しないでほしい', '掲載しないでほしい']).setRequired(true);
form.addCheckboxItem().setTitle('最終確認').setChoiceValues(['内容を確認し、申し込む']).setRequired(true);
// ---- ⑦ 分岐(ページ遷移)の設定 ----
qType.setChoices([
qType.createChoice('現地参加', pb2), // → 2ページ目
qType.createChoice('オンライン参加', pb3) // → 3ページ目
]);
pb3.setGoToPage(pb4); // 現地の人は2ページ目を終えたら3ページ目を飛ばして4ページ目へ
// ---- ⑧ ログにURLを表示 ----
Logger.log('■ 編集用URL: ' + form.getEditUrl());
Logger.log('■ 回答用URL: ' + form.getPublishedUrl());
return form.getEditUrl();
}
実行手順と初回の承認
1.関数選択で「createEventForm」を選ぶ(初期設定の myFunction から変更)
2.▶実行 → 初回は「承認が必要です」と出るので、自分のアカウントで「許可」
3.実行ログに「編集用URL」「回答用URL」が表示される。「回答用URL」を参加者に共有すれば募集開始です
注意:実行するたびに新しいフォームが作られるので、実行は1回だけにしましょう。
コードのポイント解説
ページ分けと分岐(⑦の部分) addPageBreakItem()が「ページ区切り」で、置いた順番=ページ順(5ページ構成)です。「参加形式」の各選択肢に遷移先ページを紐づけるのが⑦のsetChoicesで、pb3.setGoToPage(pb4) が「現地の人がオンライン用の3ページ目を飛ばしてアンケート(4ページ目)へ合流する」設定です(PageBreakItem 公式リファレンス)。フローは以下の通りです。
1.基本情報 ─┬現地参加→ 2.現地詳細 ─(3ページ目スキップ)→ 4.アンケート → 5.最終確認 → 送信
└オンライン参加→ 3.オンライン詳細 ────────→ 4.アンケート → 5.最終確認 → 送信
入力チェック ②のメールアドレス設問の requireTextIsEmail() でメール形式を、⑤の参加人数の requireNumberBetween(1, 10) で1〜10の数値を強制しています。URL形式・文字数上限などのチェックもあります(TextValidationBuilder 公式リファレンス)。
高度な設問 ⑤の「グリッド」は行×列の表、「チェックボックスグリッド」は複数回答可の表、「スケール」は1〜5の段階評価です。いずれも画面操作と同じ設問型です。
自動保存 ①のtryブロックが、回答用スプレッドシートを自動作成してフォームに接続します。失敗してもフォーム作成は継続する設計です。
回答受付時の自動メール
次のコードを追記すると、回答のたびに「受付完了メール」を自動送信できます。
// 回答時の自動返信メール関数。設定: 左メニュー「トリガー」→「トリガーを追加」
// → 実行する関数: sendThankYouMail / イベントの種類: フォーム送信時 / 保存。
// ※送信イベントで自動実行されるため、▶実行ボタンでは動きません。
function sendThankYouMail(e) {
var name = '';
var mail = '';
var rows = e.response.getItemResponses();
for (var i = 0; i < rows.length; i++) {
var title = rows[i].getItem().getTitle();
var value = rows[i].getResponse();
if (title === 'お名前') { name = value; }
if (title === 'メールアドレス') { mail = value; }
}
if (!mail) { return; }
MailApp.sendEmail({
to: mail,
subject: '【秋のオフィス交流会】受付完了のお知らせ',
body: name + ' 様\n\nお申し込みを承りました。\n詳細が決まり次第ご連絡いたします。\n\nイベント運営事務局'
});
}
設定は左メニュー「トリガー」→「トリガーを追加」→ 実行する関数:sendThankYouMail / イベントの種類:フォーム送信時 → 保存です(インストール可能なトリガー 公式ガイド)。コード内の「お名前」「メールアドレス」は、フォームの設問タイトルと完全一致させる必要があります。なお、ファイル添付設問は2026年現在、スクリプトでは作れずフォーム編集画面(UI)でのみ追加でき、追加すると回答者にGoogleアカウントのサインインが求められる点も注意してください。
カスタマイズのコツ
変数名は触らず、引用符の中だけ書き換えるのがコツです。
| 変更したい内容 | コードの場所 |
|---|---|
| フォームのタイトル | ①の FormApp.create(…) の中身 |
| 設問の文言 | 各設問の setTitle(…) |
| 選択肢 | setChoiceValues([…]) の中身 |
| 必須/任意 | setRequired(true) を false に |
| 完了メッセージ | setConfirmationMessage(…) |
よくあるエラーと対処
| 症状 | 対処 |
|---|---|
| 初回の「承認が必要です」 | 自分のアカウントで許可して問題ありません |
| 「関数が定義されていません」 | 誤字があります。実行ログの行番号を確認 |
| フォームが作られない | 関数の選択が createEventForm になっているか確認 |
| 分岐が効かない | 分岐させる設問を必須にして、setChoices を最後に書く |
| 自動メールが届かない | トリガーと承認の設定を確認 |
応用:どんなフォームに使えるか
このコードの仕組みは、次のような場面にそのまま流用できます。
学会・セミナーの参加申込(参加形式や会場で分岐させたいとき)
研修・部活動イベントの事前アンケート(日程候補×都合のマトリクスが活きる)
宿泊・移動手段の手配を伴うイベントの同意書兼アンケート(設問を同意チェック式に拡張)
構造はすべて共通なので、setTitle() と setChoiceValues() の中身を書き換えるだけで別のフォームになります。分岐の行(⑦)だけは、ページ区切りの変数名(pb2, pb3, pb4)と合わせて編集してください。
トリガーをさらに活用する
フォーム送信時のトリガーは一度登録すれば繰り返し使えます。同じ処理の中で、回答内容を整形して別のシートに書き出す、担当者への通知を自動化する、といった処理も、このコードに数行追加するだけで実現できます。
よくあるエラーで多いのは「グリッド設問の行・列が空のまま実行する」ケースです。実行ログに表示される行番号と、コードの貼り直しで、大半のトラブルは解決します。
検証方法
本記事の2つのコードは、構文チェックに加え、FormApp などのAPIを挙動再現したモック環境で実行し、全20項目が合格しています(20件の設問と5ページが正しく並ぶこと、分岐2件とスキップ設定が入ること、メール形式・人数範囲のチェック、各フォーム設定、返信メールの宛先・本文 を確認)。Googleアカウント上での初回承認操作だけはこの環境では実行できないため、実行時に画面の指示に従ってください。
まとめ
コードでフォームを管理すれば、再現も改造も自由自在です。研修の事前アンケートや学会の申込など、どんなフォームにも応用できます。まずは今日、5分で1つ作ってみてください。




















