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

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

新規登録して質問してみよう
ただいま回答率
85.35%
Google Apps Script

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

Q&A

解決済

3回答

8900閲覧

Google Apps Scriptでフォーム機能からメール送信でエラーが出る

oyatsu8

総合スコア97

Google Apps Script

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

0グッド

0クリップ

投稿2020/06/27 04:04

編集2020/06/27 17:03

修正したいこと

エラーメールが来ないように修正したい。

現在の状態

下記のサイトなどを参考に、フォームを送信すると自動返信メールが送られる設定をしたところ、

http://creazy.net/2011/03/google_form_mailsend.html

送信者にも、フォーム管理側にも想定したメールは届くのですが、
もう1通、フォーム管理側にエラーメールが届くようになりました。
想定通りの動きをしているのに、エラーメールが来る原因がわかりません。

エラーメッセージ

件名:【失敗】Googleフォームからメール送信中にエラーが発生
本文:Cannot read property 'getLastRow' of null

エラーメッセージを送っていコード部分

catch(e){
MailApp.sendEmail(admin, "【失敗】Googleフォームからメール送信中にエラーが発生", e.message);
}

やってみたこと

もしかして、
var sheet = SpreadsheetApp.getActiveSheet();

var rows = sheet.getLastRow();
の間にgetSheetName("フォームのタイトル(日本語)")の処理が必要だったのかもしれないと思いいれて見ましたが、
別のエラー
"パラメータ(String)が SpreadsheetApp.Sheet.getSheetName のメソッドのシグネ
チャと一致しません。"
と出ました、、

また、よくわからなかったのが、シート名は回答フォームからスプレッドシートを開いた時のシートのタイトルだと思ったのですが、もしかして違うのでしょうか、この質問をみたのですが、
https://teratail.com/questions/189952
sheetNameが何を指すのかがわからず、、

色々理解しきれていませんが、アドバイスを頂けると助かります。


ソースコード全体

Google

1function sendMailGoogleForm() { 2 Logger.log('sendMailGoogleForm() debug start'); 3 4 //------------------------------------------------------------ 5 // 設定エリアここから 6 //------------------------------------------------------------ 7 8 // 件名、本文、フッター 9 var subject = "[メッセージ]"; 10 var body 11 = "メッセージ\n\n" 12 + "------------------------------------------------------------\n"; 13 var footer 14 = "------------------------------------------------------------\n\n" 15 + ""; 16 17 // 入力カラム名の指定 18 var NAME_COL_NAME = '名前'; 19 var MAIL_COL_NAME = 'メールアドレス'; 20 21 22 // メール送信先 23 var admin = "メールアドレス"; // 管理者(必須) 24 var sendername = "送信者名";//送信者名(必須) 25 var cc = ""; // Cc: 26 var bcc = admin; // Bcc: 27 var reply = admin; // Reply-To: 28 var to = ""; // To: (入力者のアドレスが自動で入ります) 29 30 31 //------------------------------------------------------------ 32 // 設定エリアここまで 33 //------------------------------------------------------------ 34 35 try{ 36 // スプレッドシートの操作 37 var sheet = SpreadsheetApp.getActiveSheet(); 38 39 var rows = sheet.getLastRow(); 40 var cols = sheet.getLastColumn(); 41 var rg = sheet.getDataRange(); 42 Logger.log("rows="+rows+" cols="+cols); 43 44 // メール件名・本文作成と送信先メールアドレス取得 45 for (var i = 1; i <= cols; i++ ) { 46 var col_name = rg.getCell(1, i).getValue(); // カラム名 47 var col_value = rg.getCell(rows, i).getValue(); // 入力値 48 body += "【"+col_name+"】\n"; 49 body += col_value + "\n\n"; 50 if ( col_name === NAME_COL_NAME ) { 51 body = col_value+" 様\n\n"+body; 52 } 53 if ( col_name === MAIL_COL_NAME ) { 54 to = col_value; 55 } 56 } 57 body += footer; 58 59 // 送信先オプション 60 var options = {name: sendername}; 61 if ( cc ) options.cc = cc; 62 if ( bcc ) options.bcc = bcc; 63 if ( reply ) options.replyTo = reply; 64 65 // メール送信 66 if ( to ) { 67 MailApp.sendEmail(to, subject, body, options); 68 }else{ 69 MailApp.sendEmail(admin, "【失敗】Googleフォームにメールアドレスが指定されていません", body); 70 } 71 72 }catch(e){ 73 MailApp.sendEmail(admin, "【失敗】Googleフォームからメール送信中にエラーが発生", e.message); 74 } 75} 76

修正後(現状)

GAS

1//sendMailGoogleForm04 2 3 4function sendMailGoogleForm() { 5 Logger.log('sendMailGoogleForm() debug start'); 6 7 //------------------------------------------------------------ 8 // 設定エリアここから 9 //------------------------------------------------------------ 10 11 // 件名、本文、フッター 12 var subject = "[件名]"; 13 var body 14 = "本文\n\n" 15 + "------------------------------------------------------------\n"; 16 var footer 17 = "------------------------------------------------------------\n\n" 18 + "フッター"; 19 20 // 入力カラム名の指定 21 var NAME_COL_NAME = '名前'; 22 var MAIL_COL_NAME = 'メールアドレス'; 23 var SUBJ_COL_NAME = '件名'; 24 //メール除外カラム 25 var EXCLUDE_COLS = ['ステータス','対応日時']; 26 27 28 // メール送信先 29 var admin = "メールアドレスm"; // 管理者(必須) 30 31 // スプレッドシートID 32// URLが「https://docs.google.com/spreadsheets/d/abc1234567/edit#gid=0」だったら「abc1234567」がID 33var spread_sheet_id = 'ID'; 34 35 36 37 //------------------------------------------------------------ 38 // 設定エリアここまで 39 //------------------------------------------------------------ 40 41 try{ 42 43 // スプレッドシートの操作 44 45 var ss = SpreadsheetApp.openById(spread_sheet_id); 46 var sh = ss.getSheetByName('form_ans');//シート名 47 console.log("ファイル名",sh.getName()); 48 49 var rows = sh.getLastRow(); 50 console.log("rows:",rows); 51 52 var cols = sh.getLastColumn(); 53 console.log("cols:",cols); 54 55 var rg = sh.getDataRange(); 56 Logger.log("rows="+rows+"cols="+cols); 57 58 //メール件名・本文作成と送信先メールアドレス取得 59 var to = ""; //To:(入力者のアドレスが自動で入ります) 60 for(var j = 1;j<=cols;j++){ 61 var col_name = rg.getCell(1,j).getValue(); //カラム名 62 var col_value = rg.getCell(rows,j).getValue(); //入力値 63 //メール用変換 64 if(col_name === NAME_COL_NAME){ 65 body = col_value + "様\n\n"+body; 66 } 67 if(col_name === MAIL_COL_NAME){ 68 to = col_value; 69 } 70 if(col_name === SUBJ_COL_NAME){ 71 subject += col_value; 72 } 73 //日付フォーマットの変換 74 //他にも変換したいカラムがある場合はこのif文をコピーしてカラム名・日付フォーマットを変更する 75 if(col_name === 'タイムスタンプ'){ 76 col_value = Utilities.formatDate(col_value,"JST","yyyy-MM-dd HH:mm:ss"); 77 } 78 //メール送信除外カラム 79 if(EXCLUDE_COLS.length > 0){ 80 is_exclude = false; 81 for(var k = 0;k<EXCLUDE_COLS.length;k++){ 82 if(col_name === EXCLUDE_COLS[k]){ 83 is_exclude = true; 84 break; 85 } 86 } 87 if(is_exclude){ 88 //除外カラムなのでスキップ 89 continue; 90 } 91 } 92 //メール本文に追加 93 body += "["+col_name+"]\n"; 94 body += col_value + "\n\n"; 95 } 96 97 body += footer; 98 /*ユーザー宛送信*/ 99 //送信オプション 100 var options = {}; 101 if(admin)options.replyTo = admin; 102 //メール送信 103 if(to){ 104 MailApp.sendEmail(to,subject,body,options); 105 }else{ 106 MailApp.sendEmail(admin,"[失敗]Googleフォームにメールアドレスが指定されていません",body); 107 } 108 109 /*管理者宛送信*/ 110 //送信先オプション 111 var options = {}; 112 if(to)options.replyTo = to; 113 //連続で送るとエラーになるので1秒スリープ 114 Utilities.sleep(1000); 115 MailApp.sendEmail(admin,subject,body,options); 116 117 118 }catch(e){ 119 MailApp.sendEmail(admin,"[失敗]Googleフォームからメール送信中にエラーが発生",e.message); 120 } 121} 122

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

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

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

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

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

guest

回答3

0

ベストアンサー

var sheet = SpreadsheetApp.getActiveSheet();でアクティブなシートを取得していますが、これに失敗すると(アクティブなシートが見つからない場合)、sheetの値がnullになり、続く処理のvar rows = sheet.getLastRow();で提示されたエラーが発生します。

解決策は、スプレッドシートのオブジェクトをID指定で取得して、シートをシート名指定で取得すること、でしょうか。

GAS

1var sheet = SpreadsheetApp.openById('スプレッドシートの実際のURLに書いてあるIDで置換').getSheetByName('実際のシート名で置換'); 2

投稿2020/06/27 10:53

編集2020/06/27 14:50
Daregada

総合スコア11990

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

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

Daregada

2020/06/27 12:23 編集

後から気がついたんですが、質問者が参考にしているサイトも「この情報古いので新しい記事を書きました」という旨のことが書いてあり、新しい記事ではIDでスプレッドシートを取得(ただし、シートはgetActiveSheet()で取得)するようにコードが訂正されていました。ネットの情報を基に作業するときは、できるだけ新しい情報を参考にしてください、ということで。
oyatsu8

2020/06/27 12:38

回答ありがとうございます。 今から試してみます。
oyatsu8

2020/06/27 12:48

>「この情報古いので新しい記事を書きました」という旨のことが書いてあり、新しい記事ではIDでスプレッドシートを取得 この記事自体が新しくしたものだと勘違いしていました。今から読んでみます。ありがとうございます。
Daregada

2020/06/27 14:40

最初のコメントに書いたように、新しいほうもgetActiveSheetを使っているんですよ。私の回答のようにシート名でシートを取得するように修正してみてください。
oyatsu8

2020/06/27 15:10 編集

すみません、どうにもわからず、下記のように書き換えましたが、今度も同じ Cannot read property 'getLastRow' of null が出ました。今度はエラーだけでなく、送信もできませんでした。 // スプレッドシートの操作 var ss = SpreadsheetApp.openById(spread_sheet_id); //var sh = ss.getActiveSheet(); //元のコード var sh = ss.getSheetByName('フォームの名前'); //書き換えたコード
MasakiTM

2020/06/27 16:12

横からすいませんが、フォームの名前じゃなくてシートの名前じゃないんですか。
Daregada

2020/06/27 16:28

スプレッドシートを表示したときのURLから、d/ と /edit の間の部分を抜き出したのがIDで、スプレッドシートの左下に出っ張って表示されている「シート1」などの文字列がシート名です。
oyatsu8

2020/06/27 16:33

ありがとうございます、書き間違えていました。シートのタイトルのことですよね。色々混乱しています。。
oyatsu8

2020/06/27 16:45

夜分にありがとうございます。やはりメールの送受信はできるのですが、相変わらずエラーが出ており、 ログを出して見たところ、ちゃんと帰ってきていました。。 Cannot read property 'getLastRow' of null var ss = SpreadsheetApp.openById(spread_sheet_id); var sh = ss.getSheetByName('シート名'); var rows = sh.getLastRow(); console.log("rows:",rows); var cols = sh.getLastColumn(); console.log("cols:",cols); var rg = sh.getDataRange(); Logger.log("rows="+rows+"cols="+cols); 帰ってきたログ 020/06/28 1:37:24 デバッグ rows: 38 2020/06/28 1:37:24 デバッグ cols: 20 2020/06/28 1:37:24 情報 rows=38cols=20
Daregada

2020/06/27 16:56

もう質問に載っているソースとは別のものを使ってますよね? spread_sheet_id とか質問のソースには含まれていませんし。 そうすると、こちらでは確かめようがないのです。
Daregada

2020/06/27 17:00

そのログは、メールを出せた時のログですね。nullのエラーはもう少し前で起きていますからログに記録されていません。コメントで部分的に見ている範囲でいうと、ssやshを、getLastRow() を動かすより前に、ログに出して確認してください。
oyatsu8

2020/06/27 17:17 編集

getLastRowより前でログを出して見ました。 // スプレッドシートの操作 var ss = SpreadsheetApp.openById(spread_sheet_id); var sh = ss.getSheetByName('form_ans');//シート名 console.log("ss:",ss.getName()); console.log("sh:",sh.getName()); ログ: Stackdriver のログ 2020/06/28 2:13:05 情報 sendMailGoogleForm() debug start 2020/06/28 2:13:05 デバッグ ss: ファイル名 2020/06/28 2:13:05 デバッグ sh: シート名 2020/06/28 2:13:05 デバッグ rows: 41 2020/06/28 2:13:05 デバッグ cols: 20 2020/06/28 2:13:05 情報 rows=41cols=20
oyatsu8

2020/06/27 17:10

ほんとに夜分にありがとうございます。また、今のコードを本文に追記しました。修正後(現状)の部分です。2時を超えてしまったため、一旦寝てから考えます。大変ありがとうございました。
guest

0

深く解析してないので申し訳ないですが
とりあえず else if(to=="")、else 略 エラーが発生~
みたいにしてみては?

投稿2020/06/27 08:09

MasakiTM

総合スコア115

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

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

oyatsu8

2020/06/27 12:37

回答をありがとうございます。 今から試してみます。
oyatsu8

2020/06/28 05:27

深夜にコメントをありがとうございました。
guest

0

解決しました。回答をくださったDaregadaさんと、MasakiTMさんのおかげでコードはなんとかなったのですが、送信元(google suite)とメール送信先(gmail)を変えていたため(個人的な理由で)、メール送信先に必ずエラーが送られていたように思えます。そのため送信元とメール送信先を同じ(google suite)にしたところ、エラーは送信されなくなりました。えらく時間がかかってしまいました。なんども返事をしていただき、大変ありがとうございます。

投稿2020/06/28 05:30

編集2020/06/28 05:31
oyatsu8

総合スコア97

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問