Google Apps Script (GAS)で文書作成をどれだけ効率化できるか挑戦 Part4.5 ~続・トリガー(再チャレンジ編)~

加藤です。 そろそろ春…?と思いきや寒い日があったりするので風邪をひきそうですね…。

シリーズPart4.5です。前回の記事はこちら。

tech.arms-soft.co.jp

前回、onEdit()トリガーを使って、スプレッドシートの条件付き書式もどきを作成しました。

ToDoリストの「進捗」の値に応じてセルの背景色を変えることには成功したのですが、 進捗とは別の列にある「期日」をチェックして、過ぎていたら日付のフォントを赤字にする…という条件分岐と書式設定を書こうとしてうまくいきませんでした。

最後にぼやいて終わってしまっていたので、あれから再挑戦をしてみました。

結果、無事に追加をすることができましたので経過報告です。

期日チェックの追加

onEdit()を以下のように編集しました。

スプレッドシートは作成したToDoリストの日付を変えてそのまま使っています。

f:id:xkato:20200316125323p:plain:w500

function onEdit(event){
  
    var status_column = 4;
    var deadline_column = 3;    //「期日」列の列番号
    
    // シート・編集範囲・列・行の取得
    var editSheet = event.source.getActiveSheet();
    var editRange = event.source.getActiveRange();
    var columnIndex = editRange.getColumn();
    var rowIndex = editRange.getRow();
  
    // 判定 - 進捗
    if(editSheet.getName() == "シート2" && columnIndex == status_column){
        check_status(editSheet,rowIndex,status_column)
    // 判定 - 期日
    }else if(editSheet.getName() == "シート2" && columnIndex == deadline_column){
        check_deadline(editSheet,rowIndex,deadline_column);
    }
}


// 「進捗」に応じて背景色変更
function check_status(editSheet,rowIndex,status_column){

    var status = {
        working : '作業中',
        complete : '完了'
   }
    if(editSheet.getRange(rowIndex, status_column).getValue() == status.working){
        editSheet.getRange(rowIndex, status_column, 1, 1).setBackgroundColor('yellow');
    } else if(editSheet.getRange(rowIndex, status_column).getValue() == status.complete) {
        editSheet.getRange(rowIndex, 1, 1, editSheet.getLastColumn()).setBackgroundColor('gray');
    } else {
        editSheet.getRange(rowIndex, 1, 1, editSheet.getLastColumn()).setBackgroundColor('white');
    }
}

// 期日チェック
function check_deadline(editSheet,rowIndex,deadline_column){
  
    // 現在日付と期日を取得
    var today = new Date();
    var deadline = editSheet.getRange(rowIndex, deadline_column).getValue(); 
  
    if(today.getTime() > deadline.getTime())
    {
      // 期日が過ぎていたら赤字にする
      editSheet.getRange(rowIndex, deadline_column, 1, editSheet.getLastColumn()).setFontColor('red');
    }else{
      // 過ぎていなければ黒字のまま
      editSheet.getRange(rowIndex, deadline_column, 1, editSheet.getLastColumn()).setFontColor('black');
    }
}

ポイント

新しく「期日」の列番号を表すdeadline_columnを変数で宣言し、「どこが編集されたか?」で分岐をさせるようにしてみました。

また、editSheetはevent.source.getActiveSheet()で取得した「編集されたシート」であるため、 同じように3列目に日付がある別のシートでもこの書式が適用されてしまう問題があることも発覚しました。 そのため分岐条件に「ToDoリストシート(シート2)の日付列が編集されたとき」と明確な条件指定をしています。

さらにつらつら書いてきたonEdit()が長くなってきたので、進捗チェックと期限チェック用に関数を切り出しました。

これで以前よりは読みやすくなったかな、と思います。 判定条件と書式設定の関数を同じように使いまわして追加していくようにすれば、新しく増やしていけるはずです。

おまけ

文書作成とは少し違う気がしたので、おまけとして載せておきます。

このToDoリストで、完了した作業の報告メールを送ることができるように機能を追加してみました。

f:id:xkato:20200316125534p:plain:w500

メール送信用のボタンを描写して、以下のsend_reportmail()スクリプトを割り当てました。

「完了」になっているタスクを取得して、メールの本文に組み込んでます。

// メール送信
function send_reportmail(){
  
  var sheet = SpreadsheetApp.getActiveSheet();
  var lastRow = sheet.getLastRow();
  var task = new Array();
  
  for(var i = 2; i <= lastRow; i++) {
    if(sheet.getRange(i, 4).getValue() == "完了"){
      task.push(sheet.getRange(i, 2).getValue());
    }
  }
  report_task = task.join('、');
  
  MailApp.sendEmail(
    {
      to: '<メールアドレス>',
      subject: '作業報告',
      body: 'タスク '+ report_task +' が完了です。おつかれさまでした!', 
    }
  );

GASではMailApp.sendEmail()でメールを送ることができます。

f:id:xkato:20200316193338p:plain:w500

このような感じで、メールもちゃんと届きました。

テキストだけの非常にそっけないメールになってしまいましたが、htmlメールの設定もできるようです。

条件を変えて、メール送信を定時処理にしたら、リマインダーにもできそうです。

今回は以上です。