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

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

ただいまの
回答率

87.49%

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

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 4,158

score 86

修正したいこと

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

現在の状態

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

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が何を指すのかがわからず、、

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


ソースコード全体

function sendMailGoogleForm() {
 Logger.log('sendMailGoogleForm() debug start');

 //------------------------------------------------------------
 // 設定エリアここから
 //------------------------------------------------------------

 // 件名、本文、フッター
 var subject = "[メッセージ]";
 var body
 = "メッセージ\n\n"
 + "------------------------------------------------------------\n";
 var footer
 = "------------------------------------------------------------\n\n"
 + "";

 // 入力カラム名の指定
 var NAME_COL_NAME = '名前';
 var MAIL_COL_NAME = 'メールアドレス';


 // メール送信先
 var admin = "メールアドレス"; // 管理者(必須)
 var sendername = "送信者名";//送信者名(必須)
 var cc = ""; // Cc:
 var bcc = admin; // Bcc:
 var reply = admin; // Reply-To:
 var to = ""; // To: (入力者のアドレスが自動で入ります)


 //------------------------------------------------------------
 // 設定エリアここまで
 //------------------------------------------------------------

 try{
   // スプレッドシートの操作
   var sheet = SpreadsheetApp.getActiveSheet();

   var rows = sheet.getLastRow();
   var cols = sheet.getLastColumn();
   var rg = sheet.getDataRange();
   Logger.log("rows="+rows+" cols="+cols);

   // メール件名・本文作成と送信先メールアドレス取得
   for (var i = 1; i <= cols; i++ ) {
   var col_name = rg.getCell(1, i).getValue(); // カラム名
   var col_value = rg.getCell(rows, i).getValue(); // 入力値
   body += "【"+col_name+"】\n";
   body += col_value + "\n\n";
   if ( col_name === NAME_COL_NAME ) {
   body = col_value+" 様\n\n"+body;
   }
   if ( col_name === MAIL_COL_NAME ) {
   to = col_value;
   }
   }
   body += footer;

   // 送信先オプション
   var options = {name: sendername};
   if ( cc ) options.cc = cc;
   if ( bcc ) options.bcc = bcc;
   if ( reply ) options.replyTo = reply;

   // メール送信
     if ( to ) {
       MailApp.sendEmail(to, subject, body, options);
     }else{
       MailApp.sendEmail(admin, "【失敗】Googleフォームにメールアドレスが指定されていません", body);
     }

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

修正後(現状)

//sendMailGoogleForm04


function sendMailGoogleForm() {
 Logger.log('sendMailGoogleForm() debug start');

 //------------------------------------------------------------
 // 設定エリアここから
 //------------------------------------------------------------

 // 件名、本文、フッター
 var subject = "[件名]";
 var body
 = "本文\n\n"
 + "------------------------------------------------------------\n";
 var footer
 = "------------------------------------------------------------\n\n"
 + "フッター";

 // 入力カラム名の指定
 var NAME_COL_NAME = '名前';
 var MAIL_COL_NAME = 'メールアドレス';
 var SUBJ_COL_NAME = '件名';
 //メール除外カラム
 var EXCLUDE_COLS = ['ステータス','対応日時'];


 // メール送信先
 var admin = "メールアドレスm"; // 管理者(必須)

 // スプレッドシートID
// URLが「https://docs.google.com/spreadsheets/d/abc1234567/edit#gid=0」だったら「abc1234567」がID
var spread_sheet_id = 'ID';



 //------------------------------------------------------------
 // 設定エリアここまで
 //------------------------------------------------------------

 try{

   // スプレッドシートの操作

    var ss = SpreadsheetApp.openById(spread_sheet_id);
    var sh = ss.getSheetByName('form_ans');//シート名
    console.log("ファイル名",sh.getName());

    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);

    //メール件名・本文作成と送信先メールアドレス取得
    var to = ""; //To:(入力者のアドレスが自動で入ります)
    for(var j = 1;j<=cols;j++){
      var col_name = rg.getCell(1,j).getValue(); //カラム名
      var col_value = rg.getCell(rows,j).getValue(); //入力値
      //メール用変換
      if(col_name === NAME_COL_NAME){
        body = col_value + "様\n\n"+body;
      }
      if(col_name === MAIL_COL_NAME){
        to = col_value;
      }
      if(col_name === SUBJ_COL_NAME){
        subject += col_value;
      }
      //日付フォーマットの変換
      //他にも変換したいカラムがある場合はこのif文をコピーしてカラム名・日付フォーマットを変更する
      if(col_name === 'タイムスタンプ'){
        col_value = Utilities.formatDate(col_value,"JST","yyyy-MM-dd HH:mm:ss");
      }
      //メール送信除外カラム
      if(EXCLUDE_COLS.length > 0){
        is_exclude = false;
        for(var k = 0;k<EXCLUDE_COLS.length;k++){
          if(col_name === EXCLUDE_COLS[k]){
            is_exclude = true;
            break;
          }
        }
        if(is_exclude){
          //除外カラムなのでスキップ
          continue;
        }
      }
      //メール本文に追加
      body += "["+col_name+"]\n";
      body += col_value + "\n\n";
    }

    body += footer;
    /*ユーザー宛送信*/
    //送信オプション
    var options = {};
    if(admin)options.replyTo = admin;
    //メール送信
    if(to){
      MailApp.sendEmail(to,subject,body,options);
    }else{
      MailApp.sendEmail(admin,"[失敗]Googleフォームにメールアドレスが指定されていません",body);
    }

    /*管理者宛送信*/
    //送信先オプション
    var options = {};
    if(to)options.replyTo = to;
    //連続で送るとエラーになるので1秒スリープ
    Utilities.sleep(1000);
    MailApp.sendEmail(admin,subject,body,options);


  }catch(e){
    MailApp.sendEmail(admin,"[失敗]Googleフォームからメール送信中にエラーが発生",e.message);
  }
}
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

checkベストアンサー

+1

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

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

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

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/06/28 02:00

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

    キャンセル

  • 2020/06/28 02:08 編集

    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

    キャンセル

  • 2020/06/28 02:10

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

    キャンセル

+1

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/06/27 21:37

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

    キャンセル

  • 2020/06/28 14:27

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

    キャンセル

0

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

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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

  • ただいまの回答率 87.49%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る