- GoogleフォームからGoogleスプレッドシートにデータを送ってあれこれ処理をする話
- Googleフォームを編集するともう一度イベントが発火する
何がつまりやすいのか
- Googleフォーム内にある回答データと、スプレッドシートに書き出したデータは同期しない
- 回答の編集でスプレッドシートに送られてくるデータは、変更があった部分のみ(新規と編集で同じコードを使うにはひと工夫必要)
- 回答済みの情報を編集するには、編集URLを行追加しておくとよい(回答番号などでは編集URLは作成できない)
- GoogleフォームのIDは、発火イベントの引数からは受け取れない
- Googleフォーム連携で発火する処理は、Apps Scriptエディタ上ではデバッグできないので、Logをいっぱい仕込んでおくしかない
書き始め
- 以下のformAction(e)を、トリガー「スプレッドシートから - フォーム送信時」に入れます。(ここでは詳しく説明しません)
- 下書きはchatGPTに書いてもらっているのでコーディングルールが一貫していません、悪しからず。
- 新規か編集かを、新規の処理時に更新した列を見て判定しています。
function formAction(e) {
// 送信元のフォームのURL。
// 編集用のIDを取ってくるのが面倒なので、Googleフォーム編集時のURLを持ってきた
const formURL = "https://docs.google.com/forms/d/xxx/";
// 編集URLの列名
const colEditURL = "編集URL"
/* 受け取りデータの解析 */
var sheet = e.range.getSheet(); // フォームの結果シートを取得
// フォームの属性名(フォームの質問のタイトル)を取得
var form = FormApp.openByUrl(formURL);
var formResponse = form.getResponses();
// フォームから全ての質問アイテムを取得
var items = form.getItems();
// 質問アイテムのタイトル(属性名)を取得して配列に格納
var attributeNames = items.map(function(item) {
return item.getTitle();
});
//新規・編集を判定
var numRows = e.range.rowEnd;
var modeEdit = false;
// 既存のヘッダー行を取得
var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0];
if(sheet.getRange(e.range.rowEnd, headers.indexOf(colEditURL)).getValue()) {
// 対象行に編集URLが入っている場合、編集モードとみなす
modeEdit = true;
}
// 編集の場合、e.valuesは編集したデータ以外、空っぽなので、
// 対象行から、送られてきたデータを読み取っておく
// フォームの属性名と値を関連付けるオブジェクトを作成
var formData = {};
for (var i = 0; i < attributeNames.length; i++) {
var attributeName = attributeNames[i];
var attributeValue = sheet.getRange(e.range.rowEnd, headers.indexOf(attributeName)+1).getValue()
formData[attributeName] = attributeValue;
}
Logger.log("入力情報を解析しました。;" + JSON.stringify(formData));
//ここからメイン処理…
}
編集URLを取得
//編集URLのセット
if(!modeEdit){
var editUrl = formResponse[Number(formResponse.length - 1)].getEditResponseUrl();
sheet.getRange(numRows, headers.indexOf(colEditURL)).setValue(editUrl);
}
ここで、もし新規の処理のときに、GASで処理して書き換えた項目があれば、URLの引数に入れておくのを忘れないこと。
例:
var editUrl = formResponse[Number(formResponse.length - 1)].getEditResponseUrl() + "&entry.599468221=" + eventId;`
引数にしたいフォーム項目のentry.599468221
を確認するには、Googleフォーム側、右上の三点リーダーメニュー>「事前入力したURLを取得」から、適当に入力をして、URLを取得することで調べられる。