ジャーナルクラブ,レクチャー割り当て解説 その1


これを上から順に説明していく.

最終実行コード

function finalcode() {
  fetchJapaneseHolidaysAndSaveToSheet();//祝日取得,4月第1週,年末年始特別休暇入力
  moveUnmatchedAndFutureTitlesToHolidays();//未来にイベント入っていたら,それを祝日に入れてしまう
  updateNames();//メンバー更新
    updateNamesforlastdays();//最終日の日付消去判定と実行
    updateNamesfortemporarylastdays();//院外研修者の日付消去判定と実行
  importSpecifiedWeekendsToSheetHorizontal();//カレンダー更新,0入力
  importJCandLectureToSheet();//カレンダーからレクチャー実績を取得
  updateDatesJCandLectureDateautomationversion();//レクチャー実績から最終JC,レクチャー日を取得(検索文字列:抄読会 名前, 朝担当 名前)
    transferstaffdoctorlastDates();//常勤医の最終日を割り当て表に移動
  updateCalendarWithZero();//ローテーターの期間以外のところに0入力
  importEventsToSheet()//リフ休や出張を取得
  update0ofrefreshholidayAssignmentSheet();//リフ休から0を割り当て表に入力
  updateGoodbyeDatesToSheet();//サヨナラレクチャー実績取得
  ByeByeLectureAssignment();//サヨナラレクチャーを割り当てる
  updateColumnsWithZeros();//さよならレクチャー以後に0を入れる
  inputJCorLC();//JCとLCを割り当て
  assign1forJC();//JCに1を割り当て
  assign10forLC();//LCに10を割り当て
  addEventsToCalendar();//カレンダーへ飛ばす
  }

それぞれのコードを書いて,この順番で実行すれば割り当てできるという様な最終コード.
//を入れると,コードの外になるので,説明を加えられる.それでおおよその説明はしている.

function createWeeklyTrigger() {
  // 既存のトリガーを削除
  var existingTriggers = ScriptApp.getProjectTriggers();
  for (var i = 0; i < existingTriggers.length; i++) {
    if (existingTriggers[i].getHandlerFunction() === 'finalcode') {
      ScriptApp.deleteTrigger(existingTriggers[i]);
    }
  }

  // 毎週水曜日の9時に実行する新しいトリガーを作成
  ScriptApp.newTrigger('finalcode')
    .timeBased()
    .onWeekDay(ScriptApp.WeekDay.WEDNESDAY)
    .atHour(9)
    .create();
}

これは必ずしも必要ではないが,毎週水曜日9時にfinalcodeを実行するためのトリガーを作るためのコード

トリガーは手動でも作ることができるが,勤務表割り当てなどで,他の人にやって貰う場合は,トリガー自体もコードに含んでおかないとGAS自体知らない人には何もできなくなってしまうのでこれも必要.

以下が,手動でのやり方.

トリガーを選択
トリガーを追加を選択

関数は自分で選ぶ.
デプロイは無視.
時間主導型がよく使うと思う.後は,毎日とか毎週とか適当に選ぶだけ.

祝日取得

function fetchJapaneseHolidaysAndSaveToSheet() {
  var calendarId = "ja.japanese#holiday@group.v.calendar.google.com";
  
  // 今日の日付を基準に、前後1年間の期間を設定
  var today = new Date();
  var startDate = new Date(today.getFullYear() - 1, today.getMonth(), today.getDate());
  var endDate = new Date(today.getFullYear() + 1, today.getMonth(), today.getDate());

  // 指定された期間のイベントを取得
  var events = CalendarApp.getCalendarById(calendarId).getEvents(startDate, endDate);

  var holidays = [];
  for (var i = 0; i < events.length; i++) {
    var event = events[i];
    var date = event.getStartTime();
    var dayOfWeek = ["日", "月", "火", "水", "木", "金", "土"][date.getDay()];
    holidays.push([Utilities.formatDate(date, Session.getScriptTimeZone(), "yyyy-MM-dd"), event.getTitle(), dayOfWeek]);
  }

  // 特別休暇を追加するための日付の計算
  // 今年、昨年、来年の特定の日付を追加
  var years = [today.getFullYear() - 1, today.getFullYear(), today.getFullYear() + 1];
  years.forEach(function(year) {
    // 4月1日から7日まで
    for (var day = 1; day <= 7; day++) {
      holidays.push([Utilities.formatDate(new Date(year, 3, day), Session.getScriptTimeZone(), "yyyy-MM-dd"), "特別休暇", ""]);
    }

    // 12月30日、31日
    holidays.push([Utilities.formatDate(new Date(year, 11, 30), Session.getScriptTimeZone(), "yyyy-MM-dd"), "特別休暇", ""]);
    holidays.push([Utilities.formatDate(new Date(year, 11, 31), Session.getScriptTimeZone(), "yyyy-MM-dd"), "特別休暇", ""]);

    // 翌年の1月1日から3日まで
    holidays.push([Utilities.formatDate(new Date(year + 1, 0, 1), Session.getScriptTimeZone(), "yyyy-MM-dd"), "特別休暇", ""]);
    holidays.push([Utilities.formatDate(new Date(year + 1, 0, 2), Session.getScriptTimeZone(), "yyyy-MM-dd"), "特別休暇", ""]);
    holidays.push([Utilities.formatDate(new Date(year + 1, 0, 3), Session.getScriptTimeZone(), "yyyy-MM-dd"), "特別休暇", ""]);
  });

  // '祝日' という名前のシートを取得、または新規作成
  var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = spreadsheet.getSheetByName('祝日');
  if (!sheet) {
    sheet = spreadsheet.insertSheet('祝日');
  }

  // シートをクリアして新しいデータを出力
  sheet.clear();
  sheet.appendRow(['Date', 'Holiday Name', 'Day of the Week']);
  // 曜日の計算を行う
  holidays = holidays.map(function(holiday) {
    var date = new Date(holiday[0]);
    var dayOfWeek = ["日", "月", "火", "水", "木", "金", "土"][date.getDay()];
    return [holiday[0], holiday[1], dayOfWeek];
  });
  sheet.getRange(2, 1, holidays.length, 3).setValues(holidays);
}

既に説明した通り.
4月の1-7日までと12月30日から1月3日までは祝日にかかわらず割り当てないので,祝日に書き込むようにしている.

メンバーリストの取得とメンバーの最終レクチャー日の取得

公休日というシートを用意している

割り当てを行うメンバー表を,勤務表から転送している.なので,転送のためのコードは勤務表に入っている.
例えば4月の勤務表からメンバーを転送して,8週間後の6月の割り当てしている.6月はメンバーが変わっているのではないかという問題があるが,実はちょうどいい.
6月までに辞める,あるいは外病院行く時期は各自入力してもらうようにしておいて,割り当てないようにしておき,かつ,5月からくる人は名前はないが,来てすぐだから6月に割り当てないのはむしろちょうどよい.

勤務表のライブラリのコード.公休日を・・・でチーム体制のメンバー表などを転送している

A列に短縮名,B列に公休日,C列にフルネームを転送している.

秘書さんが作成しているメンバー表と名前の一致するものがあれば,その入職と退職時期,後期研修医以上かどうかの判定をD列,E列,F列に転送.

他院から回ってくるローテーターも秘書さんが作成しているので同様に入職,退職,後期研修医以上かの判定をC, D, E列に転送.

これらを,
毎週月曜日:勤務表からメンバーリストをA, B, C列に転送
毎週火曜日:その名前を利用して,入退職時期,後期研修医判定をD, E列に転送.

これで,メンバーリストと公休日,入退職時期,後期研修医以上かどうかの状況の最新状況がわかるシートが作成できた.

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

これで,1, 2, 3, 5は出来たし,7は各自に入れてもらうようにすればいい.そのリマインドコードについては後述.

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