0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

google spread sheetで期日になったら通知するGAS

Posted at

やりたいこと

Google Spread Sheetで業務や在庫などの期日を管理している場面で、期日間近になったら定期的に通知してくれるようにしたい。
期日x前に注意通知先のアドレス、期日過ぎたら警告通知先のアドレスに送信するようにする。

管理シートの形式

大項目 中項目 小項目 担当者 期日 注意通知の送り先email 警告通知の送り先email
AAA aaa 高橋 2023/8/1 takahashi@mail section1@mail
AAA bbb 佐藤 2023/5/1 satou@mail section1@mail
BBB ccc 渡辺 2023/7/1 watanabe@mail section1@mail
CCC bbb 斉藤 2023/7/1 saitou@mail section1@mail
BBB ddd 高橋 2023/4/1 takahashi@mail section1@mail
AAA aaa 渡辺 2023/5/1 watanabe@mail section1@mail
DDD aaa 渡辺 2023/8/1 watanabe@mail section1@mail

プログラム

GASは普段プログラムを書かない人も使う可能性があると思うので、コメント多めに入れています。

function ExpiredNotification() {
    // ===== 実行する前のアラーム =====
    let result = Browser.msgBox('期限切れ物品に対し、メールを送信しますか?', Browser.Buttons.OK_CANCEL);
    if (result == 'cancel'){
        return;
    }

    // ===== 対象ファイル =====
    const ss = SpreadsheetApp.getActiveSpreadsheet();
    const ss_url = ss.getUrl();

    // ===== 対象シート =====
    // 対象シート上にクリックボタンを配置して実行する場合は、getActiveSheetにする。別シートから実行する場合は、getSheetByNameにする。
    //const sh = ss.getActiveSheet();
    const sh = ss.getSheetByName('保管リスト');

    // ===== 表の行方向範囲 =====
    const start = 2; //開始行番号
    const last = sh.getLastRow();


    // ===== 現日付 =====
    const today = new Date();

    // x日後に保管期日を超える物品に通知する場合は、today.getDate()にx日を足す。
    // 間もなく期限が切れることの通知(注意通知期日)
    const dateBorderA = 30; // ■■■任意設定■■■
    const shresholddateA = new Date(today.getFullYear(), today.getMonth(), today.getDate() + dateBorderA);

    // 期限が切れたことの通知(警告通知期日)
    const dateBorderB = 0; //■■■任意設定■■■
    const shresholddateB = new Date(today.getFullYear(), today.getMonth(), today.getDate() + dateBorderB);


    // ===== 表を連想配列として取り込む =====
    let data = [];
    let strLarge, strMedium, strSmall, strPerson, strLimit, strMail, strGroupMail
    for (let i=start; i<=last; i++){
        // 大項目
        strLarge = sh.getRange('A'+i).getValue();

        // 中項目
        strMedium = sh.getRange('B'+i).getValue();

        // 小項目
        strSmall = sh.getRange('C'+i).getValue();

        // 担当者
        strPerson = sh.getRange('D'+i).getValue();

        // 期日
        strLimit = sh.getRange('E'+i).getValue();

        // 注意通知のメールアドレス
        strMail = sh.getRange('F'+i).getValue();

        // 警告通知のメールアドレス
        strGroupMail = sh.getRange('G'+i).getValue();

        // 連想配列に格納
        data.push({large:strLarge, medium:strMedium, small:strSmall, person:strPerson, limit:strLimit, mail:strMail, groupmail:strGroupMail});
    }; // for i 終了


    // ===== 注意通知 =====
    // 同一連絡先にまとめて送りやすくするため、メールアドレスで降順sortする。
    data.sort((a, b)=>{
        if(a.mail > b.mail) return -1;
        if(a.mail < b.mail) return 1;
        return 0;
    });
    // 期日x日前且つ連絡先ありでフィルタリング
    const filterdataA = data.filter(x => x.limit <= shresholddateA && x.mail !== '');
    // 該当品がない場合はreturn。
    if (filterdataA == ''){
        return;
    }
    // メール配信
    SendMail(filterdataA, 'mail', '(注意)期日間近です', ss_url);


    // ===== 警告通知 =====
    // 同一連絡先にまとめて送りやすくするため、メールアドレスで降順sortする。
    data.sort((a, b)=>{
        if(a.groupmail > b.groupmail) return -1;
        if(a.groupmail < b.groupmail) return 1;
        return 0;
    });
    // 期日過ぎ且つ連絡先ありでフィルタリング
    const filterdataB = data.filter(x => x.limit <= shresholddateB && x.groupmail !== '');
    // 該当品がない場合はreturn
    if (filterdataB == ''){
        return;
    }
    SendMail(filterdataB, 'groupmail', '(警告)期日が過ぎています', ss_url);

} // function 終了


//  ===== メール送信関数 =====
function SendMail(inputData, keyName, strTitle, sheetURL) {
    // 同一連絡先はまとめてメール配信
    const len = Object.keys(inputData).length;   // フィルター後のデータ数
    const strSubject = strTitle;   // メール件名
    const strFooter = 'シートURL:' + sheetURL + '\n\n'
        + '※自動配信のため、本メールに返信不要';
    let strBody = '';   //メール本文の初期化
    let toAddress = '';

    try{
        for (let j=0; j<=len-1; j++){  // 配列は0はじまりなので、最後はlen-1
            //日付のフォーマット
            if (inputData[j].limit !== ''){
                if(isNaN(inputData[j].limit.getFullYear()) || isNaN(inputData[j].limit.getMonth()) || isNaN(inputData[j].limit.getDate())){
                    strLimit = '期日が正しく入力されていません。';
                }else{
                    strLimit = Utilities.formatDate(inputData[j].limit,"JST","yyyy/MM/dd");
                }

            }else{
                strLimit = '期日が空欄か、入力が正しくありません。';
            }
            // メール本文の作成。同一宛先で複数の物品がある場合は、追加していく。
            strBody = strBody
                + '・大項目:' + inputData[j].large + '\n'
                + '・中項目:' + inputData[j].medium + '\n'
                + '・小項目:' + inputData[j].small + '\n'
                + '・担当者:' + inputData[j].person + '\n'
                + '・期日:' + strLimit + '\n'
                + '\n';
            if (j<=len-2){  // 下にデータがまだある場合
                // 下のデータの連絡先が違う場合は、メール送信
                if (inputData[j][keyName] !== inputData[j+1][keyName]){
                    strBody = strBody + strFooter;
                    toAddress = inputData[j][keyName];
                    GmailApp.sendEmail(toAddress, strSubject, strBody);
                    strBody = '';  //メール本文の初期化
                }
            }else{  // 最終データの場合は、メール送信
                strBody = strBody + strFooter;
                toAddress = inputData[j][keyName];
                GmailApp.sendEmail(toAddress, strSubject, strBody);
                strBody = '';  //メール本文の初期化
            }
        } // for j 終了
    }catch(e){
        console.log(strBody);
        console.log(toAddress);
    }
}

変数や関数の補足

const start
には、表の開始番号を入れる。
今回の場合は、項目名が1行目なので2を入れている。

const dateBorderA = 30
が、期日30日前に注意通知をする設定箇所。
宛先は注意通知の送り先email。

const dateBorderA = 0
が、期日0日前(つまり期日切れ)に警告通知をする設定箇所。
宛先は警告通知の送り先email。

sh.getRange('A'+i).getValue()
でA列を取り込んでいる。
列が変わる場合はAの部分を変えること。
(他の列も同様)

GmailApp.sendEmail
の関数でメール送信している。
送信元も変更できるが、権限によってはできない。
複数宛に送信する場合はカンマ区切りでアドレスを入れればOK。

GASのトリガーで関数を実行するようにすれば、定期的に自動で実行してくれる。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?