今までの記事一覧
- GASでGoogleForm回答を取得するなら lastRow?(e)?試してみた
- onFormSubmit(e)を手動実行でデバッグする方法
- どっちを使う?onFormSubmit(e)の values と namedValues の違いと使い分け
- onFormSubmit(e) の e.values 配列順のしくみ
- Googleフォームで質問を変えても壊れない!cleanFormData(e)でnamedValues防御力をアップ <この記事
- Googleフォームの質問変更に負けない!「部分一致」と「秘密の暗号」でcleanFormData(e)の防御力を鉄壁に
- 手動コピペはもう卒業!Googleフォームの回答別に処理を自動仕分け
- Googleフォームで同時に大量送信されても踏ん張る!LockServiceで順番制御!try - catch - finally でバトンを繋げ!
- LockServiceでは順番は守れない?受付番号で順序を保証する方法
前提
この記事は、フォーム回答を保存している スプレッドシート側のGAS を前提にしています。
トリガーは以下を設定しています。
- スプレッドシートから
- フォーム送信時
前回はe.valuesの配列順のしくみとリセットについて確認しました。
今回はもう一度namedValuesの弱点と、できるだけ実務で安全に使う方法を考えてみましょう。
おさらい:namedValuesの弱点
namedValuesは便利ですが、実務で使うには次のような問題があります。
-
配列地獄:
namedValuesは配列なのでnamedValues["質問名"][0]と、いちいち[0]を付けなきゃいけなくてめんどくさいし可読性が悪い。 - 型がすべて文字列: 数値や日付として扱いたい場合でも文字列で返ってくる。
-
フォーム変更に弱い: 質問タイトル(キー名)が変わると
undefinedエラーになる。
ユーティリティ関数を使おう
実務では、onFormSubmit(e)の中で直接namedValuesを扱うのではなく
下準備用の自作関数(ユーティリティ関数ともいう)を用意することが多いです。
今回はfunction cleanFormData(e)という名前の関数を自分で作り、
-
namedValuesを整理する -
[0]を取り除く - 取得できない場合は空文字にする
という処理をまとめて行います。
/************************
* メインの関数
**************************/
function onFormSubmit(e) {
// 1. function cleanFormData(e)に行く
const formData = cleanFormData(e);
// 2. 後続の処理では「翻訳後の名前」を使う
// これなら、質問文が変わってもここ(メイン処理)は書き換えなくてOK!
Logger.log("email:"+ formData.email);
Logger.log("name:"+ formData.name);
Logger.log("body:"+ formData.body);
}
/************************
* 自作関数(フォームの質問文をプログラム用の名前に変換)
**************************/
function cleanFormData(e) {
const namedValues = e.namedValues;
// ここで「フォームの質問文」と「プログラムで使いたい名前」を紐付ける
return {
// 左側:プログラムで使う名前 / 右側:実際のフォームの質問文
email: namedValues["メールアドレス"] ? namedValues["メールアドレス"][0] : "",
name: namedValues["お名前"] ? namedValues["お名前"][0] : "",
body: namedValues["お問い合わせ内容"] ? namedValues["お問い合わせ内容"][0] : ""
};
}
ユーティリティ関数の動き
メイン関数function onFormSubmit(e)の
const formData = cleanFormData(e);の行で
いきなりfunction cleanFormData(e) に飛びます。
(正確にはcleanFormData(e) を呼び出す、と言います)
function cleanFormData(e) の処理結果(returnされた値)がメイン関数に戻ってきて
変数formDataに入るイメージです。
三項演算子
email: namedValues["メールアドレス"] ? namedValues["メールアドレス"][0] : "",
この行は、三項演算子という書き方で、以下の処理をまとめてやっています。
- 質問名 ”メールアドレス” があったら
- その回答([0]番目の中身)を取り出す
- 質問名 ”メールアドレス”がなかったら
- 代わりに空文字("")を返す
この行の最大のメリット
この行の役割は、質問名が変わったときの undefinedエラーの回避 です。
本来、存在しない質問名に対して [0] を指定すると「そんなの無いよ!」とエラーで止まってしまいますが、この書き方なら「無いときは空欄」として処理を続けてくれるので、スクリプトが途中でエラー停止しません。
if文のこれと同じ意味です。
let email;
if(namedValues["メールアドレス"]){ // その項目が存在するかチェック
email = namedValues["メールアドレス"][0];
} else {
email = "";
}
この関数を動かした結果
まとめ
今回は、ユーティリティ関数function cleanFormData(e)をメインの関数の中にいれることで
- 配列地獄解消:関数の外では [0] を書かなくて済むのでスッキリ!
-
エラー回避:質問名が変わっても
undefinedで止まらない!
でも結局質問名が変わったらうまく取得できないじゃん
そう、今回は質問名を完全一致で取得する方法をご紹介しました。
次回は「メールアドレス」が「メールアドレスをお願いします」に変わっても対応できる
部分一致で取得する方法をご紹介します。

