Outlookを使うと、本当にGoogleカレンダーは使いやすいなと惚れ惚れする。
とはいえ、Googleカレンダーにも細かい不満がないわけではない。
その一つが、繰り返し予定で「毎月第1営業日」という指定ができない事だ。
例えば会社員なら、毎月第1営業日に勤怠を締めたり、前月の売上を報告したり、請求書を処理したりといった定例業務があるだろう。
この手の繰り返し系はToDoアプリなんかで別管理している人もいるだろうが、会社で使えるツールが限られていたり、そもそも複数のサービスを使いたくない人はとりあえずカレンダーに放り込んでいる人も多いと思う。
Googleカレンダーには「毎月1日」「毎月第1月曜日」などの繰り返し設定はあるが、「土日祝日を除いた最初の営業日」という設定はできない。
これまでは妥協して毎月1日に予定を入れ、土日祝日と重なった月だけ手動でドラッグして変更していた。
大した手間ではない。
ただ、この「大した手間ではない」が厄介なのだ。
月に1回だからこそ忘れるし、たまにしか発生しない例外処理ほど自動化したくなる。
そこで、Google Apps Script(GAS)を使い、毎月第1営業日に自動で予定が入る仕組みを作ってみた。
JavaScriptで書く必要はあるが、今やAIにコードを書いてもらえる時代。非エンジニアでも十分実現できる。
一度設定すれば、あとは基本的に放置でよい。
今チェックしておきたいキャンペーン・特価情報
※内容・適用条件・開催期間はリンク先をご確認ください。
Googleカレンダー標準の繰り返し設定では対応できない
Googleカレンダーには、予定を定期的に繰り返す機能がある。
毎日、毎週、毎月、毎年といった設定のほか、「毎月第1月曜日」のような指定も可能だ。
しかし、「毎月第1営業日」は別の話だ。
例えば、月初が以下のような場合を考えてみよう。
-
1日が月曜日で祝日ではない → 1日に予定を入れる
-
1日が土曜日 → 3日以降の最初の平日に入れる
-
1日が日曜日 → 翌日の月曜日に入れる
-
1日が祝日 → 祝日明けの営業日に入れる
-
1日から連休が続く → 連休明けの営業日に入れる
曜日だけでなく、日本の祝日まで考慮する必要がある。
例えば2025年11月は1日が土曜日かつ、2日は日曜、3日は文化の日のため、第1営業日は11月4日(火)になる。
毎月1日にセットしている予定が、2日なら1週間予定表で隣に表示されるのでまだ見落とす事も少ないが、4日ともなると忘れてしまいそうだ。
こうした営業日判定をGoogleカレンダーの標準機能だけで実現することはできない。
しかし、GASなら簡単な条件分岐で対応できる。
GASで毎月第1営業日に予定を自動登録する
今回作るのは、次のような仕組みだ。
毎月25日になるとGASが自動実行され、翌月の第1営業日を計算。そして、Googleカレンダーに「勤怠締め作業」という予定を9時から10時まで登録する。
もし1日が土日や祝日なら、翌日、さらに翌日と日付を進め、最初の営業日を探す。
一度登録した予定は、同じスクリプトを再実行しても重複しないようにしておく。
事前準備:日本の祝日カレンダーを登録する
まずは、GASが日本の祝日を判定できるようにしておく。
今回はGoogleが公開している「日本の祝日」のうち、祝日のみを収録したカレンダーを利用する。
Googleカレンダーの設定から「カレンダーを追加」→「カレンダーに登録」を開き、次のカレンダーIDを登録する。
ja.japanese.official#holiday@group.v.calendar.google.com
ここは少し注意が必要だ。
以前から使われている次のIDでも、日本の祝日を取得できる。
ja.japanese#holiday@group.v.calendar.google.com
しかし、Googleの仕様変更によって、こちらには節分、七夕、クリスマスなど、国民の祝日ではない行事まで含まれるようになった。
そのため、予定が1件でもあれば祝日と判定する単純なプログラムでは、平日なのに休日扱いしてしまう可能性がある。
今回はこの問題を避けるため、「祝日のみ」のカレンダーを利用する。
なお、「祝日のみ」にも銀行休業日などが含まれる場合があるため、厳密な法定休日の判定とは異なる。ただ、一般的な会社の営業日を判定する用途では、むしろ都合がよい場合もある。
コピペで使えるGASコード
Google Apps Script を開き、「新しいプロジェクト」を作成する。
標準で表示されるコードを削除し、以下を貼り付ければよい。
const HOLIDAY_CALENDAR_ID =
'ja.japanese.official#holiday@group.v.calendar.google.com';
function createFirstBusinessDayEvent() {
const calendar = CalendarApp.getDefaultCalendar();
const holidayCalendar =
CalendarApp.getCalendarById(HOLIDAY_CALENDAR_ID);
// 祝日カレンダーが取得できなければ処理を中止
if (!holidayCalendar) {
throw new Error(
'日本の祝日カレンダーを登録してください。'
);
}
const title = '勤怠締め作業';
// 翌月1日の9時を取得
const now = new Date();
const targetDate = new Date(
now.getFullYear(),
now.getMonth() + 1,
1, 9, 0, 0
);
// 土日祝日なら翌日に進める
while (isNonBusinessDay(targetDate, holidayCalendar)) {
targetDate.setDate(targetDate.getDate() + 1);
}
// 終了時刻は10時
const endTime = new Date(targetDate);
endTime.setHours(10, 0, 0, 0);
// 同じ日時・タイトルの予定があれば追加しない
const alreadyExists = calendar
.getEventsForDay(targetDate)
.some(event =>
event.getTitle() === title &&
event.getStartTime().getTime() === targetDate.getTime()
);
if (alreadyExists) {
console.log('予定は登録済みです');
return;
}
// Googleカレンダーに予定を追加
calendar.createEvent(title, targetDate, endTime, {
description: 'GASで自動登録した第1営業日の予定'
});
console.log('予定を登録しました:' + targetDate);
}
// 土日・祝日を判定する
function isNonBusinessDay(date, holidayCalendar) {
const day = date.getDay();
// 日曜日または土曜日
if (day === 0 || day === 6) {
return true;
}
// 日本の祝日カレンダーに予定があれば休日
return holidayCalendar.getEventsForDay(date).length > 0;
}
コードが長く見えるかもしれないが、やっている事は単純だ。
まず翌月1日を取得し、その日が休日なら翌日にずらす。
平日で、なおかつ祝日カレンダーにも予定がなければ、その日を営業日と判定する。
あとは、その日の9時から10時に予定を作成するだけである。
なお、登録先はGASを実行するGoogleアカウントのメインカレンダーとなる。別のカレンダーに登録したい場合は、getDefaultCalendar() の部分を変更すればよい。
また、プロジェクトのタイムゾーンは「Asia/Tokyo」に設定しておこう。
最初に一度だけ手動実行する
コードを保存したら、画面上部の関数選択欄で createFirstBusinessDayEvent を選択し、「実行」をクリックする。
初回はGoogleカレンダーへのアクセス許可を求められるので、内容を確認して承認する。
実行が成功すると、翌月の第1営業日の9時から10時に「勤怠締め作業」という予定が作成される。
Googleカレンダーで実際に予定が入っているか確認してみよう。
なお、もう一度実行しても、同じタイトル・開始日時の予定が既に存在すれば追加しないようにしている。
これで、テスト実行によって同じ予定が何件も増える問題も回避できる。
毎月25日に自動実行するトリガーを設定する
ここまでできれば、あとは自動実行の設定だけだ。
GASには「トリガー」という機能があり、指定した日時や条件でスクリプトを実行できる。
設定方法は以下のとおり。
-
GASの画面左側にある「トリガー」(時計のアイコン)をクリック
-
「トリガーを追加」をクリック
-
実行する関数に
createFirstBusinessDayEventを指定 -
イベントのソースは「時間主導型」を選択
-
時間ベースのトリガーは「月ベースのタイマー」を選択
-
実行する日付は「25日」を選択
-
実行する時間帯を選び、保存する
これで毎月25日になると、翌月の第1営業日に予定を作成してくれる。
なぜ25日なのかというと、翌月の予定を月末までに用意しておきたいからだ。
実際には20日でも月末でも構わない。ただし、月初の予定を登録するので、前月中に実行する必要がある。
また、GASの時間主導型トリガーは、指定した時間帯の中で実行時刻に多少の幅がある。今回のように翌月の予定を事前に登録する用途なら、特に問題はない。
これで毎月の手作業が一つ消えた。
応用編:休日なら「前営業日」にずらす
今回のプログラムは、休日に当たった予定を後ろ倒しにする仕組みだ。
しかし、業務によっては逆に前倒ししたいケースもあるだろう。
例えば、会社の独自ルールとして「会社創立記念日や祝日が土・日・祝と重なったら、その前営業日を休日にする」とかという制度がある場合だ。
こうした処理も、GASなら簡単に実現できる。
先ほどのコードでは、次の部分で日付を1日ずつ進めていた。
while (isNonBusinessDay(targetDate, holidayCalendar)) {
targetDate.setDate(targetDate.getDate() + 1);
}
これを、次のように変更する。
while (isNonBusinessDay(targetDate, holidayCalendar)) {
targetDate.setDate(targetDate.getDate() - 1);
}
違いは + 1 を - 1 にしただけ。
これだけで、土日祝日に当たった予定を直前の営業日まで遡らせる処理になる。
もちろん、創立記念日の振替ルールは会社ごとに異なる。法律上の振替休日が必ず前営業日になるという意味ではなく、あくまで会社独自のルールを再現する例である。
例えば「毎月末の最終営業日に請求書チェックを行う」という用途なら、翌月1日から前営業日へ戻すことで簡単に実現できる。
翌営業日への繰り越しだけでなく、前営業日への前倒しにも対応できるのは便利だ。
注意点:会社独自の休業日までは判定できない
ここまでの仕組みで、土日と日本の祝日には対応できる。
ただし、会社独自の休日は別問題だ。
例えば、
-
創立記念日
-
夏季休業
-
年末年始の会社指定休日
-
全社一斉休業日
こうした日付は、Googleの祝日カレンダーだけでは正しく判定できない。
厳密な「自社の第1営業日」を求めるのであれば、会社独自の休業日を登録した専用カレンダーを作り、その予定も参照して判定する仕組みにするとよい。
例えば「会社休日」というカレンダーを用意しておけば、総務や人事が休日を追加するだけで、GAS側の営業日判定にも反映できる。
毎年スクリプトを書き換えるより、こちらの方が管理しやすいだろう。
また、祝日カレンダーの仕様や会社の休日は変更される可能性がある。自動登録された予定が実際の営業日と一致しているか、特に年始などは確認しておきたい。
今回の仕組みは予定を自動登録するものであり、後から祝日が変更された場合に、登録済みの予定を自動で移動するものではない点にも注意が必要だ。
まとめ:小さな手間ほどGASに任せたい
毎月第1営業日に予定を登録する。
やっている事は地味だし、手動で変更したとしても月に数十秒程度の作業だろう。
しかし、こうした「たまに発生する面倒な作業」は意外と厄介である。
毎月1日に予定を入れておけばいいじゃないかと思っても、月初が連休に重なったときに修正を忘れる。
そして、いざその日になってから「あ、勤怠締めなきゃ」となる。
今回のGASは、そういう小さな問題を解決するための仕組みだ。
何より、JavaScriptが書けなくても、AIに「Googleカレンダーに毎月第1営業日の予定を入れたい。祝日も考慮して」と依頼すれば、こうしたコードを作れる時代になった。
必要なのは、プログラミング能力そのものよりも「この作業、自動化できるんじゃないか?」と気づくことなのかもしれない。
Googleカレンダーが標準機能で対応してくれるのが一番ではあるが、ないものは仕方ない。
自分で作ってしまおう。
一度設定すれば、毎月の勤怠締め作業を忘れずに済む。
……まぁ、私は予定に入れていても、やり忘れるタイプなんだけど。



コメント