- 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 を前提にしています。
トリガーは以下を設定しています。
- スプレッドシートから
- フォーム送信時
前回はonFormSubmit(e)で
-
e.valuesはフォーム内容が変わっても崩れにくいけど配列順を数えるのが大変 -
e.namedValuesは可読性はいいけどフォームの質問文が変わるをエラーになる
それぞれのメリットデメリットを確認しました。
今回はe.valuesの挙動について調べていきたいと思います。
e.valuesの配列内の順番はスプレッドシート接続時の順番
まずは普通のフォームで確認
こんなフォームがあったとき

こうやってe.valuesで回答の中身を取り出すと
function form_test(e) {
Logger.log(JSON.stringify(e.values));
}
こういう結果が返ります。
["2026/**/** **:**:23","これは1問目の回答です","これは2問目の回答です"]
タイムスタンプはシステムが勝手に入れるので
何の変哲もなく普通の順番です。
スプレッドシートもこうなっています。

質問を途中に追加
ではここで1問目と2問目の前に0問目を追加してみましょう。

e.valuesを取り出した結果はこちらです。
["2026/03/** **:**:29","1問目の回答です","2問目の回答です","0問目の回答です"]
スプレッドシートはこんな感じ。
後から追加した0問目は一番最後に追加されています。
削除したらどうなる?
["2026/03/** **:**:02","1問目の回答","","0問目の回答"]
2問目が入るべき部分は""になっています。
フォームで質問項目が削除されてもe.valuesの中では
履歴が残るんですね。
2問目の質問は削除されたけど、列名は消えません。
e.valuesの正体
つまり、e.valuesでは、一度作られた順番は堅持、
フォームで後から作った質問はフォーム上のどの場所にあっても
e.valuesの配列順は一番後ろに追加。
そしてこの順番は
スプレッドシートの列順と完全に一致しています。
e.valuesはフォームではなくスプレッドシートの列順が基準なのです。
これがe.valuesの大きな特徴です。
フォームの順番と
e.valuesの順番が違うの、なんだか不便じゃね?
いえいえ、GASで処理を書くとき、これがめちゃくちゃ大きなメリットなんです。
順番が崩れないメリット
例えばこんなコードがあったとします。
function onFormSubmit(e) {
const timestamp = e.values[0]
const question1 = e.values[1]
const question2 = e.values[2]
//以下、何かの処理
}
e.valuesの中身はこれ
["2026/**/** **:**:23","これは1問目の回答です","これは2問目の回答です"]
この場合、
- question1 >> "これは1問目の回答です"
- question2 >> "これは2問目の回答です"
になります。
ここに0問目を追加したらどうでしょう。
["2026/**/** **:**:23","これは1問目の回答です","これは2問目の回答です","これは0問目の回答です"]
GASコードはこうします。
function onFormSubmit(e) {
const timestamp = e.values[0]
const question0 = e.values[3] //これを追加するだけ
const question1 = e.values[1]
const question2 = e.values[2]
//以下、何かの処理
}
「2問目」を削除した場合も
["2026/**/** **:**:23","これは1問目の回答です","","これは0問目の回答です"]
function onFormSubmit(e) {
const timestamp = e.values[0]
const question0 = e.values[3]
const question1 = e.values[1]
//const question2 = e.values[2] //この行を削除するだけ
//以下、何かの処理
}
つまりとても楽なのです。
もし配列の順番がフォームの質問順に入れ替わるとしたら
フォームが変わるたびにe.values[1]この数字を書き換えなきゃいけない。
1つでも間違えたらバグになっちゃう。
実務ではこれ、すごく大事なのです。
いじりすぎてカオスになったe.valuesはリセット
さて、この見本は質問が3つだけだからいいけど
質問がすごくたくさんあって、条件分岐も複雑だったらどうでしょう。
このフォームのここんとこ、回答内容によって質問内容変えれる?あと、こないだ入れたこの部分はやっぱいらない。で、こっちにこの質問追加で入れてよ。あ、それから....
上司、シバいていいですか。
順番がぐちゃぐちゃになったe.values、見るだけで頭痛が痛くなりますよね。
この順番、永久に固定というわけではありません。
実はリセットできちゃいます。
フォームの「回答」タブで、「スプレッドシートで表示」の横の点3つをクリックし
「フォームのリンクを解除」または
スプレッドシート側でシートタブの横の ▼ をクリックし
「フォームのリンクを解除」すると
フォームとスプレッドシートのリンクが切れます。
その後、もう一度リンクを繋げばOK。
削除された2問目が残り、0番目が1番後ろになっているこのシートが

フォームのUIどおりに並べ替えられました!
しかも、今までの回答内容も全部入っています。
※ただし、フォームから削除された質問は復活しません。

ただ、残念なことにこの方法はe.valuesの順番もリセットします。
スプレッドシートの列構成が変わるため、既存のGASコードはそのままではバグります。ほぼ確実に。
今まで組んだGASは修正が必要になってしまいます。がっくり・・・
やっぱり namedValues かな。
弱点はあるけど、うまく使えば、コードの修正を最小限にできるかもしれません。
まとめ
-
e.valuesの順番はフォームの表示順ではなくスプレッドシートの列順 - フォームに質問を追加すると 配列の一番後ろに追加
- スプレッドシートとのリンクを作り直すと順番リセット
- 今までのフォームの回答は新しいシートにも引き継がれる
- リセットしたらGASの修正も必要
シンプルそうに見える e.values、なかなか奥が深いですね。
次回は namedValues を実務でどう扱うかについて考えてみます。


