ジャーナルクラブ,レクチャー割り当て解説 その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は各自に入れてもらうようにすればいい.そのリマインドコードについては後述.
この記事が気に入ったらサポートをしてみませんか?