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

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

ただいまの
回答率

90.00%

GASで複数の企業に複数の異なるファイルを添付して一斉メール送信する際、空白のセルが存在すると実行できない

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 2,816

seijisam

score 5

GoogleスプレッドシートとGASを用いて、複数の企業にそれぞれの企業別に異なる複数のファイルを添付して、メールを一斉送信したい。

ただし、企業によって添付するファイルの数が異なり、添付ファイルが1つだけのところもあれば、2つ、あるいは3つの企業もあります。

![イメージ説明](ccbdc8dc28a04611568ba01b7801d891.gif)

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

添付のように添付ファイル名を呼び出すセルが空白だと、そこでスクリプトの実行が止まってしまいます。

空白はそのままスキップし(添付なし)で、次の行に移動して欲しいのですが。

### 該当のソースコード

  //------------- Google Driveから添付ファイルを取得 -----------------------
  // 添付ファイル用の配列を作成
  var attachmentFiles = new Array(); 

  // 添付ファイル1~3を取得

  var folder = DriveApp.getFolderById('-----------------------'); //(添付1ファイル)のフォルダIDで取得
  var file1 = folder.getFilesByName(mySheet.getRange(i,3).getValue()).next(); //(添付1ファイル)のファイル名を取得    

  var folder = DriveApp.getFolderById(''-----------------------'); //(添付2ファイル)のフォルダIDで取得
  var file2 = folder.getFilesByName(mySheet.getRange(i,4).getValue()).next(); //(添付2ファイル)のファイル名を取得

 var folder = DriveApp.getFolderById(''-----------------------'); //(添付3ファイル)のフォルダIDで取得
  var file3 = folder.getFilesByName(mySheet.getRange(i,5).getValue()).next(); //(添付3ファイル)のファイル名を取得    


### 試したこと

素人で全く分からないのですが、指定されたセルにデータが存在しない(空白)のときは、戻り値はブランクで処理終了(次の行に移動)といった処理が出来ないものかと思うのですが、そういったことは可能でしょうか?

宜しくご教授願います。

### 補足情報(FW/ツールのバージョンなど)

function sendMailWithAttachments(){

/* スプレッドシートのシートを取得と準備 */

var mySheet=SpreadsheetApp.getActiveSheet(); //シートを取得

/* ドキュメント「メール本文」を取得する */
var docTest=DocumentApp.openById("-----------------------"); //メール本文のドキュメントをIDで取得
var strDoc=docTest.getBody().getText(); //ドキュメントの内容を取得

/* メール表題、fromアドレス、差出人名を準備 */
var strSubject="複数添付ファイルの送付"; //表題
var strFrom="-----------------------"; //From
var strSender="-----------------------"; //差出人

// 添付ファイル用の配列を作成
var attachmentFiles =[];

var arr = mySheet.getRange(2, 2, 4, 4).getValues();// 

//処理負荷軽減のためまとめてフォルダー情報を取得

var folders = [
DriveApp.getFolderById('-----------------------'), //(添付1ファイル)のフォルダIDで取得
DriveApp.getFolderById('-----------------------'), //(添付2ファイル)のフォルダIDで取得
DriveApp.getFolderById('-----------------------') //(添付3ファイル)のフォルダIDで取得
];

for(var i = 0, i= arr.length; i <1; i++){

var strTo=arr[i][0].getValue().next(); //送付先メールアドレスを取得

//添付ファイル1~3を取得(空白ならスキップ) 

if(arr[i][1] != ''){
attachmentFiles.push(folders[0].getFilesByName(arr[i][1]).next());
}
if(arr[i][2] != ''){
attachmentFiles.push(folders[1].getFilesByName(arr[i][2]).next());
}
if(arr[i][3] != ''){
attachmentFiles.push(folders[2].getFilesByName(arr[i][3]).next());
}
}

var strBody=strDoc

/* メールを送信 */
GmailApp.sendEmail(
strTo, //toアドレス
strSubject,  //表題
strBody, //本文
{
from: strFrom, //fromアドレス
name: strSender, //差出人
attachments: []
}
); 

}
コード
```

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

質問への追記・修正、ベストアンサー選択の依頼

  • 退会済みユーザー

    退会済みユーザー

    2018/03/27 15:15

    初心者マークは付けておきましょうね。

    キャンセル

回答 3

checkベストアンサー

+1

改めて回答させていただきますね。
コード中に補足も入れています。

function sendMailWithAttachments(){

  /*省略*/

    var arr = mySheet.getRange(2, 2, 4, 4).getValues();// 
    /*
    arr が二次元配列として以下のように取得されていることがイメージできていますか?
    [['送信先アドレス','添付1ファイル名','添付2ファイル名','添付3ファイル名'],...[]]
    */

  /*省略*/

    for(var i = 0, l = arr.length; i < l; i++){//←修正しました。

       //var strTo=arr[i][0].getValue().next(); //送付先メールアドレスを取得
       var strTo=arr[i][0];

     //添付ファイル1~3を取得(空白ならスキップ) 

        if(arr[i][1] != ''){
            attachmentFiles.push(folders[0].getFilesByName(arr[i][1]).next());
        }
        if(arr[i][2] != ''){
            attachmentFiles.push(folders[1].getFilesByName(arr[i][2]).next());
        }
        if(arr[i][3] != ''){
            attachmentFiles.push(folders[2].getFilesByName(arr[i][3]).next());
        }
     //}

    //var strBody=strDoc //←必要ですか?

    /* メールを送信 */
    GmailApp.sendEmail(
      strTo, //toアドレス
      strSubject,  //表題
      //strBody, //本文
      strDoc,
      {
        from: strFrom, //fromアドレス
        name: strSender, //差出人
        //attachments: [] //←空配列を添付?
        attachments:attachmentFiles
      }
    );

    attachmentFiles = []; //初期化
  }
/*
forループでの処理が間違っています。
最初に示したロジック通りになっていません。
「企業ごとに」空値チェック、添付ファイル取得、メール送信までを行います。
*/

  }


[補足]
お約束ではございますが、動作確認等はしておりませんので、参考までに。

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/04/03 09:39 編集

    for分の括り、間違っていませんか?
    attachmentFiles = []; //初期化 までがループ処理になります。
    あと、要所要所でLogger.log()にて値がちゃんと取得できているか確認してみてください。
    (具体的にはstrTo、arr[i][1]、arr[i][2]、arr[i][3])

    キャンセル

  • 2018/04/04 09:21

    stshisho様

    for分の括りを見直し修正したところ、正確に動かすことが出来ました!!

    本当に有難うございました!!

    キャンセル

  • 2018/04/04 09:55

    何よりです。

    キャンセル

0

まず、ループ中の処理だけを提示されているのかと思いますが、全体が見えないので見える部分のみでの回答となります。
ロジックとしては以下のようにすれば良いと思います。

  1. メールアドレス~添付ファイル名_3までの範囲を取得(B2:E5)
  2. 企業ごとに空値チェック、添付ファイル取得、メール送信までを行う

条件分岐をわかりやすく、あえて泥臭く適当に組んだサンプルです。
動作確認はしていませんので参考程度に。

    /*省略*/
    var arr = mySheet.getRange(2, 2, 4, 4).getValues();// 1
    //処理負荷軽減のためまとめてフォルダー情報を取得
    var folders = [
        DriveApp.getFolderById('-----------------------'), //(添付1ファイル)のフォルダIDで取得
        DriveApp.getFolderById('-----------------------'), //(添付2ファイル)のフォルダIDで取得
        DriveApp.getFolderById('-----------------------') //(添付3ファイル)のフォルダIDで取得
    ];
    // 2
    for(var i = 0, l = arr.length; i < l; i++){
        if(arr[i][1] != ''){
            attachmentFiles.push(folders[0].getFilesByName(arr[i][1]).next());
        }
        if(arr[i][2] != ''){
            attachmentFiles.push(folders[1].getFilesByName(arr[i][2]).next());
        }
        if(arr[i][3] != ''){
            attachmentFiles.push(folders[2].getFilesByName(arr[i][3]).next());
        }
        /*メール送信処理省略 to:arr[i][0] */
        attachmentFiles = []; //初期化
    }
    /*省略*/


[補足]
一部、コード中に記述ミスがありましたので修正しました。

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/03/28 08:45

    早速アドバイスを頂き、有難うございました。

    これから試してみます。まずはお礼まで。

    キャンセル

  • 2018/03/28 16:00

    stshisho様

    教えて頂いた内容をもとに本日ずっとトライしていますが、ご推察のとおり当方初心者マークが10個くらい必要なスーパー素人なため、未だにうまく動かせていません。

    試行錯誤して現在下記のようなスクリプトに辿り着いたのですが、方向性は合っていますでしょうか?
    (無効なメール: undefined 行48 というエラーが出ています)

    あるいは全くトンチンカンなことをやっていますでしょうか?

    お忙しいところ恐縮ですが、ご教授頂ければ幸いです。

    --------------------------------------------------------------------
    function sendMailWithAttachments(){

    /* スプレッドシートのシートを取得と準備 */

    var mySheet=SpreadsheetApp.getActiveSheet(); //シートを取得

    /* ドキュメント「メール本文」を取得する */
    var docTest=DocumentApp.openById("---------------------------"); //メール本文のドキュメントをIDで取得
    var strDoc=docTest.getBody().getText(); //ドキュメントの内容を取得

    /* メール表題、fromアドレス、差出人名を準備 */
    var strSubject="複数添付ファイルの送付"; //表題
    var strFrom="------------------------"; //From
    var strSender="----------------------"; //差出人

    // 添付ファイル用の配列を作成
    var attachmentFiles =[];

    var arr = mySheet.getRange(2, 2, 4, 4).getValues();//

    //処理負荷軽減のためまとめてフォルダー情報を取得

    var folders = [
    DriveApp.getFolderById('--------------------------'), //(添付1ファイル)のフォルダIDで取得
    DriveApp.getFolderById('--------------------------'), //(添付2ファイル)のフォルダIDで取得
    DriveApp.getFolderById('--------------------------') //(添付3ファイル)のフォルダIDで取得
    ];


    for(var i = 0, i= arr.length; i <1; i++){

    var strTo=arr[i][0].getValue().next(); //送付先メールアドレス

    if(arr[i][1] != ''){
    attachmentFiles.push(folders[0].getFilesByName(arr[i][1]).next());
    }
    if(arr[i][2] != ''){
    attachmentFiles.push(folders[1].getFilesByName(arr[i][2]).next());
    }
    if(arr[i][3] != ''){
    attachmentFiles.push(folders[2].getFilesByName(arr[i][3]).next());
    }
    }

    var strBody=strDoc

    /* メールを送信 */
    GmailApp.sendEmail(
    strTo, //toアドレス
    strSubject, //表題
    strBody, //本文
    {
    from: strFrom, //fromアドレス
    name: strSender, //差出人
    attachments: []
    }
    );

    }

    キャンセル

  • 2018/03/28 18:19

    申し訳ございませんが、コメント欄にコードを記述されると可読性が悪いため、質問欄に補足として追記していただければと思います。
    (「</>」のアイコンをクリックしてください。)
    あと、できれば適切なインデント処理(字下げ)もお願いします。

    キャンセル

0

function sendMailWithAttachments(){

  /* スプレッドシートのシートを取得と準備 */

  var mySheet=SpreadsheetApp.getActiveSheet(); //シートを取得

  /* ドキュメント「メール本文」を取得する */
  var docTest=DocumentApp.openById("------------------------------"); //メール本文のドキュメントをIDで取得
  var strDoc=docTest.getBody().getText(); //ドキュメントの内容を取得

  /* メール表題、fromアドレス、差出人名を準備 */
  var strSubject="複数添付ファイルの送付"; //表題
  var strFrom="------------------------------"; //From
  var strSender="------------------------------"; //差出人

   // 添付ファイル用の配列を作成
    var attachmentFiles =[];

    var arr = mySheet.getRange(2, 2, 4, 4).getValues();// 

    //処理負荷軽減のためまとめてフォルダー情報を取得

    var folders = [
        DriveApp.getFolderById('------------------------------'), //(添付1ファイル)のフォルダIDで取得
        DriveApp.getFolderById('------------------------------'), //(添付2ファイル)のフォルダIDで取得
        DriveApp.getFolderById('------------------------------') //(添付3ファイル)のフォルダIDで取得
    ];


    for(var i = 0, i= arr.length; i <1; i++){

       var strTo=arr[i][0].getValue().next(); //送付先メールアドレスを取得

     //添付ファイル1~3を取得(空白ならスキップ) 

        if(arr[i][1] != ''){
            attachmentFiles.push(folders[0].getFilesByName(arr[i][1]).next());
        }
        if(arr[i][2] != ''){
            attachmentFiles.push(folders[1].getFilesByName(arr[i][2]).next());
        }
        if(arr[i][3] != ''){
            attachmentFiles.push(folders[2].getFilesByName(arr[i][3]).next());
        }
     }

    var strBody=strDoc

    /* メールを送信 */
    GmailApp.sendEmail(
      strTo, //toアドレス
      strSubject,  //表題
      strBody, //本文
      {
        from: strFrom, //fromアドレス
        name: strSender, //差出人
        attachments: []
      }
    ); 

  }

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

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

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