LoginSignup
3
2

More than 1 year has passed since last update.

010-Form Submitの違いを理解する

Last updated at Posted at 2018-04-28

結論

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()を実行するためには
1. FormApp.openById(fid).getResponses() を用いて送信結果をFormResponse[]形式でまるっと取得し
2. 配列の中から対象のデータを捜索し4
3. getEditResponseUrl() を実行する

という手順を踏まねばならず「実行メソッド増やすと処理時間が長くなるからイヤ!」という思いもあり5、なんだか面倒くさいなぁと思っていたのです。

編集用URLを「そのデータがスプレッドシート側に書き出された行」に追記する

個人的どハマりポイントその2。

「フォーム編集用URLを取り出すだけならスプレッドシート側のトリガーとして実行する必要ないよね」という発想でフォーム側トリガーを用いてスクリプトを書き始めた、というのが今回(&次回)のエントリーを投稿しようと思ったきっかけなのですが。

1. 実行タイミングにどハマる

スプレッドシート側で設定したForm Submitトリガーは「フォーム送信結果が、リンクされたスプレッドシート側に書き出された 後に スクリプトが実行」されます。
そのため手順としては

  1. トリガーが実行されたら
  2. 編集用URLを取得して
  3. シートの最終行のどこかに追記する

で良いのですが、フォーム側でトリガーを実行してしまうと「リンクされたスプレッドシート側に書き出される 前にスクリプトが実行」されてしまうため

  1. トリガーが実行されたら
  2. 編集用URLを取得して
  3. シートの最終行= 一つ前の(新規で送信された)フォーム入力結果を記載した行のどこかに追記する

となってしまい、おかしなことになってしまいます。

2.トリガー条件にどハマる

加えて。

フォーム側で設定されたForm Submitトリガーは

  • 「新規で送信された場合」

だけでなく

  • 「送信済み結果を編集し、再送信した場合」

も実行されるため、実行トリガーが後者の場合は実行キャンセルが必要になります。

どちらが良いとか悪いという話ではないのですが、うまく使い分けしたいですね。


  1. 取得自体はスプレッドシート側で実行しても簡単です。実行メソッド増やしたくないとかそんな理由(詳細は後述) 

  2. 3つ挙げたいがために書きましたが私自身この機能を利用したことはなく、使い道が思いつきません… 

  3. Sound Trickerさんが記事にされてました。 

  4. getResponses() で返されるデータは送信時刻の昇順となるためトリガー対象となるデータを引っ張るだけなら配列のlength-1を指定してあげればよく、実はそこまで面倒ではなかったりします。 

  5. 実際はこの程度であれば実行速度に影響を与えるとは思えないため、もう宗教上の理由みたいになっていますが。 

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2