chikako65
@chikako65

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

GASで自動メール送信:個別に本文の内容を変えて送信したい

Google App Scriptでスプレッドシートの内容を自動で取得してメールを送るコードを作成しています。
本文に記載するデータをくり返し取得する方法が知りたいです。

取得したいデータは画像のようになっていて、メール1件に対してA列からE列の情報を反映させたいと思っています。

A列:送信相手の氏名
B列:送信相手のメールアドレス

以下メール本文にくり返し反映させたい内容
(アポイントの相手の情報です)
C列:氏名
D列:場所
E列:日時

test.png

2件目のメールはF~J列、3件目のメールはK~O列の内容を反映させたいです。

このC~E列(F~J列、K~O列)は関数で別のシートから値を引用しており、データ数が増えたり減ったりします。

現在のコードではA2からE2のデータのみGASでメールを自動送信できるようになったのですが、C~F列の3行目以下、およびF列以降のデータをくり返し取得することができません。

※現在のコードでは本文用にドキュメントファイルを引用しています。
コード作成参考サイト:https://tonari-it.com/gas-replace/

function sendMail(){

const sheet = SpreadsheetApp.getActiveSheet();
const lastRow = sheet.getLastRow();
const values = sheet.getRange(1, 1, lastRow, 10).getValues(); 

const DOC_URL = 'ドキュメントURL'; //本文の編集用ドキュメント 
const doc = DocumentApp.openByUrl(DOC_URL);
const docText = doc.getBody().getText();

const subject = 'メルマガ送信テスト';
const options = {name: '差出人'};


for(let i = 1; i < lastRow; i++){ 

const personnel = values[i][0]; //担当者
const recipient = values[i][1]; //メルアド
const name = values[i][2]; //氏名
const place = values[i][3]; //場所
const filledin = values[i][4]; //日時


let body = docText
.replace('{担当者}',personnel)
.replace('{氏名}',name)
.replace('{場所}',place)
.replace('{日時}',date)


GmailApp.sendEmail(recipient, subject, body, options);
}
}

bodyに氏名、場所、日時を入力データがなくなるまで代入するようなコードでいいのかなとやってみたのですが、うまく取得できません。
上記のコード以外の方法でも結構ですので、どなたかお力を貸していただけないでしょうか。
よろしくお願いいたします。

1

1Answer

こんにちは。
GASと聞いて来たのですが、ほぼほぼ完成してると思いますよ。

質問の部分。
今現在は

const lastRow = sheet.getLastRow();
const values = sheet.getRange(1, 1, lastRow, 10).getValues(); 

で一括で取得してるところを
もうちょっと細かく

const lastRow = sheet.getRange('C:C').getValues().filter(String).length;
const values = sheet.getRange('A1:E'+lastRow).getValues();

みたいにセクション毎に区切って
同じ処理すると想定した動作になると思います。

2Like

Comments

  1. @chikako65

    Questioner

    harmless_3d6様

    はじめまして。ご丁寧に教えていただいてありがとうございます。
    さっそく質問したコードを教えていただいた部分を書き換えて実行してみました。


    ```
    const personnel = values[i][0]; //担当者
    const recipient = values[i][1]; //メルアド
    ```

    この部分を

    ```
    const personnel = values[2][0]; //担当者
    const recipient = values[2][1]; //メルアド
    ```

    このように変えたところうまくC列最後までメールを送ることができました!
    教えていただいてありがとうございます。


    もし可能であれば、1件のメールにC2:E14の内容をすべて盛り込みたいのですが、そうなると質問したコードを大幅に変えないといけないのでしょうか?
    下記の理想のようなメールにしたいです。


    現状:B2のアドレスにC2からC14まで14件のメールが送られる

     1件目
      佐藤 様
      お疲れ様です。
      明日、担当いただく方の情報をお送りします。
      ご確認おねがいいたします。

      ーーーーーーーーーーーーーーーーーーーーーーーー
      氏名:A様
      場所:東京
      日時:20/8/14

     2件目
      佐藤 様
      お疲れ様です。
      明日、担当いただく方の情報をお送りします。
      ご確認おねがいいたします。

      ーーーーーーーーーーーーーーーーーーーーーーーー
      氏名:B
      場所:神奈川
      日時:20/8/14

      ~省略~

     14件目

      佐藤 様
      お疲れ様です。
      明日、担当いただく方の情報をお送りします。
      ご確認おねがいいたします。

      ーーーーーーーーーーーーーーーーーーーーーーーー
      氏名:M
      場所:埼玉
      日時:20/8/14



    理想:C~E列を繰り返して本文に記載

     1件目
      佐藤 様
      お疲れ様です。
      明日、担当いただく方の情報をお送りします。
      ご確認おねがいいたします。

      ーーーーーーーーーーーーーーーーーーーーーーーー
      氏名:A様
      場所:東京
      日時:20/8/14

      ーーーーーーーーーーーーーーーーーーーーーーーー
      氏名:B
      場所:神奈川
      日時:20/8/14

      ~省略~

      ーーーーーーーーーーーーーーーーーーーーーーーー
      氏名:M
      場所:埼玉
      日時:20/8/14


    度々の質問ですみませんが、ご存知でしたら教えてください。
    よろしくお願いいたします。
  2. 動いたようで良かったです。
    返信でいただいた要望への対応なら、
    最初の質問の中で書いてあったコードのループ文を
    「メールを送るため」→「文章を作るため」のものに変えたら
    行けると思いますよ。

    ちょっとコピペですけど

    ```
    let body = '';
    for(let i = 1; i < lastRow; i++){
    const personnel = values[i][0]; //担当者
    const recipient = values[i][1]; //メルアド
    const name = values[i][2]; //氏名
    const place = values[i][3]; //場所
    const filledin = values[i][4]; //日時

    let tempBody = docText.replace('{担当者}',personnel)
    .replace('{氏名}',name)
    .replace('{場所}',place)
    .replace('{日時}',date)

    if(body.length > 0){
    tempBody += "\n\n------------------------------------\n\n";
    }
    body += tempBody;
    }

    GmailApp.sendEmail(recipient, subject, body, options);
    ```

    こんな感じですかね?
  3. @chikako65

    Questioner

    harmless_3d6 様
    再度ご丁寧に教えていただいてありがとうございます。
    おかげさまで無事に1通のメールでくり返し情報を送ることができました。

    for(くり返し)の処理がいまいち理解できておらず、
    「メールを送るため」→「文章を作るため」
    のループにしたらよいとのことでとても参考になりました。

    本文にくり返し表示したい部分をドキュメントで編集できるようにし、冒頭の定型文はコードの中に書きました。

    let bodyで担当者、メルアドを取得したままだとうまく反映できなかったので、let body の下で値を取得してlet tempBodyと合わせてmainBodyとしました。



    以下最終的なコード


    function sendMail5(){

    const sheet = SpreadsheetApp.getActiveSheet();
    const lastRow = sheet.getRange('C:C').getValues().filter(String).length;
    const values = sheet.getRange('A1:E'+lastRow).getValues();

    const DOC_URL = 'ドキュメントURL'; //本文の編集用ドキュメント
    const doc = DocumentApp.openByUrl(DOC_URL);
    const docText = doc.getBody().getText();

    const subject = 'メルマガ送信テスト';
    const options = {name: '差出人'};


    let body = '';
    for(let i = 1; i < lastRow; i++){

    const name = values[i][2]; //氏名
    const place = values[i][3]; //場所
    const filledin = values[i][4]; //日時

    let tempBody = docText
    .replace('{氏名}',name)
    .replace('{場所}',place)
    .replace('{日時}',filledin)


    body += tempBody;

    }

    const personnel = values[1][0]; //担当者
    const recipient = values[1][1]; //メルアド

    var mainBody =

    personnel + ' 様\n\n'
    +'おつかれさまです。\n明日、担当いただく方の情報をお送りします。\nご確認お願いいたします。\n\n'
    + 'ーーーーーーーーーーーーーーーーーーーーーーーー\n'
    + body;

    GmailApp.sendEmail(recipient, subject, mainBody, options);
    }


    本当にありがとうございました!

Your answer might help someone💌