何が自動になるの?仕組みを30秒で理解する
この仕組みでは、人が手を動かすのはコードを貼ってトリガーを設定するところまでで、それ以降のフォーム回答のスプレッドシートへの書き込みはすべて自動で行われます。
- 01入力Googleフォームの回答
- 02トリガーフォーム送信時に onFormSubmit が動く
- 03転記必要な列だけ集計シートへ追記
- 04確認列ずれ・空欄をテスト送信で確かめる● 人が確認
ここで使うのはGoogle Apps Script(GAS)という、Googleが無料で提供しているプログラムの仕組みです。名前は聞き慣れないかもしれませんが、コードはこの記事に載せているものをそのまま貼り付ければ動くので、プログラミングの経験は前提にしていません。
動く流れは次の3段階です。
- 誰かがGoogleフォームに回答を送信する
- GASが「フォームが送信された」という合図を受け取る
- GASがスプレッドシートの集計用シートに回答を自動で書き込む
この「合図を受け取る」仕組みをトリガーと呼びます。フォームが送信されたときだけGASを起動する、という条件をあらかじめ登録しておくイメージです。トリガーの設定自体はクリック操作だけで終わります。つまり、自分で作業するのは最初の設定だけで、設定が終わってしまえば日々の転記作業からは手が離れます。
作業を始める前に確認しておくこと
コードを貼る前に、フォームとスプレッドシートの紐づけとApps Scriptエディタの開き方の2点を確認しておくと、途中で迷う時間を減らせます。
フォームとスプレッドシートが紐づいているかどうかは、Googleフォームの「回答」タブを開けば確認できます。タブの右上に緑色のスプレッドシートアイコンが出ていれば、そこから回答先のスプレッドシートを指定できます。すでに紐づいている場合は「スプレッドシートで表示」という表示に変わっているので、クリックすれば回答先のシートへ移動します。
Apps Scriptエディタは、紐づけ済みのスプレッドシートを開き、メニューの「拡張機能」から「Apps Script」を選ぶと別タブで開きます。このあとのコードは、すべてこの画面に貼り付けていきます。フォームとスプレッドシートの連携設計そのものについては、回答をスプレッドシートに集計 | Google フォームの使い方にも整理されています。
実際にコードを貼り付けて動かしてみる(Step1〜6)
Step1からStep6まで順番に進めれば、フォーム送信と同時に集計シートが更新される状態になります。途中でつまずきやすい箇所には、その都度注意点を添えています。
Step1: フォームとスプレッドシートを紐づける
Googleフォームを開き、「回答」タブをクリックします。右上の緑色のスプレッドシートアイコンをクリックし、「新しいスプレッドシートを作成」または「既存のスプレッドシートを選択」を選んで回答先を指定してください。
ここで詰まりやすいのは、既存のスプレッドシートを選んだ場合に「フォームの回答1」という名前のシートが自動で増える点です。このシートはフォームが標準で作る記録用で、これから作る集計用シートとは別物なので、削除せずそのまま残しておいてください。
Step2: GASエディタを開く
紐づけたスプレッドシートを開き、メニューの「拡張機能」から「Apps Script」を選びます。新しいタブでGASのエディタ画面が開きます。
最初からfunction myFunction() {}というコードが入っていますが、これは全部削除してください。次のステップで別のコードを貼り付けます。複数のタブを開いたまま作業していると、どのタブがエディタかわからなくなって手が止まる人が多いので、作業中はこのタブだけを前面に出しておくと迷いません。
Step3: コードを貼り付けて保存する
エディタが空になったら、以下の2つのコードをまとめて貼り付けます。上から順にそのままコピーしてください。
フォーム送信トリガーで回答を集計シートに追記するスクリプト
Googleフォームの送信イベントを受け取り、回答内容を「集計」シートの末尾に自動で追記します。
// フォーム送信時に自動実行される関数(トリガーに登録する)
function onFormSubmit(e) {
const SHEET_NAME = "集計"; // 書き込み先シート名
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = getOrCreateSheet(ss, SHEET_NAME);
// フォームの回答を配列で取得(タイムスタンプ + 各質問の回答)
const responses = e.values; // ["2024/01/15 10:30:00", "回答1", "回答2", ...]
// シートの末尾行に追記
sheet.appendRow(responses);
}
集計シートが存在しない場合に自動作成しヘッダーを挿入する処理
「集計」シートがまだない場合でも自動で作成し、1行目にフォームの質問項目をヘッダーとして挿入します。
// シートを取得、なければ新規作成してヘッダーを挿入
function getOrCreateSheet(ss, sheetName) {
let sheet = ss.getSheetByName(sheetName);
if (!sheet) {
sheet = ss.insertSheet(sheetName);
// フォームと連携したスプレッドシートから質問項目を取得
const formUrl = ss.getFormUrl();
if (formUrl) {
const form = FormApp.openByUrl(formUrl);
const items = form.getItems();
// ヘッダー行:タイムスタンプ + 各質問タイトル
const headers = ["タイムスタンプ", ...items.map(item => item.getTitle())];
sheet.appendRow(headers);
// ヘッダー行を太字・背景色で装飾
const headerRange = sheet.getRange(1, 1, 1, headers.length);
headerRange.setFontWeight("bold").setBackground("#d9ead3");
}
}
return sheet;
}
貼り付けたら保存します。保存ボタンはエディタ上部のツールバー中央付近にあるフロッピーディスクのアイコンです。ブラウザのウィンドウ幅が狭いとアイコンが折りたたまれて見えなくなることがあるので、見当たらない場合は表示倍率を下げるか、キーボードでCtrl+S(Macはcommand+S)を押すと保存できます。エラーが出なければ保存は成功です。
Step4: トリガーを設定する
コードを保存しただけでは、まだ自動では動きません。「フォームが送信されたときに起動する」という指示をGASに伝える必要があります。これがトリガーの設定です。
エディタ左側のメニューにある時計のアイコン「トリガー」をクリックし、右下の「トリガーを追加」ボタンを押します。設定画面で次の3項目を選んでください。
- 実行する関数:
onFormSubmit - イベントのソース:スプレッドシートから
- イベントの種類:フォーム送信時
設定できたら「保存」をクリックします。ここで、保存ボタンを押しても画面が切り替わらず固まったように見えることがありますが、これは承認画面の読み込み待ちであることがほとんどです。数秒待っても変化がない場合は、一度タブを再読み込みしてからトリガー画面を開き直すと、承認ダイアログが正しく表示されます。
なお、コードの中にはsetTrigger()という関数も用意しています。トリガーをスクリプトから登録したい場合や、重複登録を防ぎたい場合は、こちらを1度だけ手動実行する方法もあります。
// ▼ トリガーをスクリプトから自動登録したい場合はこの関数を1度だけ手動実行する
function setTrigger() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
// 既存の同名トリガーを削除(重複防止)
ScriptApp.getProjectTriggers().forEach(trigger => {
if (trigger.getHandlerFunction() === "onFormSubmit") {
ScriptApp.deleteTrigger(trigger);
}
});
// フォーム送信時に onFormSubmit を起動するトリガーを登録
ScriptApp.newTrigger("onFormSubmit")
.forSpreadsheet(ss)
.onFormSubmit()
.create();
Logger.log("トリガーを登録しました");
}
Step5: Googleアカウントの承認を行う
トリガーを保存すると、「このアプリはGoogleアカウントへのアクセスを求めています」という承認ダイアログが表示されます。これはあなた自身のスクリプトが、あなた自身のスプレッドシートを操作するための許可を求める、通常の確認画面です。
「詳細」をクリックし、表示されたプロジェクト名のリンクをクリックしたあと、「許可」をクリックすると承認が完了します。ここでよく止まるのは、「詳細」のリンクが見当たらないケースです。画面を下にスクロールすると小さな文字で「詳細」と表示されていることが多いので、見落とさないようにしてください。承認画面がそもそも開かない場合は、ブラウザのポップアップブロックが働いている可能性があるので、ポップアップを許可してからトリガーの保存をやり直してください。
Step6: テスト送信して動作を確認する
設定が終わったら、実際にフォームをプレビューで開いてテスト回答を送信してみてください。スプレッドシートの「集計」シートに新しい行が追加されていれば成功です。
テスト送信が不安な場合は、GASエディタで次のテスト関数を実行する方法もあります。ダミーデータで動作を確かめられます。
// テスト用:フォーム送信イベントをダミーデータで模擬実行
function testOnFormSubmit() {
const dummyEvent = {
values: [
new Date().toLocaleString("ja-JP"), // タイムスタンプ
"テスト太郎", // 質問1の回答
"[email protected]", // 質問2の回答
"お問い合わせ内容のテスト" // 質問3の回答
]
};
onFormSubmit(dummyEvent);
Logger.log("テスト送信完了 → 集計シートを確認してください");
}
エラーが出た場合は、エディタ左メニューの「実行数」をクリックすると実行ログを確認できます。エラーメッセージをそのままコピーして検索すると、多くの場合は解決の手がかりが見つかります。実行してもログに何も表示されない場合は、保存を忘れている可能性が高いので、Step3の保存操作からやり直してみてください。
つまずいたときの対処(拡張版)
ここまでの手順でよく聞かれる詰まりどころは、次の6パターンにほぼ集約されます。症状から原因を探して対処してください。
| 症状 | 原因 | 対処 |
|---|---|---|
| トリガーを設定したのに集計シートに何も書き込まれない | コード内で指定したシート名と実際のシート名が一致していない | エディタの「実行数」ログでエラーを確認し、コード内のSHEET_NAMEを実際のシート名に合わせる |
| 承認画面に「このアプリはGoogleで確認されていません」と表示される | 自作のスクリプトが未検証のアプリとして扱われるため | 「詳細」からプロジェクト名のリンクを選び「許可」を押す。自分のスクリプトを自分のアカウントで動かす場合に出る通常の表示 |
| 回答が集計シートに重複して書き込まれる | 同じ関数に対するトリガーが複数登録されている | 「トリガー」画面を開き、同じ関数に対するトリガーが2つ以上あれば古いものを削除する |
| 日本語の回答が文字化けして見える | 実行ログの表示上の問題であることが多く、セルの値自体は正常なケースがほとんど | スプレッドシートのセルを直接開いて値を確認する。セルの値が正しければ対応は不要 |
| 複数のフォームの回答を1つのスプレッドシートにまとめたい | フォームごとに紐づくスプレッドシートが別であること、1つのスプレッドシートに対してトリガーは複数登録できること | まとめたいスプレッドシートを開き、フォームごとに「トリガーを追加」を繰り返して、それぞれのフォームに対応するonFormSubmitトリガーを登録する。シート名をSHEET_NAMEでフォームごとに分けておくと、どの回答がどのフォーム由来かが追いやすくなる |
| フォームの質問項目を後から増減したらヘッダーの列とデータの列がずれた | ヘッダー行は集計シートを新規作成したときの1回だけ書き込まれる仕組みのため、あとから質問を変えてもヘッダーは自動更新されない | 質問を変更した場合は、集計シートの既存のヘッダー行を手動で削除してから再度フォームをテスト送信するか、getOrCreateSheetを実行し直して新しいヘッダーを作り直す。既存データ行を残したい場合は、ヘッダーだけを新しい質問に合わせて手で書き換え、スクリプト側の列番号も同じ順に直します。そのうえでテストの回答を1件送り、転記先の列がずれていないことを確認してから運用に戻してください。 |

GAS外注の要件定義シート・契約の取り決め・納品後のログ運用
GAS自動化を外注する前に決めておく作業の切り分けと依頼文
GASが向く作業と向かない作業を実際の移行経験から整理する