BLOG

ブログ

  • Top
  • Blog
  • Google App Scriptを使用して当番表の作成をしてみた

Google App Scriptを使用して当番表の作成をしてみた

ブログサムネイル
Crunchtimer株式会社

著者:クランチタイマー株式会社

Twitter Icon

クランチタイマーはアプリ・Webサービスなどの開発を手掛けるWebデベロッパーです。ブログ記事ではロジカルで最適な手法を伝え、課題解決の手助けとなる情報を惜しみなく提供していきます。



はじめに

Google Apps Script(GAS)は、Googleのサービスを拡張してカスタマイズするための強力なツールです。

この記事では、GASを使用してスタッフの当番表の作成を自動化する具体的な方法を紹介します。

環境の設定

まず、Googleスプレッドシートを開き、「拡張機能」から「App Script」を選択します。

これでGASの基本的な編集環境が開かれます。

実際に作成する

要件

  • ・土日は、当番を割り振らない。
  • ・担当した曜日が次の担当の際に被らない。
  • ・特定の曜日に担当できない人がいるので除外する。
  • ・担当を選ぶ際は、担当回数が少ない人を選ぶ。
  • ・2ヶ月分の当番表を作成する。
  • ・週ごとに通知をする人が変わるので通知の当番の割り振りをする。

これらの要件をもとに作成したいと思います。

作成

担当者を割り振るための変数の定義と初期化をする。

staff:当番を担当する人の名前を定義

specialCases:特定の曜日に担当できない人がいるので除外するための変数

lastAssigned:各担当者が最後に割り当てられた日付を記録するオブジェクト

assignmentCount:各担当者の割り当て回数を追跡するオブジェクト

for文で、lastAssignedとassignmentCountに初期値を挿入しています。

dateArray:日付を格納するための変数

dateNameArray:曜日名を格納するための変数

chosenStaffArray:各日付に割り振られたスタッフの名前を格納する

chosenMondayStaffArray:月曜日に通知をするための担当者の名前が格納する

lastMondayStaff:月曜日の通知の担当者の初期値

const staff = ["中島", "小林", "佐々木", "滝村", "神本", "中井"];
 const specialCases = {
   "水": ["神本"]
 };
 let lastAssigned = {};
 let assignmentCount = {};  // 担当回数を追跡するオブジェクト
for (let i = 0; i < staff.length; i++) {
   lastAssigned[staff[i]] = new Date();
   lastAssigned[staff[i]].setDate(lastAssigned[staff[i]].getDate() - 10);
   assignmentCount[staff[i]] = 0;  // 担当回数を初期化
 }
let dateArray = [];
let dayNameArray = [];
let chosenStaffArray = [];
let chosenMondayStaffArray = [];
let lastMondayStaff = "滝村";

担当者の割り当て

60日間のループ:for ループを使用して、現在から60日間をカバーします。

ループ変数 i は0から始まり、60までカウントします。

現在の日付の設定:let today = new Date(); で現在の日付の新しいインスタンスを作成し、today.setDate(today.getDate() + i); でループのそれぞれに対応する日付に設定します。

週末のスキップ:if (today.getDay() === 0 || today.getDay() === 6) の条件で週末(日曜日と土曜日)をスキップします。これは、これらの日には割り当てを行わないためです。

曜日名の取得:dayNames 配列から today.getDay() を使って対応する曜日名を取得します。

利用可能なスタッフの選定:staff 配列から filter メソッドを使い、特定の条件を満たすスタッフを選び出します。

これには、特定の曜日に特定のスタッフを除外するルール(specialCases)や、前回の割り当てから一定期間が経過しているかどうかをチェックします。

担当回数が最も少ないスタッフの選定:利用可能なスタッフの中から担当回数が最も少ないスタッフを選びます。

これは、均等に割り当てるためのロジックです。

月曜日のスタッフの特別な処理:月曜日(.getDay() === 1)の場合、特定のロジックに従って選ばれるスタッフを変更し、chosenMondayStaffArray に追加します。

配列へのデータの追加:日付、曜日名、選ばれたスタッフをそれぞれ dateArray、dayNameArray、chosenStaffArray に追加します。

日付は Utilities.formatDate を使用してフォーマットされます。

for (let i = 0; i <= 60; i++) {
   let today = new Date();
   today.setDate(today.getDate() + i);


   // 週末をスキップ
   if (today.getDay() === 0 || today.getDay() === 6) {
     continue;
   }


   let dayNames = ["日", "月", "火", "水", "木", "金", "土"];
   let dayName = dayNames[today.getDay()];


   let availableStaff = staff.filter(function(name) {
     return !(specialCases[dayName] && specialCases[dayName].includes(name)) &&
            (!lastAssigned[name] || (today - lastAssigned[name]) / (1000 * 60 * 60 * 24) > 4);
   });


   // 担当回数が最も少ないスタッフを選ぶ
   availableStaff.sort((a, b) => assignmentCount[a] - assignmentCount[b]);
   let chosenStaff = availableStaff[0];
   lastAssigned[chosenStaff] = today;
   assignmentCount[chosenStaff] += 1;  // 担当回数をインクリメント


   if (today.getDay() === 1) {
     let chosenMondayStaff = lastMondayStaff === "滝村" ? "中井" : "滝村";
     lastMondayStaff = chosenMondayStaff;
     chosenMondayStaffArray.push(chosenMondayStaff);
   } else {
     chosenMondayStaffArray.push(null);
   }


   dateArray.push(Utilities.formatDate(today, "GMT", "MM/dd"));
   dayNameArray.push(dayName);
   chosenStaffArray.push(chosenStaff);
 }

スプレッドシートへの記入

アクティブなスプレッドシートの取得:const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet(); これにより、現在アクティブなスプレッドシートのアクティブなシートを取得します。

スプレッドシートへの固定値の設定:sheet.getRange() メソッドを使用して、特定のセル範囲を指定し、setValue() でその範囲に値を設定します。

この部分で、「名前」、「佐々木」、「小林」など、スタッフの名前や他の固定テキストをシートの特定のセルに設定しています。

配列データのスプレッドシートへの書き込み:
sheet.getRange().setValues() を使用して、dayNameArray(曜日名)、dateArray(日付)、chosenStaffArray(選ばれたスタッフ)、chosenMondayStaffArray(月曜日に選ばれたスタッフ)といった以前に計算された配列データをシートに書き込みます。

これらのデータは、シートの特定の列に沿って配置されます。


const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
 sheet.getRange(2, 1, 1, 1).setValue("名前");
 sheet.getRange(3, 1, 1, 1).setValue("佐々木");
 sheet.getRange(4, 1, 1, 1).setValue("小林");
 sheet.getRange(5, 1, 1, 1).setValue("中島");
 sheet.getRange(6, 1, 1, 1).setValue("滝村");
 sheet.getRange(7, 1, 1, 1).setValue("神本");
 sheet.getRange(8, 1, 1, 1).setValue("中井");
 sheet.getRange(10, 1, 1, 1).setValue("進行");
 sheet.getRange(11, 1, 1, 1).setValue("slack");
 sheet.getRange(1, 2, 1, dayNameArray.length).setValues([dayNameArray]);
 sheet.getRange(2, 2, 1, dateArray.length).setValues([dateArray]);
 sheet.getRange(10, 2, 1, chosenStaffArray.length).setValues([chosenStaffArray]);
 sheet.getRange(11, 2, 1, chosenMondayStaffArray.length).setValues([chosenMondayStaffArray]);

実行をしてスプレッドシートに記入する

Google App Scriptの実行ボタンを押す。

すると最初に開いていたスプレッドシートに記入されます。

まとめ

一般的なweb言語であるjavascriptの使用ができれば、当番表を簡単に作成できることが分かりました。

また、これを使用することで面倒な担当者の割り振りが簡単にできるので非常に便利です。

ぜひ参考にしてみてください。

この記事をシェア  

link-icon

筆者

中井祐一郎

クランチタイマー株式会社で主にフロントエンドの開発をしているエンジニアです。最近の好きな名言は「初めて牡蠣を食った人間は大胆な人間であった」です。ブログでは、主に言語や技術について解説させていただいてます。

最新情報を確認する

CONTACT

お気軽にお問い合わせください。

TEL082-299-2286

NEWSLETTER

代表の佐々⽊が⽉に1回お届けするメールマガジン。
国内外スタートアップの最新情報や最新技術のサマリー、クランチタイマーの開発事例紹介など、ITに関する役⽴つ情報を中⼼にお送りします!