ジャーナルクラブとレクチャーの割り当て やり方編


1.まずは大枠のイメージを作成する

これが実は一番難しい.完璧を目指すといつまで経ってもできないので,なんとなくイメージして作りながら修正する.これをアジャイル開発という.とはいえ,普通の仕事でも当たり前の話で,完璧を最初から目指し過ぎたら時間がいくらあっても足りないので,おおよそで走り始める.一方で,後で,大穴見つけると完全なやり直しとかもあり得るので,それなりに詰めておくのも大切.

僕が最初に考えたイメージ

割り当ては,木金土で,ジャーナルクラブ,レクチャー全然やっていない人から,公休日や有休,学会などを除いた上で割り当てていくとなるだろうと予想.ランダムに割り振る必要はあまりないかなと思った.
ということで,以下のような手順と予想した.

1.木金土のカレンダーを作る
2.祝日を取得する
3.メンバーのリストを作る
4.各メンバーのジャーナルクラブ,レクチャー最終日を取得する
5.各メンバーの公休日を把握する
6.各メンバーの有休を取得する
7.辞める日を把握する(さよならレクチャーのため)
8.辞める人はさよならレクチャーを辞める日の数週間前に割り当てて,以後は当たらないようにする
9.今から2ヶ月後の木金土を割り当てる
10.ジャーナルクラブもレクチャーも割当日に休みではなく,やったことない人>やったのが一番古い人の順で割り当てる
11.割り当てる人がいなかったらエラーをteamsに送るようにして気づくようにしておく

だいたい,これくらいをささっと考えて,後は,chat GPTにそれぞれの段階をやっていってもらうだけ.

2.木金土のカレンダーを作る

chat GPTにお願いしたらだいたいうまくいく.
その際に,先に実際にカレンダーを作るスプレッドシートを作成する必要がある.

こんな感じで,カレンダー作ったらそこで割り当てていくので割り当て表というシートにカレンダーを作ってもらうことにした.
プロンプトは以下の様な感じになる.
プロンプトの例はこれ.慣れたらGPTが理解しやすいプロンプトがわかってくる.

GASコードを書いてください.
”割り当て表"シートに木金土だけのカレンダーを作成したい.以下の条件でお願いします.
1.J列以降を一旦クリアしてください
2.1行目に日付けを入れてR, S, T列が8週間後の木曜日,金曜日,土曜日となるように
(今日が2024/5/11ならR列が6/27, S列が6/28, T列が6/29)
J列からAH列まで木金土の日付だけ入れてください
3.2行目に曜日を入れてください
function createWeekendCalendar() {
  // スプレッドシートを取得
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("割り当て表");

  // J列以降をクリア
  sheet.getRange("J1:AH1000").clear();  // 1000行までクリアしておきます。行数に応じて調整してください。

  // 現在の日付と8週間後の日付を取得
  var today = new Date();
  var eightWeeksLater = new Date();
  eightWeeksLater.setDate(today.getDate() + 56); // 8週間後 (8 * 7日)

  // 8週間後の木曜日、金曜日、土曜日を求める
  var startDay = eightWeeksLater.getDate() - eightWeeksLater.getDay() + 4; // 週の始まりを木曜日に設定
  var thursday = new Date(eightWeeksLater.setDate(startDay));
  var friday = new Date(eightWeeksLater.setDate(startDay + 1));
  var saturday = new Date(eightWeeksLater.setDate(startDay + 2));

  // 列のインデックスを設定
  var columnIndex = 18; // R列は18番目です

  // 8週間分の日付と曜日を設定
  for (var i = 0; i < 8; i++) {
    var thurs = new Date(thursday);
    var fri = new Date(friday);
    var sat = new Date(saturday);

    // 日付と曜日をセット
    sheet.getRange(1, columnIndex + i * 3).setValue(formatDate(thurs));
    sheet.getRange(2, columnIndex + i * 3).setValue("木");
    sheet.getRange(1, columnIndex + i * 3 + 1).setValue(formatDate(fri));
    sheet.getRange(2, columnIndex + i * 3 + 1).setValue("金");
    sheet.getRange(1, columnIndex + i * 3 + 2).setValue(formatDate(sat));
    sheet.getRange(2, columnIndex + i * 3 + 2).setValue("土");

    // 次の週へ
    thursday.setDate(thursday.getDate() + 7);
    friday.setDate(friday.getDate() + 7);
    saturday.setDate(saturday.getDate() + 7);
  }
}

// 日付のフォーマットを変更するヘルパー関数
function formatDate(date) {
  return Utilities.formatDate(date, "GMT", "yyyy/MM/dd");
}

出たコードがこれ.実際に動かすとこんな感じでカレンダーできた.

これで毎週決まった曜日にこれを実行すれば,R, S, T列に割り当てたい日付が来るので,ここで割り当てればよいという話になる.

3.祝日の取得

祝日シートを用意してGoogleカレンダーから祝日を取得し,コードを実行すれば更新してくれるようなのにした.コードを定期的に自動で実行させることは可能(例えば毎週月曜日10時とか)なので,これで,祝日は自動取得出来ることになる.

GASコードを書いて.
'祝日'シートの
A列に今日から2年後までの2本の祝日をGoogleカレンダーから取得するコードを書いて

このプロンプトで以下がでた.

function importHolidays() {
  // スプレッドシートと祝日シートを取得
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('祝日');
  sheet.clear();  // シートをクリア
  
  // 日本の祝日カレンダーのID
  var calendarId = 'japanese__ja@holiday.calendar.google.com';
  
  // 今日の日付と2年後の日付を設定
  var startDate = new Date();
  var endDate = new Date();
  endDate.setFullYear(startDate.getFullYear() + 2);
  
  // 指定した期間のカレンダーイベントを取得
  var calendar = CalendarApp.getCalendarById(calendarId);
  var events = calendar.getEvents(startDate, endDate);
  
  // イベントの日付とタイトルをシートに書き込み
  var holidays = events.map(function(event) {
    return [event.getStartTime(), event.getTitle()];
  });
  
  // シートに祝日の情報を書き込む
  if (holidays.length > 0) {
    sheet.getRange(1, 1, holidays.length, 2).setValues(holidays);
  }
}

動かしてみると

これは16行目がおかしいということ.これをchat GPTにコピペして以下のようにすると

TypeError: Cannot read properties of null (reading 'getEvents')
とでた
エラーメッセージ「TypeError: Cannot read properties of null (reading 'getEvents')」は、指定されたカレンダーIDに対応するカレンダーが見つからないか、アクセスできない場合に発生します。これを解決するために以下の点を確認してください:

カレンダーIDの確認:
カレンダーIDが正しいかどうか再度確認してください。特に、日本の祝日カレンダーを使用している場合、正しいIDが使用されているかをチェックする必要があります。日本の祝日カレンダーのIDは japanese__ja@holiday.calendar.google.com ですが、Google がIDを変更することもあり得るので、それも考慮してください。

GoogleカレンダーAPIの有効化:
Google Apps Scriptのエディタで「サービス」を開き、「+ サービスを追加」ボタンをクリックして、GoogleカレンダーAPI(Calendar API)がリストに含まれていることを確認し、有効にしてください。APIがリストになければ、それを追加してください。

権限の付与:
スクリプトを初めて実行する際に、Googleカレンダーへのアクセス権限をリクエストする承認画面が表示されます。この画面で「許可」を選択して、スクリプトがカレンダーデータへアクセスできるようにしてください。

カレンダーへのアクセス:
使用しているGoogleアカウントが該当するカレンダーにアクセス権を持っているかを確認してください。特に、組織内のカレンダーなど、アクセス制限がある場合はその点も考慮が必要です。

これらの確認を行い、それでも問題が解決しない場合は、エラーが発生している具体的な行やコンテキストを教えていただければ、さらに詳細なアドバイスを提供することができます。

カレンダーIDが怪しいとのこと.chat GPTはあてにならなそうなので,Googleで普通に調べる.

GPT4の提案してきたIDと異なるのでトライしてみる.ということで,このIDを入れてみると

function importHolidays() {
  // スプレッドシートと祝日シートを取得
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('祝日');
  sheet.clear();  // シートをクリア
  
  // 日本の祝日カレンダーのID
  var calendarId = "ja.japanese#holiday@group.v.calendar.google.com";
  
  // 今日の日付と2年後の日付を設定
  var startDate = new Date();
  var endDate = new Date();
  endDate.setFullYear(startDate.getFullYear() + 2);
  
  // 指定した期間のカレンダーイベントを取得
  var calendar = CalendarApp.getCalendarById(calendarId);
  var events = calendar.getEvents(startDate, endDate);
  
  // イベントの日付とタイトルをシートに書き込み
  var holidays = events.map(function(event) {
    return [event.getStartTime(), event.getTitle()];
  });
  
  // シートに祝日の情報を書き込む
  if (holidays.length > 0) {
    sheet.getRange(1, 1, holidays.length, 2).setValues(holidays);
  }
}

日本の祝日カレンダーの""で囲まれたところだけ変更して実行.できた.

こんな感じで,try & errorをしていく.こんな感じで,コードをひたすら書くだけでできる.
もし,僕が死んだり辞めたりした時に現在あるコードがわからないと困ると思うので,以後は,現在あるコードの説明,およびエラーが出たときに修正しやすいような話をしていく.

この記事が気に入ったらサポートをしてみませんか?