結論
Googleフォームから実行するべき場合とは
- フォーム送信結果をスプレッドシートに 書き出す前に 実行したいことがある場合
- 編集用URLを「簡単に」1取得したい場合
- フォーム送信結果をスプレッドシートにリンクさせない場合
Googleスプレッドシートから実行するべき場合とは
- フォーム送信結果をスプレッドシートに 書き出した後に 実行したいことがある場合
- フォーム送信結果を1次元配列で取得したい場合
- フォーム送信結果が挿入された範囲(range)を取得したい場合2
つぶやき
「Googleフォームで送信された内容をGoogle Apps Scriptで遊んでみましょう」というのは、GAS学習でよく見かける最初の一歩です。
GAS紹介サイトなどでも初期からよく取り上げられており、私も以前フォーム送信時にメールを送信するスクリプトについて紹介しました。
さてこの「Form Submit」、元々はGoogle スプレッドシートのお家芸でしたが、新しいGoogle フォームがリリースされてからはGoogle フォームからでも実行できることは皆様ご存知のとおり3。
これにより「フォーム側で用意したスクリプト」を使っても同じようなことができるようになったのですが、フォーム入力データを取り出す際のデータの取り出し方が違うため、うっかりしてるとドツボにはまることになります。私も最初はまりました。
「はまり箇所を避ければどっちを使っても良いんじゃない?」
私もそんな風に思っていた時期がありました。
「Scriptを作る際は、以前作成して(動作実績が)あるものをコピーするから気にしたことないよ」と。
でも実際は微妙に動作が違うんですね。
今回はそんなお話です。
動作の違いを知っておくべきシチュエーション
昔スプレッドシート用に作成したスクリプトをフォーム用に使い回す
「同じForm Submit だから大丈夫だよね」みたいに考えていると値の取り出し方ではまります。
単純に配列指定すれば取り出せるスプレッドシート側トリガーの方が個人的には好きです。
なのですが・・・
フォーム編集用URLをスプレッドシートに書き出す
私はこれをやろうと思った時にはまりました。
Form Submitをスプレッドシート側から実行した場合、イベントオブジェクト e
に編集用URLデータはありません。
そのためgetEditReponseUrl()を実行するためには
-
FormApp.openById(fid).getResponses()
を用いて送信結果をFormResponse[]形式でまるっと取得し - 配列の中から対象のデータを捜索し4
-
getEditResponseUrl()
を実行する
という手順を踏まねばならず「実行メソッド増やすと処理時間が長くなるからイヤ!」という思いもあり5、なんだか面倒くさいなぁと思っていたのです。
編集用URLを「そのデータがスプレッドシート側に書き出された行」に追記する
個人的どハマりポイントその2。
「フォーム編集用URLを取り出すだけならスプレッドシート側のトリガーとして実行する必要ないよね」という発想でフォーム側トリガーを用いてスクリプトを書き始めた、というのが今回(&次回)のエントリーを投稿しようと思ったきっかけなのですが。
1. 実行タイミングにどハマる
スプレッドシート側で設定したForm Submitトリガーは「フォーム送信結果が、リンクされたスプレッドシート側に書き出された 後に スクリプトが実行」されます。
そのため手順としては
- トリガーが実行されたら
- 編集用URLを取得して
- シートの最終行のどこかに追記する
で良いのですが、フォーム側でトリガーを実行してしまうと「リンクされたスプレッドシート側に書き出される __前に__スクリプトが実行」されてしまうため
- トリガーが実行されたら
- 編集用URLを取得して
- シートの最終行= __一つ前の(新規で送信された)フォーム入力結果を記載した行__のどこかに追記する
となってしまい、おかしなことになってしまいます。
2.トリガー条件にどハマる
加えて。
フォーム側で設定されたForm Submitトリガーは
- 「新規で送信された場合」
だけでなく
- 「送信済み結果を編集し、再送信した場合」
も実行されるため、実行トリガーが後者の場合は実行キャンセルが必要になります。
どちらが良いとか悪いという話ではないのですが、うまく使い分けしたいですね。