趣旨:Googleフォームでハマったことをメモしておく
-
同じことでまたハマって時間を空費しないようにメモ。
-
以下、トリガーが返すイベントオブジェクトを
e
として記述します。
トリガーには Formsイベント と Sheets イベントの2種類があるので注意!
-
回答者がフォームを送信した際に発火するトリガーには2種類あります。
-
ひとつは、フォーム そのものに備わったトリガー
https://developers.google.com/apps-script/guides/triggers/events#form-submit_1 -
もうひとつは、フォームにリンクした スプレッドシート に備わったトリガー
https://developers.google.com/apps-script/guides/triggers/events#form-submit
フォームに備わったトリガー
- 回答を取得するには、イベントオブジェクト
e
から取得できるFormResponse
オブジェクトe.response
を用います。 -
e.response
は、空欄でないすべての質問への回答を含みます。- 以前の回答を編集する場合、フォームには前回送信した値が規定値として書き込まれています。予め入力されていた前回送信内容を編集しなくても、
e.response
には値が含まれます。 - 回答が必須でない質問を空欄(未解答)で送信すると、
e.response
には含まれません。その質問を指そうとすると属性が存在せず、エラーになります。
- 以前の回答を編集する場合、フォームには前回送信した値が規定値として書き込まれています。予め入力されていた前回送信内容を編集しなくても、
スプレッドシートに備わったトリガー
- 回答を取得するには、イベントオブジェクト
e
から取得できるオブジェクトe.namedValues
および配列e.values
を用います。 -
e.namedValues
およびe.values
は、更新のあった質問の回答だけを含みます。- 新規回答であればすべての回答を含みますが、以前の回答を編集した場合、前回から更新されなかった質問のデータは含まれません。
フォーム起動時のトリガーは、フォーム編集画面起動時なので注意!
- Googleフォームには「起動時」のトリガーがあるが、これは、フォーム回答者がフォームを開いた時ではなく 、フォーム作成者がフォーム編集画面を開いたときに発火するトリガーなので注意。
-
誰得なの?起動時トリガーは、フォームの選択肢を作成者が決め打ちせず、スプレッドシートなどに基づいて生成する際などに有用なのかもしれない。(本番運用時には、同じトリガーを1日1回など間隔を決めて実行する感じか)
https://developers.google.com/apps-script/guides/triggers/events#open_3
-
フォームに送信された回答は編集できない
- フォームにリンクしたスプレッドシートの内容は、送信後に編集・削除することが可能だが、フォームそのものに登録されている回答を編集することはできない(削除は可能)。
- スプレッドシートで編集した内容を、フォームの回答に反映することはできない。
- GAS には、フォームの回答を作成する
createResponse()
関数が備わっているが、回答の送信者はトリガーを作成したユーザーに設定されるため、任意の回答者の回答を置き換えることはできない。
- 回答者が「回答を編集」して送信済みのフォームを編集する際に、前回の回答をバックエンドで編集して表示するといったことはできない。
- 例えば、写真をアップロードするフォームで、回答者が前回までにアップした写真の一覧をフォーム画面に表示するような処理は(おそらく)できない。
- また、回答者が閲覧するフォーム画面を動的に編集できるトリガーも存在しないので、回答者のアカウントごとに、フォーム上に掲載する情報を動的に変えることもできない。
フォームとスプレッドシートは、フォームの回答とスプレッドシートの行が紐づけられている
- フォームとスプレッドシートをリンクしたとき、フォームのそれぞれの回答は、スプレッドシートの行に紐づけられている。より具体的には、おそらく、スプレッドシートの各セルのIDと紐づけられている。
- スプレッドシート側の行を削除してしまった場合、undo して行を復元しない限り、その行に対応するフォームの回答をスプレッドシート状に復元することは不可能。(紐づけられたIDを持つセルを復元しなければならない)
- undoで復元できない場合、いったんリンクを解除して、もう一度リンクを設定して新しいシートをつくるしかない(スプレッドシートは同じファイルでも可)。
- フォームを「以前の回答を編集できる」設定にしてある場合、スプレッドシート上で対応する行が削除されてしまっていると、以前の回答を編集したフォームが送信されても、スプレッドシートは更新されない(新たな行が追加されることはない)。(紐づけられたIDのセルが消失しているため)
- スプレッドシート側の行を削除してしまった場合、undo して行を復元しない限り、その行に対応するフォームの回答をスプレッドシート状に復元することは不可能。(紐づけられたIDを持つセルを復元しなければならない)
フォームの回答のIDのユニークさの特徴
- フォームの回答にはIDがあり、これに基づき、フォームから任意の回答を削除したりできる。
回答を1回に限定した場合の回答IDの性質
- 回答を1回に限定した場合、ユーザーはGoogleアカウントで認証を受け、同一のユーザーは1回しか回答できない。
- フォーム管理者が回答を削除すれば、再回答可能になるので、正確には「同時に2つの回答を登録することができない」である。
- この時、既存の回答が削除され、ユーザーが2度目以降の回答を登録する際、回答に付与されるIDは、既に削除した初回の回答に与えられていたIDと同一である。
- フォームには、同時に同じIDの回答は存在しないので、フォームではユニークな回答IDであるといえる。
- 一方、スプレッドシートにリンクして、フォームの回答を流し込んでいる場合、フォームの回答を削除しても、スプレッドシートのデータは、意図的に更新しない限りそのまま残る。スプレッドシートの回答が残っている場合、2度目以降の回答は、その行を上書きする(新たな行は加わらない)。
- 既存の回答を削除し、次の回答を過去の回答は別に扱いたい場合、回答IDでは区別できないので、自分で別の方法を用意しなければならないので、注意を要する。
全角スペースから半角スペースへの強制変換(自動変換)
- GASを用いてフォームの選択肢に文字列をセットするさい、GASの文字列変数に含まれる全角スペースが半角スペースに強制変換(自動変換)される。
- そのため、例えば、スプレッドシート中の文字列をフォームの選択肢にコピペし、フォームへの回答データで選ばれた選択肢とスプレッドシートを照合しようとする際などに、スプレッドシートでは全角スペースなのに、フォーム選択肢は半角スペースになっている為に、同じ文字列として照合できない不具合が発生しうる。
- こうした現象を織り込んで照合をコーディングしないと、スプレッドシートの範囲からプルダウンメニューの質問をつくって1つ選択させたのに、選択した値がスプレッドシートに見つからないといった謎の不具合が発生しうる。