見出し画像

【生成AI×GAS】営業日を逆算して締切期日設定GASの解説②

オレンジピーチのトシです。
今回は、引き続き、営業日を逆算して締切期日を設定するGASの解説を行います。
(前回解説の記事はこちら)


作成したGASのおさらい

今回の記事で解説するGASがこちらです。
スクリプトの内容も、一見すると複雑に見えます。
しかし、順に見ていくと、GAS初心者の人でも十分に理解できる内容になっています。
前回の記事で、スクリプトの全体的な構成を説明しましたので、今回は順に詳細な説明を行っていきます。

function sendEmail() {
  // スプレッドシートを開く
  var sheet = SpreadsheetApp.getActiveSheet();

  // A列2行目から最終行までの氏名を取得
  var nameRange = sheet.getRange("A2:A" + sheet.getLastRow());
  var nameList = nameRange.getValues();

  // B列2行目から最終行までのメールアドレスを取得
  var emailRange = sheet.getRange("B2:B" + sheet.getLastRow());
  var emailList = emailRange.getValues();

  // C列2行目から最終行までの部署名を取得
  var departmentRange = sheet.getRange("C2:C" + sheet.getLastRow());
  var departmentList = departmentRange.getValues();

  // 現在の日付を取得
  var today = new Date();
  var year = today.getFullYear();
  var month = today.getMonth() + 1; // 月は0始まりなので、+1する

  // 営業日を計算する関数を呼び出す
  var deadline = calculateBusinessDay(year, month);

  // 件名を設定
  var subject = `月次進捗ファイル(${year}${month}月度)の更新依頼`;

  // 各メールアドレスにメールを送信
  for (var i = 0; i < emailList.length; i++) {
    var recipient = emailList[i][0];
    var name = nameList[i][0];
    var department = departmentList[i][0];

    // 本文を設定
    var body = "";
    body += "株式会社オレンジピーチ \n";
    body += "\n";
    body += `${department}${name} 様\n`;
    body += "おつかれさまです。\n";
    body += "企画部の橙桃です。\n";
    body += `${year}${month}月度の月次進捗ファイルの更新をお願いいたします。\n`;
    body += `締切は、**${deadline}**となります。それまでに、リンクの月次進捗表を更新して下さい。\n`;
    body += "\n";
    body += `${department}${name} 月次進捗ファイル\nURL: ********\n`;
    body += "\n";
    body += "どうぞよろしくお願いします。";

    MailApp.sendEmail({
      to: recipient,
      subject: subject,
      body: body
    });
  }
}

function calculateBusinessDay(year, month) {
  // 月末日を取得
  var lastDay = new Date(year, month, 0);

  // 営業日を数える変数
  var businessDays = 0;

  // 営業日を5日戻るまでループ
  while (businessDays < 5) {
    lastDay.setDate(lastDay.getDate() - 1);
    
    // 土曜日または日曜日ならカウントしない
    if (lastDay.getDay() === 0 || lastDay.getDay() === 6) {
      continue;
    }

    // 祝日ならカウントしない
    if (isHoliday(lastDay)) {
      continue;
    }

    // 営業日をカウント
    businessDays++;
  }

  // 日付を文字列で返す
  return Utilities.formatDate(lastDay, Session.getScriptTimeZone(), 'MM月dd日');
}

function isHoliday(date) {
  // GoogleカレンダーAPIを使用して祝日を確認
  var calendarId = 'ja.japanese#holiday@group.v.calendar.google.com';
  var events = CalendarApp.getCalendarById(calendarId).getEventsForDay(date);

  return events.length > 0;
}

GASの内容解説②

それでは、順にコードの解説を行っていきます。
すでに過去の記事で紹介済みの箇所は省略して、今回の修正点を中心に進めていきます。

スプレッドシートからデータを取得(解説済のため省略)

前半のスクリプトは、これまでの内容から変更ありません。

// スプレッドシートを開く
var sheet = SpreadsheetApp.getActiveSheet();

// A列2行目から最終行までの氏名を取得
var nameRange = sheet.getRange("A2:A" + sheet.getLastRow());
var nameList = nameRange.getValues();

// B列2行目から最終行までのメールアドレスを取得
var emailRange = sheet.getRange("B2:B" + sheet.getLastRow());
var emailList = emailRange.getValues();

// C列2行目から最終行までの部署名を取得
var departmentRange = sheet.getRange("C2:C" + sheet.getLastRow());
var departmentList = departmentRange.getValues();

// 現在の日付を取得
var today = new Date();
var year = today.getFullYear();
var month = today.getMonth() + 1; // 月は0始まりなので、+1する

営業日を計算する関数を呼び出す

今回の修正で変更となった箇所です。
別の関数である、関数 calculateBusinessDay(year, month) を呼び出しています。
その際に、引数として 変数 year、変数 month を渡しています。
(別の関数の呼び出しについて詳しく知りたい方は、こちらの記事をご覧ください。)

営業日を計算する関数の解説

呼び出した関数 calculateBusinessDay(year, month) の内容を見ていきましょう。

月末日を取得する
まず、new Date オブジェクトを用いて、新しく日付を取得します。
第1引数、第2引数で、year, month を指定しているため、現在の年・月の日付になります。
第3引数として「0」を指定している点がポイントです。
日に 0 を指定すると、指定された月の前月の最後の日、つまり月末日になります。

少しややこしいのですが、第2引数のmonthは「現在の月+1」したものでした、そのため、monthの前月の最後の日は、当月の月末日になる訳なのです。

そして、得られた日付を、変数 lastDay に格納します。

// 月末日を取得
var lastDay = new Date(year, month, 0);

営業日をカウントする変数
次に、営業日をカウントするための変数を準備します。
初期値としてまず変数に0を代入しています。

// 営業日を数える変数
var businessDays = 0;

営業日を5日戻るまでループ
営業日を遡ってカウントします。

ループの内容は次回の記事で説明したいと思います。

// 営業日を5日戻るまでループ
while (businessDays < 5) {
  lastDay.setDate(lastDay.getDate() - 1);

  // 土曜日または日曜日ならカウントしない
  if (lastDay.getDay() === 0 || lastDay.getDay() === 6) {
    continue;
  }


  // 祝日ならカウントしない
  if (isHoliday(lastDay)) {
    continue;
  }

  // 営業日をカウント
  businessDays++;
}

ここまでのまとめ

今回は、Dateオブジェクトを用いて月末日を取得する部分のGASの解説を行いました。
月末日を取得するコードのような記載は、そのコードの書き方を知っている人と、知らない人の差が大きく表れる部分と思います。
このような場合にも、生成AIであれば過去の大量の情報を元に解決方法を提示してくれるため、スキルアップにも繋がっていきます。
生成AIをパートナーとして、記事を読んで頂いた人のGAS技術の向上につながればHappyです。
次回は、ここから日付を遡っていくところを解説したいと思います。

今回は以上です。最後まで読んで頂き、ありがとうございました。
記事の内容が参考になった方は、「スキ」して頂けると励みになります。






この記事が少しでもお役に立てたのなら、サポートいただけると嬉しいです。頂いたご支援は、今後の活動費やコンテンツの質向上に使わせていただきます。