ここで紹介するGAS(diyReplay)とスプレッドシートの関数を使って、Googleフォームの回答以外の値を、返信メールの文面に簡単に表示できます。
例えば、回答項目を使って計算した合計金額などを、返信メールの文章に加えることができます。
準備
テストのフォームとスプレッドシートを作りながら、作成したGAS(diyReply)の機能を説明します。
フォーム
次のようなフォームを作ります。

①返信メールの件名
②返信メールの本文
③返信メールの宛先
スプレッドシート
スプレッドシートにリンクします。


シートを追加して、返信メールに必要なシート(ここでは、シート1)を作ります。

- 1行目(C1~E1)には、質問項目の①②③を入れます。
- 2行目(B2~E2)には、フォームからの回答が入ります。
- B3:OFF(半角)を入れるとメールを送りません。(文章作成時のテスト時に使えます。)
- B4:返信メールの件名を入れます。ここでは、=C2を入れます。
- B5:返信メールの本文を入れます。ここでは、=D2を入れます。
- B6:返信メールの宛先を入れます。ここでは、=E2を入れます。
- B7:必要なら、CC:を入れます。複数の場合は、aaa@gmail.com, bbb@gmail.comのように,で区切ってください。
- B8:必要なら、BCC:を入れます。複数の場合は、aaa@gmail.com, bbb@gmail.comのように,で区切ってください。
- B9:必要なら、送信元(自分)の表示名を入れます。
- B10:必要なら、返信先アドレスを入れます。
- B11(New!):必要なら、送信元アドレスを入れます。
送信元アドレスには、Googleアカウント(Gmailアドレス)のエイリアスをご利用ください。
(※権限のないメールアドレスでは、送信できませんのでご注意ください。) - B12(New!):ON(半角)を入れるとC12に回答編集用のURLを表示します。
GAS
GAS(diyReply)を登録します。スクリプトエディタを開きます。

次のGAS(diyReplay)をエディタへコピペします。
- function diyReply(SheetNo) {
- // アクティブなフォームとスプレッドシート
- const form = FormApp.getActiveForm();
- if (!(SheetNo > 1)) SheetNo = 1; // SheetNoは必要なら変更する(一番左のシートが0、2番目が1、3番目が2…)
- const ss = SpreadsheetApp.openById(form.getDestinationId());
- // 回答シートとメール用シートを取得
- const answerSheet = ss.getSheets()[0];
- const mailSheet = ss.getSheets()[SheetNo];
- // フォームのすべての回答を取得し、最後の(最新の)タイムスタンプを取得
- const formResponses = form.getResponses();
- const lastResponse = formResponses[formResponses.length - 1];
- const formTimestamp = lastResponse.getTimestamp();
- // 回答シートのA列(タイムスタンプ)から、最新のフォーム送信と一致する行を探す
- const sheetTimestamp = answerSheet.getRange(2, 1, answerSheet.getLastRow() - 1).getValues();
- let targetRow = -1;
- for (let i = 0; i < sheetTimestamp.length; i++) {
- if (sheetTimestamp[i][0] instanceof Date && sheetTimestamp[i][0].getTime() === formTimestamp.getTime()) {
- targetRow = i + 2; // 実際の行番号
- break;
- }
- }
- if (targetRow === -1) {
- Logger.log("回答が見つかりませんでした。");
- return;
- }
- // 見つけた行の回答内容をメール用シートに転記
- const lastCol = answerSheet.getLastColumn(); // 最大列数を取得
- mailSheet.getRange(2, 2, 1, lastCol).setValues(answerSheet.getRange(targetRow, 1, 1, lastCol).getDisplayValues());
- SpreadsheetApp.flush(); // sync;sync;syncのおまじない(省略可)
- // B12セルが"ON"の場合、C12に編集リンクを出力
- mailSheet.getRange('C12').setValue(mailSheet.getRange('B12').getValue() === 'ON' ? lastResponse.getEditResponseUrl() : "");
- // メール用シートの項目(B3-B11)を配列に取得
- const mailTbl = mailSheet.getRange('B3:B11').getDisplayValues().map(elm => elm[0]);
- // FROM:(B11)が未設定ならアクティブユーザーのメールアドレスを使用
- if (!mailTbl[8]) mailTbl[8] = Session.getActiveUser().getEmail();
- // "OFF"でなければメール送信
- if (mailTbl[0] !== 'OFF') {
- GmailApp.sendEmail(mailTbl[3],mailTbl[1],mailTbl[2],{from:mailTbl[8],cc:mailTbl[4],bcc:mailTbl[5],name:mailTbl[6],replyTo:mailTbl[7]});
- }
- } //Ver4.0.0 for maintenance
今回のバージョン(Ver4.0.0)は、これまでにいただいた複数のご指摘をもとに、問題点を徹底的に解消した構成となっています。
回答の位置を、シートとフォームの両方から取得する「ハイブリッド型」の仕組みを採用しており、これまで発生していたすべての問題パターンに、初めて完全に対応できました。
↓ ↓ コピペ ↓ ↓ (保存を忘れずに!)

トリガー
トリガーを追加します。

イベントの種類の選択は、「フォーム送信時」を選びます。

※承認を求められたら、「Advanced」(あるいは、「詳細」)→「Go to ~~(Unsafe)」(あるいは、「~~に移動」)→「Allow」(あるいは、「許可」)

動作テスト
フォームを実行(プレビュー)して、回答、そして送信します。

結果、シート1に次のように表示されています。

結果、宛先(TO:)へ送られてきた返信メールです。

成功しました。
このように、GAS(diyReply)はフォームからの回答をシート1にコピー、シート1の内容をメールするだけです。
つまり、思い通りのメールを送るには、スプレッドシートの関数を駆使して自分で作る必要があります。
そして、どのような返信メールも自由自在に作ることができます。
実践編
応用例その8
フォームより入力された項目には価格があり、その合計金額をメールに表示したいとします。
注文商品(価格あり)の個数をプルダウンのメニューから選ぶフォームです。

返信メールのためのシート1を次のように作りました。
数式表示[Ctrl]+@しています。

テーブル(コピペ用)に表示します。
質問 | タイムスタンプ | 名前 | メールアドレス | 注文商品1(1,500円/個) | 注文商品2 (2,500円/個) |
最新の回答 | |||||
OFF: メールを送らない | |||||
件名 | ご注文承りました | ||||
本文 | =C2&" 様、 ご注文をありがとうございます。 ------------------------------- 注文商品: "&E1&"×"&E2&"個 "&F1&"×"&F2&"個 合計金額:"&TEXT((1500*E2+2500*F2),"#,##0")&"円 ------------------------------- お支払方法は、~~~ またのご利用をお待ちしております。" | ||||
TO: | =D2 | ||||
CC:(省略可) | |||||
BCC:(省略可) | |||||
NAME:(省略可) | 〇〇商店 | ||||
REPLY TO:(省略可) | |||||
FROM:(省略可) | |||||
ON: 回答編集用のURLを表示 |
"文字列"(ダブルクォーテーションで挟まれた文字列)とセルの数値(C2など)を、&(半角)でつなぎながら文章を書くのは慣れないと少し難しいかもしれません。
コツは最初に"を付けてから、一気に文章を書きあげて最後に"で閉じます。
この時、改行([Ctrl]+[Enter]キー)も気にせずに使います。
それから必要な箇所を"&※※&"に置き換えていきます。(※※は、A1,、B2など)
B5セルに望みの文章が表示出来たら、それがそのままメールの文章になります。
実行(プレビュー)します。


成功です。
合計金額が表示された返信メールが送られてきました。
シート1の名前(NAME:)で記した○○商店も表示されています。

この例を参考に、ご自分の思い通りな返信メールをお作り下さい。
応用例その8.5(クレジット決済を追加する)
お支払い方法に銀行振込だけでなくクレジット決済も対応した応用例です。
ご参考までにどうぞ。
応用例その9
応用例その11(2つのGASを使って署名活動フォームを作る)
応用例の補足(フォームの選択肢に定員設定を追加する)
次のGAS(updateItems)を使って、フォームの選択肢に定員(人数制限)を付けられます。
今回のGAS(diyReply)と同時に使うことで、フォームの応用がさらに広がります。
複数のGASの同時使用の応用例が『応用例その11』です。
参考にしてください。
応用例の補足2(フォームの回答者数に定員設定を追加する)
次のmultiReplyは、今回のdiyReplyに"フォームの回答者数に定員設定"ができる機能を追加しました。
「質問の選択肢」毎の定員でなく、「回答者数」の定員でよいのなら、とても有用なスクリプトです。
おわりに
GASを組むことで、フォームやスプレッドシートから得られる質問項目と回答項目を、メール文書に加えるのは簡単です。
しかし、それらにない計算値などをメールに加えるには、GASを特別に組み直さなければいけません。
フォームに対して1対1のGASになってしまい、汎用性が失われてしまします。
また、GASで数式を組んでテストをするのは、なかなかに手間がかかります。
そこで、この負担をスプレッドシートの関数側に持っていくために、GASの機能を削りに削ってできたのが今回のdiyReplyです。
GASでは困難な複雑な数式も、スプレッドシートの関数ならトライ&エラーが簡単に行えるため短時間で完成できます。
diyReplyと組み合わせることで、今回の例では合計金額ですが、関数に詳しい方はいくらでも難しい数式で得た値を、メールに表示できます。
ぜひ、自由自在な返信メールをご活用ください。
それでは、また次の記事でお会いしましょう。
追記(2024.9.25):
このGASを公開して1年以上が経ちますが、今でも日に20~30人の方がご覧になられるようです。
それに伴いこれまで、いくつかの問題点をご指摘いただきました。
特に、フォームとスプレッドシートの回答数が一致しない場合、混乱が生じていたというご指摘を何度か受け、今回の大幅なバージョンアップを行い以下の点を改善いたしました。
- 従来はスプレッドシートから回答を取得していましたが、新しいバージョン(2.1.0)以降では、フォームに直接記録された回答を取得するように変更いたしました。
これにより、確実に最後の回答を取得できるようになり、フォームとスプレッドシートの回答数が一致しない場合でも確実に、フォームからの送信者(回答者)の回答を使ったメールが送れます。
次の機能は、より柔軟な対応を可能にするため、追加いたしました。
- 返信メールの送信者(From:)に、フォームのオーナーのメールアドレスのエイリアスを設定できるようにしました。
- 回答者が自身の回答を編集するためのURLを表示できるようになりました。
もし使ってみて何か問題点がありましたら、コメントにてお知らせいただけると幸いです。
追記(2025.5.2):
質問セクションについて、バージョン2.1.0以降では、回答をフォームから直接取得する方式のため、対応できていません。旧バージョン(1.3.x以前)では、スプレッドシートから取得するために問題はありません。ただし、最新の回答が必ず回答シートの最終行になるように注意してください。
旧バージョンが必要な方は、このリンク(diyReply-Ver1.3.0)を参照してください。
追記(2025.5.18):
最新バージョン(Ver4.0.0)は、これまでにいただいた複数のご指摘をもとに、問題点を徹底的に解消した構成となっています。
回答の位置をシートとフォームの両方から取得する「ハイブリッド型」の仕組みを採用しており、これまで発生していたあらゆる問題パターンに、今回初めて完全に対応することができました。
特に、回答シートを手動で操作した場合などに発生する、フォームとシートの回答数の不一致によるメールの誤送信にも対応できました。
これにより、より安心してご利用いただけるようになったかと思います。
コメント
#VALUE!になりましたね。進歩しました。
セルのF2は使われていたんですね。サンプルは商品をE~Fにしていましたので、Fを削除しました。
あと、フォームで商品数をプルダウンから選ぶ時の数値は、必ず半角の数字だけでお願いしますね。
=C2&"様
この度は籽清ZIQINGをご利用頂きまして
誠にありがとうございます。
━━━━━━━━━━━
【注文商品】
"&IF(D2="","",D1&"×"&D2&"個="&TEXT((1000*D2),"#,##0")&"円
")&IF(E2="","",E1&"×"&E2&"個="&TEXT((2000*E2),"#,##0")&"円
")&"【合計金額】"&TEXT((10500*D2+3500*E2),"#,##0")&"円
━━━━━━━━━━━
【お支払方法】
・のちほどお送り致します請求書に沿って
海外送金をお願い致します。
・振込手数料につきましては別途ご負担wo願います。(インターネットからのお手続きが便利でお得です)
・入金確認後、発送準備を進めて参ります。
━━━━━━━━━━━
Mai:ziqing@gmail.com
籽清ZIQING(シーズジックイーン)
659-○○○○27-1"
これでご確認ください。
今度は、#VALUE!がでました。内容は関数限【 MULTIPLY のパラメータ 2 の値は 数値 にしてください。テキスト が「○○@ymobile.ne.jp」になっているので、数値 にできません。】です。
この「○○@ymobile.ne.jp」は質問の宛先F2入ってくるもので、TO=F2にしています。
この後、CCには、店のアドレス、NAMEには店名を手入力しています。
本当に手を取らせてすみません。
どうぞ宜しくお願い致します。
当ブログをご覧いただきありがとうございます。
ご質問の送信元のメールアドレスの変更ですが、システムの規制上できません。
プログラム内でメール送信のコマンドなどを実行したときの送信者は、プログラムの実行者、あるいはプログラムのオーナーになります。
ですので、Googleフォームは、そのオーナーのGoogleアカウントのメールアドレス(gmail)が使用されます。
代わりにですが、セルB10の返信先アドレスに記入されたアドレス(ReplyTo)は、相手が返信をするときに採用されます。こちらは自由に設定できます。
ご参考になりましたでしょうか。
追記、
Gmailはエイリアスをサポートしていますので、任意のメールアドレスでGoogleのSendMailサーバーを使うことができます。オーナーのGmailアドレスにエイリアスを設定されている人は、送信元にそのエイリアスを指定できます。
その場合は、スクリプトの20行目を、
(変更前)
GmailApp.sendEmail(mailTbl[3],mailTbl[1],mailTbl[2],{cc:mailTbl[4],bcc:mailTbl[5],name:mailTbl[6],replyTo:mailTbl[7]});
(変更後)
GmailApp.sendEmail(mailTbl[3],mailTbl[1],mailTbl[2],{from:'aaa@bbb.co.jp',cc:mailTbl[4],bcc:mailTbl[5],name:mailTbl[6],replyTo:mailTbl[7]})
このようにエイリアス(aaa@bbb.co.jp)を追加することで送信元を代えることもできます。
今後、エイリアスを使っている人が多いようなら、送信元も設定項目に追加してもよいのかなと思いました。
了解です。
エラー処理とスタイルを整えただけです。計算式等はそのままです。
=C2&"様
この度は籽清ZIQINGをご利用頂きまして
誠にありがとうございます。
━━━━━━━━━━━
【注文商品】
"&IF(D2="","",D1&"×"&D2&"個="&TEXT((1000*D2),"#,##0")&"円
")&IF(E2="","",E1&"×"&E2&"個="&TEXT((2000*E2),"#,##0")&"円
")&IF(F2="","",F1&"×"&F2&"個="&TEXT((3000*F2),"#,##0")&"円
")&"【合計金額】"&TEXT((10500*D2+3500*E2),"#,##0")&"円
━━━━━━━━━━━
【お支払方法】
・のちほどお送り致します請求書に沿って
海外送金をお願い致します。
・振込手数料につきましては別途ご負担wo願います。(インターネットからのお手続きが便利でお得です)
・入金確認後、発送準備を進めて参ります。
━━━━━━━━━━━
Mai:ziqing@gmail.com
籽清ZIQING(シーズジックイーン)
659-○○○○27-1"
コピペでお試しください。
記事を拝見し参考にさせていただいております。
送信元のメールアドレスを変更したい場合、記述はどのようにしたらよろしいでしょうか?
ご教示いただけますと大変助かります。
よろしくお願いいたします。
有難うございます!
お言葉に甘えまして…。
宜しくお願い致します。
=C2&”様
この度は籽清ZIQINGをご利用頂きまして
誠にありがとうございます。
━━━━━━━━━━━
=”【注文商品】”&CHAR(10)&IF(D2=””,””,D1&”×”&D2&”個=”&TEXT((1000*D2),”#,##0″)&”円”&CHAR(10))&IF(E2=””,””,E1&”×”&E2&”個=”&TEXT((2000*E2),”#,##0″)&”円”&CHAR(10))&IF(F2=””,””,F1&”×”&F2&”個=”&TEXT((3000*F2),”#,##0″)&”円”&CHAR(10))
【合計金額】”&TEXT((10500*D2+3500*E2),”#,##0″)&”円
━━━━━━━━━━━
【お支払方法】
・のちほどお送り致します請求書に沿って
海外送金をお願い致します。
・振込手数料につきましては別途ご負担wo願います。(インターネットからのお手続きが便利でお得です)
・入金確認後、発送準備を進めて参ります。
━━━━━━━━━━━
Mai:ziqing@gmail.com
籽清ZIQING(シーズジックイーン)
659-○○
○○27-1″
このコメントにあなたの数式をコピペされたのですか?ちょっと載っていないようなのですが……。
ひょっとしてですが、私が作成した数式をそのままでなく弄ってテストしていますか?
もしそうであるなら、セルB5の本文の数式を私の方で見ましょうか?
このコメントの返信にコピペしていただければ、確認できますがいかがでしょうか?
すみません、全角と変な文字はないか見ましたが、また同じエラーです。
改行もされないです。私の方の改行されていない数式を見ていただこうとこちらにコピペしましたら、ちゃんと改行されます。
文字色ですが、【注文商品】、個、#,##0は黒色で、D2やE2は紫や水色、それ以外の文章は全て緑色です。
最後の住所…27-1としていますがその後に消しても消しても”がつきます。
何かわかればと思い、記させて頂きました。
よろしくお願い致します。
それは関数が間違っているエラーですね。なにか変な文字が入っているのかな…?
もう一度、セルをクリアして、次の関数式をコピペしてください。
="【注文商品】"&CHAR(10)&IF(D2="","",D1&"×"&D2&"個="&TEXT((1000*D2),"#,##0")&"円"&CHAR(10))&IF(E2="","",E1&"×"&E2&"個="&TEXT((2000*E2),"#,##0")&"円"&CHAR(10))&IF(F2="","",F1&"×"&F2&"個="&TEXT((3000*F2),"#,##0")&"円"&CHAR(10))
まだ同じエラーが出ますか?
コピーされた関数式をじ~っと見て、間違いがないかよく見てください。ひょっとして半角”が全角”になっていないでしょうか?
最後に変な(や”が追加されていませんか?
間違い探しですね!
数式の解析エラーです。