質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.34%
Google フォーム

Google フォームは、 Google社が提供しているアンケートフォーム作成および集計ができる無料のツール。Googleアカウントがあれば利用が可能です。集計データは、スプレッドシートに収集され、データ分析もできます。

Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

Q&A

1回答

161閲覧

Google Apps Scriptで複数のgoogle formを元に送信時トリガーを作成した際に遭遇したerrorについて

Atom

総合スコア0

Google フォーム

Google フォームは、 Google社が提供しているアンケートフォーム作成および集計ができる無料のツール。Googleアカウントがあれば利用が可能です。集計データは、スプレッドシートに収集され、データ分析もできます。

Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

0グッド

1クリップ

投稿2024/11/22 06:29

目標

GASを使いgoogle form(以降form_A)からの回答内容を反映した新しいgoogle form(以降form_B)を作成し、form_Bの内容をgoogle calendarに反映させるスクリプトを書きたい。そのためform_Bの回答内容をスクリプト内で参照したい。

登場するトリガー

  • form_Aの送信時トリガー
  • form_Bの送信時トリガー <- errorが起きるトリガー

前提

form_Aの回答者は複数人いることを想定しているので、form_Aに回答した人が3人いればform_B-1, form_B-2, form_B-3が作られることとなり、送信時トリガーも3つ作られることになる。

発生している問題・エラーメッセージ

ここで起きた問題はform_Bの送信時トリガーでform_Bの応答IDが見つからないことです。

Exception: No response with ID {応答ID} exists for this form.  at onFormSecondSubmit(main:58:19)

該当のソースコード(Java Script(Google Apps Script))

  • form_Bの作成とトリガー作成関数の呼び出し
function make_body(json_obj, exist, new_form_url){ if(exist == true){ ~~~ 省略 ~~~ } else if(exist == false){ var [new_form_url, id] = create_form(json_obj) create_trigger(id)
  • form_Bの作成
function create_form(json_obj) { var form = FormApp.create(json_obj["氏名"]+"様") var pull_down = form.addListItem() form.setDescription("顧客情報") pull_down.setTitle("日にちの確定").setChoiceValues([json_obj["第一希望日"], json_obj["第二希望日"], json_obj["第三希望日"] ]) pull_down.setRequired(true) Utilities.sleep(1000); var url = form.getPublishedUrl() var id = form.getId() Logger.log("id on create_form : "+id) return [url, id] }
  • form_Bのトリガーの作成
function create_trigger(id) { Utilities.sleep(1000); ScriptApp.newTrigger("onFormSecondSubmit") .forForm(id) .onFormSubmit() .create() Logger.log("id on create_trigger: "+id) }
  • form_Bのトリガーで起動する関数
function onFormSecondSubmit(e) { Utilities.sleep(2000); const items = {}; Logger.log(JSON.stringify(e)); e.response.getItemResponses().forEach(itemResponse => { ~~~ 以下省略 ~~~

試したこと

トリガー作成時のIDが正しく渡されていること、form_Bの回答情報、sleepの挿入を確認、または試しました。
form_Bの送信トリガーで呼び出されるonFormSecondSubmit(e)の引数eの中身を確認しようともしましたがそもそも応答IDが見つからないと言われているので、関数内の処理は行われていないようでした。
また以下の記事では別々のformが元になる送信トリガーは同じスクリプト内では共存できないと書かれているようで(自信はないです)そもそも実現ができない処理を行おうとしているのか?とも思ってしまっています。
https://stackoverflow.com/questions/65346812/installable-trigger-to-fire-script-in-a-different-form

回答よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

Google Apps Scriptでは、フォーム送信をトリガーとするイベントを
フォームおよびスプレッドシートに設置することができます。

フォームに紐づくトリガーは、(たぶん)そのフォームからの送信時のみ処理可能ですが、
スプレッドシートに紐づけたフォーム送信のトリガーは、
同じスプレッドシートに紐づけられた複数のフォーム送信に対応することが可能です。

公式ドキュメントはこちらをご参照ください:
イベント - Google Apps Script


複数のフォーム送信を一つのトリガーで処理する方法

スプレッドシートに設置したフォーム送信トリガーでは、
送信されたデータが書き込まれるシート名でどのフォームからの送信かを判定できます。

まず、フォームの回答タブからスプレッドシートで表示をクリックし、
フォームに紐づくスプレッドシートを作成します。

以下のように、onFormSubmitToSpreadsheet 関数内でシート名を取得し、
条件分岐を行うことでフォームごとの処理を実装できます。
今回はFormAかそれ以外という判定にしています。

javascript

1function onFormSubmitToSpreadsheet(e) { 2 // どのシートに回答が追加されたかを確認 3 const sheet = e.range.getSheet(); 4 const sheetName = sheet.getName(); 5 6 if (sheetName === 'FormA Responses') { //シート名は適宜修正 7 // FormAからの回答の場合の処理 8 handleFormASubmission(e); 9 } else { 10 // FormA以外(FormB)からの回答の場合の処理 11 handleFormBSubmission(e); 12 } 13}

新しく作成するフォームの回答先を指定する方法

新しく作成するフォーム(例えばFormB)の回答先は、
setDestination 関数を使用して既存のスプレッドシートに設定できます。
これにより、複数のフォームの回答を同じスプレッドシートで管理することができます。

javascript

1function createFormB(jsonObj) { 2 // FormBを作成 3 const form = FormApp.create(`${jsonObj["氏名"]}`); 4 const pullDown = form.addListItem(); 5 6 form.setDescription("顧客情報"); 7 pullDown.setTitle("日にちの確定") 8 .setChoiceValues([ 9 jsonObj["第一希望日"], 10 jsonObj["第二希望日"], 11 jsonObj["第三希望日"] 12 ]) 13 .setRequired(true); 14 15 // フォームのURLとIDを取得 16 const url = form.getPublishedUrl(); 17 const id = form.getId(); 18 19 // フォームの回答先を設定 20 const spreadsheetId = 'YOUR_MASTER_SPREADSHEET_ID'; // 実際のスプレッドシートIDに置き換えてください 21 form.setDestination(FormApp.DestinationType.SPREADSHEET, spreadsheetId); 22 23 return [url, id]; 24}

この方法のメリット

  • トリガーの数を削減:スプレッドシートにトリガーを一つ設置するだけで、複数のフォーム送信イベントを処理できます。これにより、トリガーの上限(ユーザーあたりの最大数)を気にせず運用できます。

  • 管理が容易:フォームごとにトリガーを設置する必要がないため、トリガーの管理が簡単になります。

  • 柔軟な対応:フォームAとフォームBの回答を同じスプレッドシートに保存したくない場合でも、setDestination 関数を使用してフォームB専用のスプレッドシートを指定し、同様の処理を組み込むことが可能です。


注意点

  • スプレッドシートの構成:フォームの回答がスプレッドシートのどのシートに書き込まれるかを把握しておく必要があります。シート名が変わると、条件分岐が正しく機能しなくなる可能性があります。

  • フォームの回答先を分ける場合:フォームAとフォームBの回答を別々のスプレッドシートに保存したい場合は、それぞれのフォームに対応するスプレッドシートに同様のスクリプトとトリガーを設置することで対応可能です。


この方法を用いることで、トリガーの上限を気にすることなく、
複数のフォーム送信イベントを一つのトリガーで効率的に処理することができます。
ご参考になれば幸いです。

投稿2024/11/26 01:28

dadadaiiiiiii

総合スコア56

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.34%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問