はじめに
本記事は以下のような方の役に立つはずです。
・GoogleフォームのGASをテスト/デバッグするときに毎回フォーム送信するのが手間だと思っている人
・スクリプトエディタでデバッグ実行し、ブレークポイントを置きながらテストしたい人
・エラーになったとき、フォームを再送信してもらうのが難しいので、回答スプレッドシートに書き込まれたデータでリトライしたい人
前提
以下の関数が、Form回答スプレッドシート内のスクリプトエディタでトリガー設定されているとします。
function formTriggerFunction(event) {
// スプレッドシートに書き込まれた行番号を取得する
const writeRowNum = event.range.getLastRow();
console.info(`${writeRowNum}行目のデータを処理します。`);
// namedValuesを取得する
const namedValues = event.namedValues;
console.info(namedValues);
}
トリガー設定方法
トリガー実行時にeventが関数に渡される
フォームが送信されると自動的にフォームの回答などの情報が入ったevent
オブジェクトを引数として渡し、関数が実行されます。
Formの内容は namedValues
オブジェクトに
key: Formの質問名
Value: Formの入力値の配列
の形式で入っています。
このような namedValues オブジェクトになります。
// event.namedValues
{
'ラジオボタン': [ '選択肢 1' ],
'記述_短文': [ '回答' ],
'タイムスタンプ': [ '2025/01/20 22:34:38' ],
'チェックボックス': [ '選択肢 2, その他項目' ]
}
回答の取得は
const timeStamp = event.namedValues["タイムスタンプ"][0];
console.info(timeStamp); //'2025/01/19 1:09:38'
のようにすると取得できます。
スクリプトエディタからの実行ではeventが渡されないのでエラーになる
引数が設定されずUndefined
になってしまうためエラーになってしまいます。
こうなると、テストのたびにフォームを送信することになり手間です。
そして、トリガーでの実行だと、ブレークポイントを置いて処理を止めながらデバッグすることが出来ないという問題があります。
手動でevent引数を再現する
このような問題を解決する方法として
トリガーで自動設定される event
を回答スプレッドシートに書き込まれたデータから再現する。
という方法で解決していきます。
ここでは
・フォームの内容が入っている namedValues
・回答スプレッドシートに書き込んだ範囲 range
の2項目のみを再現します。
他の項目は公式ドキュメントに記載があります。(再現できるかは未検証です...)
再現するコード
function reproductionEvent(targetRow) {
// スプレッドシート、シート取得
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName("フォームの回答 1");
// 最終列取得
const lastColumn = sheet.getLastColumn();
// 質問を取得
const questionValues = sheet.getRange(1, 1, 1, lastColumn).getDisplayValues()[0];
// 回答が書き込まれた範囲を取得
const range = sheet.getRange(targetRow, 1, 1, lastColumn);
// 回答を取得
const anserValues = range.getDisplayValues()[0];
// namedValuesを再現する
const namedValues = {};
for (const index in questionValues) {
namedValues[questionValues[index]] = [anserValues[index]];
}
// eventを再現する(namedValues, rangeのみ)
const event = {namedValues, range};
// eventを返す
return event;
}
処理内容
回答スプレッドシートの
1行目の質問名をkey
指定した行のデータをvalue
にして namedValues
を再現しています。
以下のような回答スプレッドシートだったら
1 | タイムスタンプ | 記述_短文 | ラジオボタン | チェックボックス |
---|---|---|---|---|
2 | 2025/01/20 23:18:57 | 回答 | 選択肢 1 | 選択肢 1, その他手入力 |
3 | 2025/01/20 23:19:11 | 回答2 | 選択肢 1 |
■ targetRow「2」を指定した場合
{
'タイムスタンプ': [ '2025/01/20 23:18:57' ],
'記述_短文': [ '回答' ],
'ラジオボタン': [ '選択肢 1' ],
'チェックボックス': [ '選択肢 1, その他手入力' ]
}
■ targetRow「3」を指定した場合
{
'タイムスタンプ': [ '2025/01/20 23:19:11' ],
'記述_短文': [ '回答2' ],
'ラジオボタン': [ '選択肢 1' ],
'チェックボックス': [ '' ]
}
このため、過去のデータをリトライするということも出来ます。
使い方
以下のようにするとeventを再現後引数に設定し関数が実行されます。
function manualRun() {
// 行数を指定
const targetRow = 3;
// eventを再現する
const event = reproductionEvent(targetRow);
// 処理を実行
formTriggerFunction(event);
}
無事Formトリガーを設定している関数がスクリプトエディタから実行されました。
コード全体
// Form送信時トリガーを設定する関数
function formTriggerFunction(event) {
// スプレッドシートに書き込まれた行番号を取得する
const writeRowNum = event.range.getLastRow();
console.info(`${writeRowNum}行目のデータを処理します。`);
// namedValuesを取得する
const namedValues = event.namedValues;
console.info(namedValues);
}
// event を再現する関数
function reproductionEvent(targetRow) {
// スプレッドシート、シート取得
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName("フォームの回答 1");
// 最終列取得
const lastColumn = sheet.getLastColumn();
// 質問を取得
const questionValues = sheet.getRange(1, 1, 1, lastColumn).getDisplayValues()[0];
// 回答が書き込まれた範囲を取得
const range = sheet.getRange(targetRow, 1, 1, lastColumn);
// 回答を取得
const anserValues = range.getDisplayValues()[0];
// namedValuesを再現する
const namedValues = {};
for (const index in questionValues) {
namedValues[questionValues[index]] = [anserValues[index]];
}
// eventを再現する(namedValues, rangeのみ)
const event = {namedValues, range};
// eventを返す
return event;
}
// 手動実行用関数
function manualRun() {
// 行数を指定
const targetRow = 3;
// eventを再現する
const event = reproductionEvent(targetRow);
// 処理を実行
formTriggerFunction(event);
}