Help us understand the problem. What is going on with this article?

GASのonFormSubmit()でハマったこと

フォームから回答が送信されたら自動的に色々処理を行うスクリプトをスプレッドシート側で書いていた時にハマったことを記録しておきます。

やろうとしたこと

(1)フォームから回答が流れてくる
(2)トリガ設定をフォーム送信時に設定したonFormSubmit(event)を起動
(3)event.responses.getItemResponses()で回答の配列を得る
(4)得たデータの特定要素の内容によって他のシートにデータをコピーする

具体的には送信者の所属によってデータを書き出すところを変えてまとめておきたかったのです。

エラー内容

実行に失敗: TypeError: undefined のメソッド「getItemResponses」を呼び出せません。

そもそもgetItemResponses()が呼び出せていません。つまりevent.responsesは存在しないことになっています。おかしいなあリファレンスもちゃんと見たのになあ〜

原因

ではリファレンスをもう一度見てみましょう。onFormSubmit()は二種類あります。

Google Sheets Event

Form submit

  • authMode
    A value from the ScriptApp.AuthMode enum
FULL
  • namedValues
    An object containing the question names and values from the form submission
{
  'First Name': ['Jane'],
  'Timestamp': ['6/7/2015 20:54:13'],
  'Last Name': ['Doe']
}
  • range
    A Range object, representing the cell or range of cells that were edited
Range
  • triggerUid
    ID of trigger that produced this event
4034124084959907503
  • values
    Array with values in the same order as they appear in the spreadsheet
['2015/05/04 15:00', 'amin@example.com', 'Bob', '27', 'Bill',
'28', 'Susan', '25']

Google Form Event

Form Submit

  • authMode

    A value from the ScriptApp.AuthMode enum

    FULL
    
  • response

    A FormResponse object, representing the user's response to the form as a whole

    FormResponse
    
  • source

    A Form object, representing the Google Forms file to which the script is bound

    Form
    
  • triggerUid

    ID of trigger that produced this event

    4034124084959907503
    

今回僕が利用しようとしていたのはGoogle Form events側のonFormSubmitです。しかしundefinedエラーを食らったので、responseが存在しないGoogle Sheetsevents側のonFormSubmitを呼び出していたのではないかと考察できます。ここで原因がわかりました。僕が冒頭に言ったことを覚えていますか?今回のスクリプトを「スプレッドシート側で書い」たのです。つまりresponseプロパティを持つonFormSubmitを使うためには、「フォーム側で」スクリプトを書かなければいけなかったのです!

コード修正

今回のパターンではスプレッドシート側で処理を行いたかったので、スプレッドシートAPIのonFormSubmitを利用するよう変更します。

勘違いしていた部分

function onFormSubmit(event){
  var itemResponses = event.response.getItemResponses();

  var bureau = itemResponses[0].getResponse();
  var name = itemResponses[1].getResponse();
  var email = itemResponses[2].getResponse();

  categorizer(bureau, name, email);
  sendToUser(name, email);
}

Sheets eventsのonFormSubmitで利用できるよう書き直したもの

function onFormSubmit(event){
  var itemResponses = event.values;

  var bureau = itemResponses[1];
  var name = itemResponses[2];
  var email = itemResponses[3];

  categorizer(bureau, name, email);
  sendToUser(name, email);
}

valuesなら生データが配列としてそのまま使えるので逆にすっきりしましたね。

おわりに

GASでイベントトリガを使うときはどこでスクリプトを書いているのかしっかり意識したうえで書きましょう!!

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away