どうも。つじけ(tsujikenzo)です。このシリーズでは 「Googleフォームとイベントオブジェクトを極めよう」 について全6回でお送りします。今日は1回目です。
はじめに
「Googleフォーム(以後、フォーム)」 はGoogle Workspace Serviceで提供されている、フォームを取り扱うサービスです。みなさんも、満足度アンケートの回答や、WEBサービスの申し込みに使用したことがあると思います。
フォームが幅広く利用されている理由は、 「URLをシェアするだけで、全世界のユーザーから回答を得られる」 からではないでしょうか。
URLはメールで送信したり、QRコードにして配布するなど、インターネットに常時接続された現代に、とてもマッチしていると思います。
「フォームのテンプレートギャラリー」 では、数多くのテンプレートが用意されています。フォームが 「アンケート」 や 「サービス申し込み」 などに適したサービスであることがわかります。
テンプレートの中から 「パーティ招待状」 をクリックしてみましょう。
内容は適当で構いませんが、1つ回答を送信してみましょう。アンケートに答えるユーザーにとって、わずか数クリックで、回答を送信できます。
進化するフォームの活用方法
そんな便利なフォームですが、いまや 「アンケート」 や 「サービス申し込み」 にとどまらず、 オンラインテスト 、学習用アプリ 、勤怠管理などのUIとして 、などさまざまな場面で活用されています。
中でも、こちらのサイトの 「スプレッドシートからGoogleフォーム英単語テストを自動作成できる」 というツールは有名です。

このような、フォームを発展させたツール(アプリケーションとも呼べると思います)が生みだされている理由のひとつとして、注目したい技術があります。それは 「回答の集計方法」 です。
フォームにおける回答の集計方法
みなさんも、フォームを作成したことがあるなら、一度は 「csvで出力する」 か 「スプレッドシートを連携する」 などで回答の集計をしたことがあると思います。
次回、回答の集計について詳しく解説しますが、この他に、 「イベントオブジェクトを操作する」 という方法があります。
「イベントオブジェクト」 とは、フォームが送信されたときに発行される情報(データ)で、その中には 「送信時間、送信者、回答内容」 など、さまざまな情報が含まれています。
普段は触れることのない「イベントオブジェクト」ですが、GASを書いたことがある人なら、誰でも簡単に扱うことができます。ということで、このシリーズでは 「フォームのイベントオブジェクト」 を理解して、実務で使えるツール(アプリ)を作成することを目標にします。
まとめ
以上で、Googleフォームのかんたんなご紹介と、このシリーズの目標をお届けしました。
「フォームを極める」というテーマですと、多岐に渡る学習が必要になりますが、 私は 「イベントオブジェクトを極めること」 がフォーム活用の近道だと考えております。
フォームを実務で使える場面はさまざまです。スプレッドシートに直接入力していた作業や、パソコンを開かないとできなかった業務が、スマホで完結できたりします。高度なプログラミング知識は必要ありません。あくまで、ノーコード・ローコードでお伝えしたいと思います。
次回は、 「フォームの回答を集計しよう」 をお届けしします。
このシリーズの目次
- [GAS]Googleフォームとイベントオブジェクトを極めよう はじめに
- [GAS]フォームの回答を集計しよう
- [GAS]トリガーとイベントオブジェクト
- [GAS]スプレッドシートのコンテナバインドのフォーム送信時トリガー
- [GAS]フォームのコンテナバインドのフォーム送信時トリガー
- [GAS]トリガー作成アカウントと実行アカウントの違いについて
どうも。つじけ(tsujikenzo)です。このシリーズでは 「Googleフォームとイベントオブジェクトを極めよう」 について全6回でお送りします。今日は2回目です。
前回のおさらい
前回は、Googleフォームのかんたんなご紹介と、このシリーズの目標をお届けしました。

今回は、 「フォームの回答を集計しよう」 をお届けしします。
アジェンダ
1. ブラウザを印刷する
2. csvを出力する
3. スプレッドシートへ出力する
4. GASを実行する
ブラウザを印刷する
フォームには、回答を確認する [回答] タブが用意されていて、ブラウザによる回答の確認方法が 3通り あります。
1.集計ページを印刷する
[回答] タブをクリックすると、 テキストやグラフで集計を表示してくれます。
質問の種類によって、円グラフや棒グラフなど、目でみやすい集計が用意されています。
この画面は、印刷(PDF化)できます。 [回答] タブをクリックして、右上の [縦3点メニュー] から、 [印刷] をクリックします。
新しいタブが表示されます。
ブラウザの任意の場所を右クリックして [印刷] をクリックします。ショートカットキー[Ctrl + p]でも可能です。
印刷設定画面が表示されますので、PDFとして保存できます。 紙での印刷 は業務効率を著しく下げる行為です。受け取る側にとっても不便です。なるべくPDFにしてメールで配布しましょう。
2.回答を個別に印刷する
さきほどは、 「回答の集計」 をPDF化しましたが、 「個別の回答」 もすべて印刷できます。 [回答タブ] の [縦3点メニュー] をクリックします。
[すべての回答を印刷] をクリックします。
印刷画面が表示されます。回答ごとに改ページされていますので、見やすいですね。
3.1 回答の集計URLを公開する
さきほどPDF化した回答の集計は、 ある固定された時点の集計 をお知らせするものでした。アンケートのように回答が増え続ける場合は、回答者自信で、 「最新の回答の集計」 を確認できたほうが効率いいですね。
そのために、 「回答の集計のURLを公開する」 という方法があります。[回答] タブをクリックして、右上の [縦3点メニュー] から、 [印刷] をクリックします。
新しいタブが表示されたら、 「分析を公開」 をクリックします。
さらに新しいタブが表示されて 「分析を公開しますか?」 というメッセージが表示されます。 [OK] をクリックします。
設定は以上です。新たに、フォームの回答を送信してみましょう。
送信完了画面に [前の回答を表示] リンクが表示されますので、クリックします。
[回答の集計] が表示されますので、管理者がPDFを送付しなくても、回答者自身で集計を確認できます。
3.2 回答の集計URLを公開する
同様の設定は、 [設定] メニューからも行えます。フォーム編集画面の右上にある [歯車アイコン] をクリックします。
[全般] タブから、回答者が行える操作:の [概要グラフとテキストの回答を表示] にチェックを入れて、最後に、 [保存] クリックします。
見た目はなにも変わりませんが、 [歯車アイコン] もう一度をクリックすると、[概要グラフとテキストの回答を表示] にチェックが入っていることが確認できます。確認できたら [キャンセル] をクリックしてウィンドウを閉じます。
どちらの設定方法でも変わりませんので、覚えやすい方法でかまいません。
csvを出力する
回答の集計は、csvファイルで出力できます。 [回答タブ] から [縦3点メニュー] をクリックします。
[回答をダウンロード(.csv)] をクリックします。
お使いのパソコンによって保存場所は違いますが、zipファイルがダウンロードされます。
zipファイルの中にcsvファイルが格納されていますので、Googleドライブの [マイドライブ] などに移動します。
csvファイルをダブルクリックすると、中身を確認できます。※Excelでcsvを開くと文字化けすることがあります。
csvの活用方法や、GASによる自動エクスポートは、このシリーズでは取り上げません。しかしながら、csvファイルがあると、社内基幹システムへのデータの橋渡しなどに便利です。
ここでは 「フォームの回答はcsvでエクスポートできる」 ということだけ覚えておきましょう。
スプレッドシートに出力する
回答の集計は、任意のスプレッドシートに出力できます。基本的な使い方は、 1つのフォームに対して、1つのスプレッドシート(回答)を用意する ことです。
[回答タブ] の [スプレッドシートアイコン] をクリックします。
回答先(スプレッドシートのことです)の選択画面が表示されます。 [新しいスプレッドシートを作成「スプレッドシート名」] にチェックが入っていることを確認して、最後に [作成] をクリックします。※ここでスプレッドシート名を変更できますが、変更する必要はさほどないと思われます。
まもなく、新しいタブで新規スプレッドシートが開きます。スプレッドシートには、過去に送信した回答が入力されています。
このスプレッドシートは、フォームが保存されているフォルダーと、同じ場所に保存されています。
スプレッドシートの連携解除
スプレッドシートが削除されたり、ゴミ箱を空にされると、ファイルが削除されたことのエラーが表示されます。
しかしながら、スプレッドシートを連携してしているデータは残っていますので、スプレッドシートの連携解除する際は、必ず [フォームのリンクを解除] をクリックする必要があります。
[フォームのリンクを解除] ウィンドウが表示されたら [リンクを解除] をクリックします。こちらに明記されているように、連携を解除しても、既存のデータ(回答)は削除されませんのでご安心ください。※引き続き集計用のスプレッドシートを使用しますので、[キャンセル] をクリックしてウィンドウを閉じます。
GASを実行する(イベントオブジェクトの登場)
最後に、 「GASを使った回答の集計」 をお伝えします。スプレッドシートのリンクを解除してしまった方は、再度、スプレッドシートの連携を行ってください。
まず、スプレッドシートを開きます。
[ツール] メニューから [スクリプトエディタ] をクリックします。
スクリプトエディタが立ち上がらないなど、起動時のエラーが起きる場合は、こちらの記事を参考にしてください。

左上の「プロジェクト名」をクリックすると、プロジェクト名を変更できます。今回はわかりやすくスプレッドシートと同じ名前にしました。最後に [名前を変更] をクリックします。
イベントオブジェクトの取得
GASには [イベントオブジェクト] と呼ばれる、[なにかアクションが起きたときに、アクションに含まれる情報を集めたデータ] が存在します。
「フォームが送信される」というアクションが起きたときに、とくに得たい情報の1つが、 [回答] です。イベントオブジェクトに含まれる[回答]を操作することで、幅広い業務効率化に活用できます。
イベントオブジェクトは、関数に引数(e)として渡されます。関数内で、eを加工することで、さまざまな処理を行います。
function myFunction(e) {
//ここでeを使って、処理を行う
}
ユーザーから送信された [回答] は [e.values] で取得できます。
e.values
このようなコードを書いてみましょう。
function myFunction(e) {
console.log(e.values);
}
スクリプトエディターは、上書き保存を忘れないようにしましょう。
トリガーを設置する
フォームが送信されたら、 myFunction(e) が実行されるように、トリガーを設置します。
スクリプトエディターの左メニューから、 [トリガー] をクリックします。
トリガー画面に切り替わったら、右下の [トリガーを追加] をクリックします。
トリガー設定ウィンドウが開いたら、下記のように設定をして、 最後に [保存] をクリックします。※初回実行時には認証画面が出ると思いますが、適宜認証してください。認証方法は割愛します。
1. 実行する関数を選択・・・myFunctiton
2. イベントのソースを選択・スプレッドシートから
3. イベントの種類を選択・・フォーム送信時
このように、トリガーが1件登録されたら完了です。
トリガーの発火
フォームを送信して、トリガーを発火させましょう。「パーティー招待状」のフォームから回答を送信します。
回答が送信されました。
スクリプトエディターに戻り、左メニューから [実行数] をクリックします。
実行数一覧の一番上に表示されているのが、 [フォーム送信時トリガー] から発火された、ログ(記録)です。クリックすると中身を確認できます。
1次元配列で、[回答] を取得できています。ユーザーはフォームから入力していませんが、回答の先頭には、送信した時刻の [タイムスタンプ] を取得しているのも特徴的です。
この1次元配列を加工することで、「メールを送信する」、「別のフォームを送信する」 など、さまざまな処理を行うことができます。
まとめ
以上で、 「フォームの回答を集計しよう」 をお届けしました。管理者だけでなく、回答を送信したユーザーがどのような形で集計にアクセスできたらよいか、さまざまな選択肢が用意されているので、とても便利ですね。
また、後半では、「スプレッドシート連携のおさらい」 と、 「フォーム送信時をトリガーとしたGASの実行」 をご紹介しました。今後はその中で登場した 「イベントオブジェクト」 について、もう少し深掘りしていきたいと思います。
次回は、「トリガーとイベントオブジェクト」 をお届けします。
このシリーズの目次
- [GAS]Googleフォームとイベントオブジェクトを極めよう はじめに
- [GAS]フォームの回答を集計しよう
- [GAS]トリガーとイベントオブジェクト
- [GAS]スプレッドシートのコンテナバインドのフォーム送信時トリガー
- [GAS]フォームのコンテナバインドのフォーム送信時トリガー
- [GAS]トリガー作成アカウントと実行アカウントの違いについて
どうも。つじけ(tsujikenzo)です。このシリーズでは 「Googleフォームとイベントオブジェクトを極めよう」 について全6回でお送りします。今日は3回目です。
前回のおさらい
前回は、 「フォームの回答を集計しよう」 をお届けしました。集計ページの印刷やURLの公開、csv出力をご紹介しましたね。
さらに、「スプレッドシート連携」 と、 「フォーム送信時をトリガーとしたGASの実行」 ということで 「イベントオブジェクト」 も登場しました。

今回は、「トリガーとイベントオブジェクト」 をお届けします。
アジェンダ
1. JavaScriptにおけるイベントハンドラー
2. シンプルトリガー
3. インストーラブルトリガー
4. イベントオブジェクト
JavaScriptにおけるイベントハンドラー
「JavaScript」 とは、ブラウザで読み込みする、 「WEBの動作」 について記述されたソース言語(ファイル)のことです。
「WEBの動作」 とは、「ポップアップウィンドウを開く」 や 「ユーザーがクリックしたらブラウザ内の背景色を変える」 などの、WEBの表示に 動き を加えたものです。
WEBの動作は 「イベント」 とも呼ばれており、ブラウザ内で起こるさまざまな動作や出来事が 「イベントリファレンス」 として定義されています。
インターネットが登場して間もない頃は、「クリックする」「ウィンドウサイズを変更する」などの単純な動作しか操作できませんでしたが、ブラウザ上で 「ドラッグアンドドロップする」 が登場したときの驚きは今でも忘れられません。
さらに、ブラウザは日々進化しています。 [動画] に関するイベントや、 [WebVRイベント] と呼ばれる、VRディスプレイに対応したイベントなどが次々に開発されています。

この、 「イベント」 が発生したときに、呼び出される処理を 「イベントハンドラー」 と呼びます。JavaScriptでは、 「クリックする」 や 「ページが読み込まれる」 といった動作を 「イベント」 と呼び、イベントが発生したときに呼び出される 「onclick」 や 「onopen」 を 「イベントハンドラー」 と呼んでいますのでご注意ください。
通常は、 「onclick」 にユーザーが定義した関数などの処理が書かれていますので、onclick & 実行される関数 のことを 「イベントハンドラー」 と呼ぶことがありますが、間違いではありません。
GASにおけるイベントハンドラー
GASでは、 「イベントハンドラー」 のことを 「トリガー」 と呼んでいます。JavaScriptと同じように、 「onOpen」 や 「onEdit」 など、イベントよって動作するトリガー(※1)が用意されています。
※1 イベントによってトリガーが動作することを 「発火」 と呼びます。英語の trigger fire を直訳したものです。
トリガーは 「シンプルトリガー」 と 「インストーラブルトリガー」 の2種類が用意されています。種類によって発火する条件や、設置する条件が異なりますので、1つずつ見ていきましょう。
シンプルトリガー
公式リファレンスはこちらです。

メリット
- 使用する時は、アクティブ化する必要がない(ユーザーに承認を求めることなく自動的に起動する)
- GASの実行で発火することがない(Range.setValue()を実行しても、onEditトリガーは実行されない)
デメリット
- Googleスプレッドシート、スライド、ドキュメント、またはフォームのコンテナバインドに設置する必要がある
- ファイルが「読み取り専用」で開かれている場合は実行されない
- トリガー名を自由に設定できない
- 承認が必要なサービス(Gmail送信など)を呼び出すことができない
- バインドされているファイルは変更できるが、承認が必要な他のファイルにアクセスできない
- getActiveUser()が使える場合と使えない場合がある
- 30秒を超えて実行できない
※これらの制限は、 doGet(e) または doPost(e) には適用されません。
6種類のシンプルトリガー
シンプルトリガーの種類は多くありません。トリガー名も決まっているため、すべて覚えてしまってもかまいません。
下記は、トリガー名と発火条件になるイベント名の一覧です。それぞれ、スプレッドシートやフォームのコンテナバインドスクリプトに設置されることをイメージしてください。
トリガー名: イベント名
onOpen(e): 起動時
onEdit(e): 編集時
onSelectionChange(e): 選択変更時
onInstall(e): インストール時
doGet(e): GETリクエスト
doPost(e): POSTリクエスト
※(e)はイベントオブジェクト
インストーラブルトリガー
続いて、インストーラブルトリガーです。公式リファレンスはこちらです。

メリット
- 時間トリガーを設定できる
- GASの実行で発火することがない(FormResponse.submit() を実行しても、フォーム送信時トリガーは実行されない)
- 承認が必要なサービスを呼び出すことができる
- トリガー名を自由に設定できる
- onOpen()を設置したユーザーの承認を得たアカウントのみ実行させることができる
- GASで「削除、変更、追加」などの管理ができる
デメリット
- 使用する時は、アクティブ化する必要がある
- ファイルが「読み取り専用」で開かれている場合は実行されない
- 発火させたアカウントではなく、トリガーを作成したアカウントで実行される ※2
※2 について対応策は、後ほど紹介します。
インストーラブルトリガーのイベントソースとイベント
インストーラブルトリガーも、基本的な処理はシンプルトリガーと変わりません。しかし、シンプルトリガーと比べて 発火条件 が数多く用意されています。
また、発火するイベントの元になるコンテナバインドのサービス(スプレッドシートやフォームなど)や時間主導型のことを [イベントソース] と呼びます。
つまり、トリガーが発火する条件は、以下によって決められます。
・コンテナバインドかスタンドアロンスクリプトか
・どのイベントソースか
・どのイベントか
//コンテナバインドスクリプトで設定できるイベントソース5種類
- スプレッドシート
- ドキュメント
- フォーム
- カレンダーイベント
- 時間主導型
//[スライド]のコンテナバインド、もしくはスタンドアロンスクリプトにした場合のイベントソース2種類
- カレンダーイベント
- 時間主導型
//イベントソースを[スプレッドシートから]にした場合のイベント4種類
- 起動時
- 編集時
- 値の変更時
- フォーム送信時
//イベントソースを[ドキュメントから]にした場合のイベント1種類
- 起動時
//イベントソースを[フォームから]にした場合のイベント2種類
- 起動時
- フォーム送信時
//イベントソースを[時間主導型]にした場合のトリガータイプ5種類
- 特定の日時
- 分ベースのタイマー
- 時間ベースのタイマー
- 日付ベースのタイマー
- 週ベースのタイマー
- 月ベースのタイマー
//イベントソースを[カレンダーから]にした場合の設定
- カレンダー更新済み
- [カレンダーのオーナーのメールアドレスを入力]
インストーラブルトリガーのトリガー名は自由に設定できます。しかしながら、インストーラブルトリガーにもかかわらずトリガー名を onOpen() とするのは、あとでコードを読む人に不親切かもしれません。 onUserOpen() など、シンプルトリガーとは違うことを明示したほうがよいでしょう。
イベントオブジェクト
「シンプルトリガー」 と 「インストーラブルトリガー」 のどちらにも共通していることは、イベントが発生したときの情報を、 イベントオブジェクト(e) としてトリガーに渡すことです。
イベントオブジェクトはその名の通り、 オブジェクト です。下記のような {key:value}形式 で情報が格納されています。
//ドキュメントのonOpen()トリガーで返されるイベントオブジェクト例
e = {
authMode:enum property,
source: { Spreadsheet object },
triggerUid: '123456789',
user: { user object '[email protected]'}
}
//スプレッドシートのフォーム送信時トリガーで返されるイベントオブジェクト例
e = {
authMode:enum property,
namedValues: {
'名前': ['つじけ'],
'Timestamp': ['6/7/2021 20:54:13'],
'参加されますか?': ['はい、参加します']
},
range: { range object },
triggerUid: '123456789',
values: ['2021/05/04 15:00', '[email protected]', 'つじけ', 'はい、参加します']
}
オブジェクトの値へのアクセス方法
イベントオブジェクトに 数値型や文字列 が格納されているプロパティは、ドット記法で直接呼び出すことができます。
console.log(e.triggerUid); //'123456789'
console.log(e.values); //['2021/05/04 15:00', '[email protected]', 'つじけ', 'はい、参加します']
一方で、イベントオブジェクトのなかには、 オブジェクト が格納されているプロパティもあります。
//オブジェクトが格納されているプロパティ例
//スプレッドシートから編集時トリガーで返される、rangeプロパティ
e = {range:{range object}}; //Range objectが格納されている
//フォームからフォーム送信時トリガーで返される、responseプロパティ
e = {response:{FormResponse object}}; //FormResponse objectが格納されている
オブジェクトが格納されているプロパティは、 各オブジェクトに用意されてるメソッド を使用して、アクセスします。
console.log(e.range.getA1Notation()); //'A1'
console.log(e.response.getRespondentEmail()); //'[email protected]'
メソッドはオブジェクトの公式リファレンスを確認しながら、必要な値を操作します。GASの公式リファレンスは充実していますので、戻り値やメソッドなどを、都度確認するようにしましょう。
まとめ
以上で、 「トリガーとイベントオブジェクト」 をお届しました。 シンプルトリガー と インストーラブルトリガー の違いを見比べながら、最後は イベントオブジェクト について紹介しました。
イベントオブジェクトにはさまざまな情報が含まれております。GASのトリガーの種類が多いということは、イベントオブジェクトの種類も豊富です。すべてを覚える必要はありませんので、必要に応じて公式リファレンスを確認しましょう。

次回は、「スプレッドシートのコンテナバインドのフォーム送信時トリガー」 をお届けします。
このシリーズの目次
- [GAS]Googleフォームとイベントオブジェクトを極めよう はじめに
- [GAS]フォームの回答を集計しよう
- [GAS]トリガーとイベントオブジェクト
- [GAS]スプレッドシートのコンテナバインドのフォーム送信時トリガー
- [GAS]フォームのコンテナバインドのフォーム送信時トリガー
- [GAS]トリガー作成アカウントと実行アカウントの違いについて
どうも。つじけ(tsujikenzo)です。このシリーズでは 「Googleフォームとイベントオブジェクトを極めよう」 について全6回でお送りします。今日は4回目です。
前回のおさらい
前回は、 「トリガーとイベントオブジェクト」 をお届けしました。 GASにおけるイベントハンドラーである、 シンプルトリガー と インストーラブルトリガー を見比べながら、最後は イベントオブジェクト を紹介しました。

今回は、 「スプレッドシートのコンテナバインドのフォーム送信時トリガー」 をお届けしします。
アジェンダ
1. スプレッドシートのコンテナバインドのフォーム送信時イベントオブジェクト
2. 多彩なスプレッドシート連携
3. フォーム送信時にメールを送信する(1対1)
4. フォーム送信時にメールを送信する(多対1)
5. トリガーの発火に条件を加える
スプレッドシートのコンテナバインドのフォーム送信時イベントオブジェクト
公式リファレンスによると、スプレッドシートのコンテナバインドのフォーム送信時に渡されるイベントオブジェクトには、下記の 5つのプロパティ が格納されています。

このイベントオブジェクトに格納されているプロパティを操作することで、さまざま業務効率化ツールを作成することができます。
ツールは主にGASで書きますが、まずは 多彩なスプレッドシート連携 をご紹介します。
多彩なスプレッドシート連携
第2回目のおさらいですが、フォームには、回答の集計として 新しいスプレッドシートを作成して連携 できました。
まだ、連携できていない方は、こちらの記事を参考に、フォームに 新しいスプレッドシート を連携してください。

このように、スプレッドシートに 「[フォームアイコン]フォームの回答1」 というシートが追加されていれば完了です。
既存のスプレッドシートに、フォームの集計シートを連携する
フォームは 「新しいスプレッドシートを作成」 して連携する以外にも、 「既存のスプレッドシート」 を連携することもできます。
今回は、このようなスプレッドシートを用意しました。
「パーティー招待状」 の回答を、このスプレッドシートに連携したいと思います。
フォームの編集画面から [回答] タブをクリックして、 [スプレッドシート] アイコンをクリックします。
[既存のスプレッドシートを選択] にチェックをいれて、 [選択] をクリックします。
Googleドライブが表示されますので、スプレッドシートを選択して [選択] をクリックします。
自動的にスプレッドシートが開きます。既存のスプレッドシートに 「フォームの回答1」 というシートが作成されています。
これでフォームと、既存のスプレッドシートが連携されました。
複数のフォームの集計を1つのスプレッドシートに連携する
既存のスプレッドシートに連携できるのは、1つのフォームだけではありません。 複数のフォームとスプレッドシートを連携 してみましょう。
今回は、テンプレートから 「Tシャツ申込書」 というフォームを新規作成しました。1つ回答を送信しておきましょう。
このフォームを、先ほどのスプレッドシートに連携します。
連携の手順はおなじです。フォームの編集画面から、 [回答] タブをクリックして、 [スプレッドシート] のアイコンをクリックします。
スプレッドシートを選択して [選択] をクリックします。
スプレッドシートが自動で開きます。 スプレッドシートには [フォームの回答2] というシートが追加されています。もちろん、前回連携した [フォームの回答1] シートもあります。
それぞれのフォームから回答を送信すると、それぞれのシートに反映されることを確認しましょう。
このように、集計の回答は 1(フォーム)対1(スプレッドシート) だけでなく、 多(フォーム)対1(スプレッドシート) の連携ができます。
多方面から送信される、 質問名が違う回答 を集計したい場合などに便利です。
フォーム送信時にメールを送信する(1対1)
フォームにはあらかじめ、 「回答のコピーをメールで送信する」 という機能があります。
しかしながら、メール本文にオリジナルメッセージを追加したい、CCを追加したいなど、メールをカスタマイズしたい場面も出てくると思います。
今回は、「フォームの回答が送信されたら、Gmailの下書きを作成する」 GASを書いてみましょう。まずは、 1(フォーム)対1(スプレッドシート) の連携をしている場合です。
スプレッドシートのコンテナバインドスクリプトを開き、GASを書きます。今回は、 「Tシャツ申込書フォーム」 が送信されたときを想定しています。
function onFormSubmit(e){
const [timeStamp, name, size, comment] = e.values;
const recipient = '[email protected]';
const subject = 'フォームから回答です';
const body = `${name}さんから${size}の注文がありました。コメント:「${comment}」`;
GmailApp.createDraft(recipient, subject, body);
}
トリガーの設定
スクリプトエディターの左メニューから [トリガー] をクリックします。
トリガー設定画面が表示されたら、右下の [トリガーを追加] をクリックします。
トリガーの設定は以下の通りです。
1. 実行する関数を選択・・・onFormSubmit
2. イベントのソースを選択・・スプレッドシートから
3. イベントの種類を選択・・・フォーム送信時
最後に [保存] をクリックします。
トリガーが設定されました。
[Tシャツ申込書] フォームから、新たにダミー回答を送信してみましょう。
Gmailを開くと、 [下書き] に1件のメールが作成されています。
1(フォーム)対1(スプレッドシート) の連携は、比較的簡単に操作できます。問題は 多(フォーム)対1(スプレッドシート) の連携です。
フォーム送信時にメールを送信する(多対1)
お気付きの方もいらっしゃるかもしれませんが、それぞれのフォームに対応した 「スプレッドシートからフォーム送信時」 トリガーを設置した場合、どれか1つのフォームを送信すると すべてのトリガーが発火してしまいます。
「パーティー招待状が送信されたらメールの下書きをする関数」は、このようになっています。
function onPartyInvitationFormSubmit(e) {
const [timeStamp, name, ans, quantity, carry, allergies, mail] = e.values;
const recipient = '[email protected]';
const subject = '招待状の返信がありました';
const body = `${name}さんは${quantity}名で出欠は「${ans}」です。
${allergies}を持参しますが、${allergies}アレルギーだそうです。`;
GmailApp.createDraft(recipient, subject, body);
}
ダミー回答を送信してみましょう。
Gmailの下書きを開くと、 2件 のメールが作成されています。本来は、送信される予定ではないトリガーも発火してしまっているためです。 メール本文 もあべこべになってしまっています。
トリガーに 「特定のフォームが送信されたら発火する」 という条件を加えることはできないのでしょうか。
トリガーの発火に条件を加える
これまで作成したトリガーは、削除しておきます。
前回作成した、onFormSubmit(e)関数の、関数名を onTshirtsFormSubmit() に変更します。
function onTshirtsFormSubmit(e){
const [timeStamp, name, size, comment] = e.values;
const recipient = '[email protected]';
const subject = 'フォームから回答です';
const body = `${name}さんから${size}の注文がありました。コメント:「${comment}」`;
GmailApp.createDraft(recipient, subject, body);
}
スクリプトエディターに、 新たにonFormSubmit()関数 を定義します。
function onFormSubmit(e) {
}
onFormSubmit()関数内で、 onPartyInvitationFormSubmit(e) 、 onTshirtsFormSubmit(e) の、2つの関数を呼び出します。
function onFormSubmit(e) {
onPartyInvitationFormSubmit(e);
onTshirtsFormSubmit(e);
}
このままでは、2つの関数を同時に実行してしまいます。そこで、 イベントオブジェクトに含まれる送信元フォームの情報 を頼りに、 「どちらの関数を実行すればよいのか」 を判定します。
送信元フォームを判定するイベントオブジェクト
スプレッドシートのコンテナバインドスクリプトのフォーム送信時トリガーで発火するイベントオブジェクト内に、 「namedValues」 プロパティがありました。
プロパティへのアクセス方法は、ドット記法です。
e.namedValues
[namedValues] プロパティには、質問と回答がオブジェクト {key:value}方式 で格納されています。
他のフォームに含まれていない、 「ユニークな質問」 を選択することで、 「回答がどのフォームから送信されたか」 を判定できます。※ 「複数のフォーム間で、ユニークな質問がない」 、という状況はあまりないと思われます。なぜなら、 質問が重複していないのであれば、同一のフォームで運用するはず だからです。
hasOwnProperty()メソッドと条件分岐
オブジェクトの中に、プロパティが含まれているか判定するのは、 [.hasOwnProperty()メソッド] です。
hasOwnProperty()メソッドは、引数に 「質問の文字列」 を指定すると、 true か false を返します。
console.log(e.namedValues.hasOwnProperty('参加人数をご記入ください。')); //Boolean
onFormSubmit()にはこのように記述することで、フォーム送信時に、それぞれの関数が実行されます。
function onFormSubmit(e) {
switch (true) {
case e.namedValues.hasOwnProperty('参加人数をご記入ください。'):
onPartyInvitationFormSubmit(e);
break;
case e.namedValues.hasOwnProperty('T シャツのサイズ'):
onTshirtsFormSubmit(e);
break;
}
}
「パーティー招待状」から、ダミー回答を送信してみましょう。
Gmailの下書きに、フォームに対応した下書きが、1件だけ作成されています。
まとめ
以上で、 「スプレッドシートのコンテナバインドのフォーム送信時トリガー」 ということで、 イベントオブジェクト の確認と 多彩なスプレッドシート連携 についてお届けしました。後半は、 フォーム送信時のトリガーの発火 について考察し、 トリガーの条件分岐方法 をご紹介しました。
なお、今回はGmailの下書きを作成しましたが、 「同一シート内に転記(集計)する」 という処理も可能です。ツールのカスタマイズ性が高まると、業務効率化も一気に進みます。引き続き 「実務で使えるツール作り」 を意識しましょう。
次回は、「フォームのコンテナバインドのフォーム送信時トリガー」 をお届けします。
このシリーズの目次
- [GAS]Googleフォームとイベントオブジェクトを極めよう はじめに
- [GAS]フォームの回答を集計しよう
- [GAS]トリガーとイベントオブジェクト
- [GAS]スプレッドシートのコンテナバインドのフォーム送信時トリガー
- [GAS]フォームのコンテナバインドのフォーム送信時トリガー
- [GAS]トリガー作成アカウントと実行アカウントの違いについて
どうも。つじけ(tsujikenzo)です。このシリーズでは 「Googleフォームとイベントオブジェクトを極めよう」 について全6回でお送りします。今日は5回目です。
前回のおさらい
前回は、 「スプレッドシートのコンテナバインドのフォーム送信時トリガー」 ということで、 主に 「多(フォーム)対1(シート)の回答集計とGAS」 についてお届けしました。

今回は、 「フォームのコンテナバインドのフォーム送信時トリガー」 をお届けしします。
アジェンダ
1. フォームのコンテナバインドのフォーム送信時イベントオブジェクト
2. スプレッドシートの名前付き範囲
3. 名前付き範囲に、フォームから入力する(1対1)
4. フォーム送信時にスプレッドシートへ入力する(1対多)
フォームのコンテナバインドのフォーム送信時イベントオブジェクト
公式リファレンスによると、フォームのコンテナバインドのフォーム送信時に渡されるイベントオブジェクトには、下記の 4つのプロパティ が格納されています。

このイベントオブジェクトに格納されているプロパティを操作することで、フォームの [回答] を自由自在に操ることができます。
自由自在に操る例として、 「フォームから納品書スプレッドシートへの入力ツール」 を作成しますが、まず スプレッドシートの名前付き範囲 をご紹介します。
スプレッドシートの名前付き範囲
スプレッドシートの単体セル、および複数セル範囲には、 「名前」 を付けることができます。 名前付き範囲 については、過去にブログを書きましたので、こちらの記事を参考にしてください。

今回は、このようなスプレッドシートを用意しました。シート [じゃがいも] には、セル[E3]に [送信日] 、セル[B11]に [じゃがいも数量] という、2つの 名前付き範囲 が設定されています。
この2つの名前付き範囲の値を、 フォームから更新 しましょう。
名前付き範囲に、フォームから値を入力する(1対1)
新規フォームを作成します。タイトルはなんでも構いませんが、今回は 「納品書入力用フォーム」 としました。
2つの質問を設置します。
1問目の質問は 「送信日を入力してください」 とし、 [日付] 、 [必須] を設定しました。
2問目の質問は 「じゃがいも数量を入力してください」 とし、[記述式] 、 [数値] 、 [必須] を設定しました。
なお、数値を入力してもらうために、 「次より大きい」 に 0 を、 「カスタムのエラーテキスト」 に 「0より大きい数値を入力してください」 を入力しています。
この設定(バリデーションチェックと呼ばれます)は、 [縦3点メニュー] をクリックして、 [回答の検証] をONにすると可能になります。
テスト回答を1件送信してみましょう。
フォーム編集画面に戻ると、 [回答] タブには1件の回答が表示されています。
フォームの作成は以上です。続いてGASを書きます。
フォームのコンテナバインドスクリプトとイベントオブジェクト
このフォームの、 コンテナバインドスクリプト にGASを書きます。右上の [縦3点メニュー] から、 <>スクリプトエディタ をクリックします。
[タイトル] は、フォームと同じがわかりやすいでしょう。
フォームのコンテナバインドのフォーム送信時に渡されるイベントオブジェクトに、 [response] プロパティがありました。中には [FormResponseオブジェクト] が格納されています。
response プロパティを呼び出すと、 FormResponseオブジェクト を取得することができるということです。
console.log(e.response); //{} FormResponseオブジェクト
FormResponseオブジェクトとは
フォームの [回答] は、 FormResponseオブジェクト と呼ばれる、回答に関するあらゆるデータを集めたかたまりになっています。

先ほど、テスト回答を送信した際、[回答] タブには1件の回答が表示されていましたが、サーバーには [FormResponseオブジェクト] が生成されていることになります。
フォームのコンテナバインドスクリプトでは、送信後の回答を いつでも、 [FormResponseオブジェクト] として取得できます。
function getItemResponsesText() {
const form = FormApp.getActiveForm();
const responses = form.getResponses(); //[{},{},{}] 複数または単体のFormResponseオブジェクト
}
[Class FormResponse] には、[getItemResponses()メソッド] が用意されています。これは、フォームの回答である FormResponseオブジェクト から、すべての ItemResponseオブジェクト を順番どおりに配列で取得します。

FormResponseオブジェクト.getItemResponses()
さらに、[Class ItemResponse] には、[getResponse()メソッド] が用意されており、ItemResponseオブジェクト から回答の中身(文字列として)を返すことができます。※公式リファレンスにもありますが、正式には戻り値はオブジェクトですが、多くの場合は文字列を返すようです。

ItemResponseオブジェクト.getResponse()
一連の流れをコード化したものがこちらです。
function getItemResponsesText() {
const form = FormApp.getActiveForm();
const responses = form.getResponses(); //[{},{},{}] 複数または単体のFormResponseオブジェクト
const itemResponses = responses[0].getItemResponses();
const itemResponsesText = itemResponses.map(itemResponse => itemResponse.getResponse());
console.log(itemResponsesText);//[ '2021-04-26', '10' ]
}
同様に、 フォームの送信時 でも [FormResponseオブジェクト] を取得できます。
前項で紹介したコードがまさに、 フォームの送信時にFormResponseオブジェクトを取得するコード です。
function onFormSubmit(e) {
const formResponseObject = e.response; //{} FormResponseオブジェクト
}
繰り返しになりますが、FormResponseオブジェクトは、 getItemResponses()メソッド や、 getResponse()メソッド により、 [回答] をテキストに変換できます。
一連の流れをコード化したものがこちらです。
function onFormSubmit(e) {
const formResponseObject = e.response; //{} FormResponseオブジェクト
const itemResponses = formResponseObject.getItemResponses();
const itemResponsesText = itemResponses.map(itemResponse => itemResponse.getResponse());
console.log(itemResponsesText);
}
トリガーの設置
トリガーを設置して確認してみましょう。
テスト送信をします。
スクリプトエディタの [実行数] を開きます。
[回答] がログ出力されています。
納品書スプレッドシートに値を入力する
さきほどのコードに加筆し、 回答 をスプレッドシートに入力するコードを書きます。
function onFormSubmit(e) {
const formResponseObject = e.response; //{} FormResponseオブジェクト
const itemResponses = formResponseObject.getItemResponses();
const itemResponsesText = itemResponses.map(itemResponse => itemResponse.getResponse());
console.log(itemResponsesText); //[ '2021-04-27', '55' ]
//スプレッドシートへ出力
const SSID = 'スプレッドシートID';
const ss = SpreadsheetApp.openById(SSID);
ss.getRange('送信日').setValue(itemResponsesText[0]);
ss.getRange('じゃがいも数量').setValue(itemResponsesText[1]);
}
スプレッドシートへ出力できました。
これは、言わばフォームとスプレッドシートが 1(フォーム)対1(スプレッドシート) の関係であると言えます。
このフォームとコンテナバインドスクリプトを発展させると、 1(フォーム)対多(スプレッドシート) のツールとして応用できます。
フォーム送信時にスプレッドシートへ入力する(1対多)
作成するツールの手順は以下のようになります。
– 名前付き範囲に汎用性をもたせる
– フォームの「質問1」に、スプレッドシートIDを用意する
– イベントオブジェクトから回答を取得する
– スプレッドシートIDを取得して掴む
– スプレッドシートにsetValue()する
それでは、1つずつみていきましょう。
名前付き範囲に汎用性をもたせる
[名前付き範囲] の汎用性が高くなるように、[名前] を変更します。たとえば、「送信日」だったものを [値1] とし、「じゃがいも数量」だったものを [値2] に変更します。
名前付き範囲は、スプレッドシート全体を通して、 「ユニークな値」 である必要があります。重複した名前を付けることができません。運用方法としては、 [value1, value2, …value n] のように シート順 、 セルの左上から順 に連番をつけるとわかりやすいかもしれません。
「じゃがいも」とは別の納品書を作成するために、「にんじん納品書」をスプレッドシートのコピーで作成しました。 名前付き範囲 を確認すると、じゃがいも納品書と同じ 名前付き範囲 が設定されています。
にんじん納品書には、「納品先」のセル[E11]に、名前付き範囲 [値3] を追加しました。
フォームの「質問1」に、スプレッドシートIDを用意する
フォームを作成します。前回は「納品書入力用フォーム」でしたが、今回は 「スプレッドシート入力用」 というフォーム名をつけます。
まず、完成系のフォームをご覧ください。
1問目 の質問には、「分かりやすいスプレッドシート名と、スプレッドシートID」 をカンマ区切りで設定しています。
スプレッドシート名, スプレッドシートID
選択方式はなんでも構いませんが、今回は [プルダウンメニュー] にしております。
値1~3はそれぞれ [記述式テキスト(短文回答)] で設定します。今回は3つ用意しましたが、必要な数だけ増やして(値10~など)構いません。
イベントオブジェクトから回答を取得する
コンテナバインドスクリプトを開きます。
フォームと同じプロジェクト名を設定します。
復習ですが、フォームのコンテナバインドスクリプト の、フォーム送信時イベントオブジェクトから回答を取得する方法は、こちらでした。
//イベントオブジェクトから回答を配列に格納する
const itemResponses = e.response.getItemResponses();
const responseArray = itemResponses.map(itemResponse => itemResponse.getResponse());
スプレッドシートIDを取得して掴む
[回答] の先頭には、「スプレッドシート名, スプレッドシートID」 が格納されています。replace()メソッドを使って、 スプレッドシートID を取得できます。
さらに、スプレッドシートIDを使って、スプレッドシートを掴むことができます。
//スプレッドシートIDを取得して掴む
const id = responseArray[0].replace(/.*,/, '');
const ss = SpreadsheetApp.openById(id);
スプレッドシートにsetValue()する
名前付き範囲は、[Class SpreadSheet] のメンバーですので、範囲を取得して、setValues()ができます。
スプレッドシートオブジェクト.getRange(シート名!名前付き範囲).setValue()
回答の配列を、名前付き範囲の 「値 + No」 に、for文で1つずつsetValue()するコードはこのようになります。
//値1~値nを配列に格納する
responseArray.splice(0, 1);
//スプレッドシートに貼り付け
for (const [index, response] of responseArray.entries()) {
ss.getRange(`値${index + 1}`).setValue(response);
}
完成したコードとツール
上記をまとめたコードがこちらです。
/**
* フォームのコンテナバインドスクリプトからスプレッドシートに入力する関数
*
* @param {object} イベントオブジェクト
* @return none
*
*時限トリガー:フォーム送信時
*/
function setValueToSheet(e) {
//イベントオブジェクトから回答を配列に格納する
const itemResponses = e.response.getItemResponses();
const responseArray = itemResponses.map(itemResponse => itemResponse.getResponse());
//スプレッドシートを取得して掴む
const id = responseArray[0].replace(/.*,/, '');
const ss = SpreadsheetApp.openById(id);
//値1~値nを配列に格納する
responseArray.splice(0, 1);
//スプレッドシートに貼り付け
for (const [index, response] of responseArray.entries()) {
ss.getRange(`値${index + 1}`).setValue(response);
}
}
コンテナバインドスクリプトに、 送信時トリガー を設定します。
トリガーが追加されました。
スプレッドシート入力用フォーム から、テスト回答を送信してみましょう。
スプレッドシートが変更されました。
それでは、同じフォームから、別のスプレッドシートに入力をしてみましょう。
「じゃがいも納品書」 には名前付き範囲 [値1] と [値2] を設定していました。
スプレッドシート入力用フォームには、[スプレッドシート名, スプレッドシートID] が必要ですので、フォームの [質問1] に追加します。
テスト回答を送信してみましょう。
「じゃがいも納品書」の [名前付き範囲] を変更できました。
まとめ
以上で、 「フォームのコンテナバインドのフォーム送信時トリガー」 ということで、[フォームのコンテナバインドのフォーム送信時イベントオブジェクト] を確認し、[スプレッドシートの名前付き範囲] を復習しました。
後半は、[名前付き範囲に、フォームから入力する(1対1)] コードを書き、最後は [フォーム送信時にスプレッドシートへ入力する(1対多)] のツールを完成させました。
データを入力するひな形が多い 、増え続けるUI(ユーザーインターフェイス)をまとめたい という方のお役に立てば幸いです。
次回は最終回で、「トリガー作成アカウントと実行アカウントの違いについて」 をお届けします。
このシリーズの目次
- [GAS]Googleフォームとイベントオブジェクトを極めよう はじめに
- [GAS]フォームの回答を集計しよう
- [GAS]トリガーとイベントオブジェクト
- [GAS]スプレッドシートのコンテナバインドのフォーム送信時トリガー
- [GAS]フォームのコンテナバインドのフォーム送信時トリガー
- [GAS]トリガー作成アカウントと実行アカウントの違いについて
どうも。つじけ(tsujikenzo)です。このシリーズでは 「Googleフォームとイベントオブジェクトを極めよう」 について全6回でお送りします。今日は6回目で最終回です。
前回のおさらい
前回は、 「フォームのコンテナバインドのフォーム送信時トリガー」 ということで、 [フォーム送信時にスプレッドシートへ入力する(1対多)] のツールをご紹介しました。

今回は、最終回で、「トリガー作成アカウントと実行アカウントの違いについて」 をお届けします。
問題が起こったきっかけ
ここに 「納品書入力用フォーム」 があり、 コンテナバインドスクリプトのフォーム送信時トリガー が、1つ設定されているとします。
このトリガーを作成したのは、私自身なので、オーナーには 「自分」 が表示されています。
トリガーで発火するFunctionは 「onFormSubmit()」 です。Gmailの下書きを作成するコードを書きます。
function onFormSubmit(e) {
const formResponseObject = e.response; //{} FormResponseオブジェクト
const itemResponses = formResponseObject.getItemResponses();
const itemResponsesText = itemResponses.map(itemResponse => itemResponse.getResponse());
const recipient = '[email protected]';
const subject = '納品書入力用フォームから回答です';
const body = `以下が回答されました。
書類作成日:${itemResponsesText[0]}
じゃがいも数量:${itemResponsesText[1]}`;
GmailApp.createDraft(recipient, subject, body);
}
GmailApp や SpreadsheetApp などの「トップレベルオブジェクト」が含まれるコードをはじめて実行する際は、一度だけ認証が必要です。
スクリプトエディタから、 onFormSubmit() を手動で実行して、認証を済ませておきましょう。※手動で実行しなくても、マニュフェストファイルに認証情報を書くことでも回避できますが、その方法はまた別のブログで紹介します。
「納品書入力用フォーム」 からテスト回答を送信します。
Gmailの [下書き] を開くと、1件の下書きが作成されています。
ここまでは問題ありません。
では、このフォームに 「別のGoogleアカウント」 から回答してみましょう。別のGoogleアカウントでログインし( 他のブラウザを使用する とアカウントの切り替えが楽です。)、フォームを送信します。
そのままGmailを開いて、 [下書き] を確認します。しかし、下書きが作成されていません。
一方で、トリガーを作成したアカウントでログインし(ブラウザを切り替えて)、Gmailの [下書き] を開きましょう。 下書きが1件作成されています。
これは、インストーラブルトリガーを設定したアカウントと、スクリプトを実行したアカウントの違いによるものです。
トリガーアカウントと、スクリプト実行アカウント
onOpen() や onEdit() で設定される、シンプルトリガー は、ファイルを作成したオーナーが誰であろうと、実行アカウントは [自分] になります。
ファイルのオーナー | 実行アカウント |
---|---|
自分 | 自分 |
他アカウント | 自分 |
しかし、 インストーラブルトリガー は、 トリガーを作成したアカウントが、実行アカウント になります。
トリガー設定アカウント | 実行アカウント |
---|---|
自分 | 自分 |
他アカウント | 他アカウント |
この、トリガーを作成したアカウントが、実行アカウント になることの、「回避方法」 をご紹介します。
回避方法
フォーム送信者のメールアドレスを取得する
まず、フォームに、 回答者のメールアドレスを送信させる ように設定します。
もし、ドメインで運用していて、フォーム送信者が ドメイン内のメンバーのみ の場合は、メールアドレスの入力が不要になります。
ひとりでも gmail.comアカウント がいる場合は、メールアドレスを手入力する必要がありますのでご注意ください。
トリガーの作成
次に、「フォームの送信時トリガー」 を、フォームを送信する全員が1つずつ作成します。(全員のファイル権限を 編集者 にする必要があります。トリガーは編集権限を失うと失効してしまうのでご注意ください。)
回答の送信者のメールアドレスは、イベントオブジェクトのFormResponseオブジェクトに、 getRespondentEmail()メソッド をぶつけると取得できます。
e.response.getRespondentEmail()
後ほどGASを書きますが、このように変数に代入しておきましょう。
const formUesr = e.response.getRespondentEmail();
プロパティサービスのユーザープロパティーズ
GASのプロジェクトには、 ユーザープロパティーズ という、GASを実行しているユーザーのみアクセスできるデータの保管場所(プロパティストア)があります。

スクリプトプロパティーズ という、オーナー権限をもつアカウントのみ編集できるデータ保管場所(プロパティストア)のことは、みなさんも聞いたことがあるかもしれません。

ユーザープロパティーズ には、GASを実行するアカウント(自分のメールアドレス)を 文字列 で格納できます。
こちらに、ユーザープロパティーズ にメールアドレスを格納する setUserProperty() 関数を用意しました。フォームを送信する前に、一度だけ実行する必要があります。
/**
* 業務前に、一度自分のアカウントから[メールアドレス]を入力して実行してください
*/
function setUserProperty() {
//自分のメールアドレスを登録してください
const email = '[email protected]';
const userProperties = PropertiesService.getUserProperties();
userProperties.setProperty('USER', email);
}
この、 ユーザープロパティーズに格納されているメールアドレス と、最初に取得した 回答の送信者のメールアドレス が一致していたら、 onFormSubmit()の処理を続行しましょう。 というのが、回避方法のロジックです。
完成したコード
上記を組み合わせて、完成したコードがこちらです。
/**
* フォーム送信時に、フォーム送信アカウントでGmailの下書きを作成する関数
*
* @param {object} イベントオブジェクト
* @return none
*時限トリガー:フォームのフォーム送信時トリガー
*/
function onFormSubmit(e) {
const userProperties = PropertiesService.getUserProperties();
const user = userProperties.getProperty('USER');
const formUesr = e.response.getRespondentEmail();
if (user === formUesr) {
const formResponseObject = e.response; //{} FormResponseオブジェクト
const itemResponses = formResponseObject.getItemResponses();
const itemResponsesText = itemResponses.map(itemResponse => itemResponse.getResponse());
const recipient = '[email protected]';
const subject = '納品書入力用フォームから回答です';
const body = `以下が回答されました。
書類作成日:${itemResponsesText[0]}
じゃがいも数量:${itemResponsesText[1]}`;
GmailApp.createDraft(recipient, subject, body);
}
}
テスト回答を送信してみましょう。※テスト回答を送信する前に、setUserProperty()関数を実行することを忘れないようにしましょう。
/**
* 業務前に、一度自分のアカウントから[メールアドレス]を入力して実行してください
*/
function setUserProperty() {
//自分のメールアドレスを登録してください
const email = '[email protected]';
const userProperties = PropertiesService.getUserProperties();
userProperties.setProperty('USER', email);
}
フォームを送信したアカウントでGmailの [下書き] を開くと、下書きが1件作成されています。
確認のため、スクリプトエディタの [実行数] を開きます。
「フォーム送信時トリガー」 が3件同時に発火しています。トリガーは3件発火していますが、if (user === formUesr) が true になるのは、 実行アカウントとフォーム送信者が一致する1件 のみです。
最終回の記事は、私が所属しているノンプロ研の@etau氏の頭の中を、弟子である私が通訳したものです。師匠、いつもありがとうございます。
まとめ
以上で、 「トリガー作成アカウントと実行アカウントの違いについて」 お届けしました。
アカウントの違いについて、策を講じましたが、 [ウェブアプリ] として公開した場合は、さほど気にしないでいいと思います。なので、あくまで 社内運用 したときに困った場合、参考にしていただければ幸いです。
このシリーズでは 「Googleフォームとイベントオブジェクトを極めよう」 ということで、さまざまなフォームの活用方法をご紹介しました。
ノーコード・ローコードアプリ作成が流行りの昨今ですが、まだまだ 「ちょっとカスタマイズしたいだけなのに」 や 「こんなこともやってみたい」 という現場の声は多いはずです。
引き続き 「実務で使えるツール作り」 を意識して、学習を続けたいと思います。
Comments