Excel の WORKDAY を、読んだ順に書き直す——締め日・支払日の年間表を作って、Excel に戻す

Kairos

1. 「翌月 1 日の 1 営業日前」と裏返して読む式

経理や総務の年間予定表には、月末最終営業日・支払日・第 10 営業日・四半期末の締めが並ぶ。Excel で作るなら WORKDAY と EOMONTH の出番で、月末最終営業日はこう書く:

=WORKDAY(EOMONTH(A2,0)+1,-1,祝日)

読み方は「A2 の月の末日の翌日、つまり翌月 1 日から、1 営業日戻る」。要件は「月末の最終営業日」なのに、式は翌月から裏返して読む。動くし、慣れれば読める。ただ、引き継いだ人が「なぜ +1 して -1 なのか」を一度は考えるし、1 セルに 1 月分なので、年の表にするには12 行にコピーする。祝日の範囲 祝日 が翌年分を含んでいなくても、式は黙って答えを返す。

この回は、同じ 4 本の要件を、要件を言う順に書く書き方で並べる。日付の一覧を作る係を Kairos に渡し、集計と見た目は Excel に残す。書き方の対照はExcel 対照レシピにまとめてあり、ここではその読み方と、Excel に戻すところまでを通す。

2. 4 本を、要件の順に書く

祝日表と営業日の列を 1 度だけ書き、4 本の式を並べる。holidays は 2026 年の祝日 18 日、bizDay は毎日から土日と祝日を引いた列:

# 経理の年間予定(月末最終営業日・25 日払い・第 10 営業日・四半期末の 3 営業日前)
premise JP {
  calendar-system: Gregorian
  tz: "Asia/Tokyo"
  wkst: Mon
}

@JP
holidays = [2026-01-01, 2026-01-12, 2026-02-11, 2026-02-23, 2026-03-20,
            2026-04-29, 2026-05-03, 2026-05-04, 2026-05-05, 2026-05-06,
            2026-07-20, 2026-08-11, 2026-09-21, 2026-09-22, 2026-09-23,
            2026-10-12, 2026-11-03, 2026-11-23] covering: 2026..2026
satSun = everyDay |> filter(d => weekday(d) == Sat or weekday(d) == Sun)
bizDay = everyDay \ (satSun | holidays)

bizDay |> within(month) |> last
everyDay |> within(month) |> nth(25) |> roll(Preceding, on: bizDay)
bizDay |> within(month) |> nth(10)
bizDay |> within(quarter) |> last |> shift(-3, unit: bizDay)

それぞれの Excel 式と読み方:

  • 月末最終営業日。Excel は =WORKDAY(EOMONTH(A2,0)+1,-1,祝日)(翌月 1 日の 1 営業日前)。Kairos は bizDay |> within(month) |> last——営業日の列を月で区切って、最後の点。
  • 25 日払い・休みなら前営業日。Excel は =WORKDAY(DATE(YEAR(A2),MONTH(A2),26),-1,祝日)(26 日の 1 営業日前)。Kairos は everyDay |> within(month) |> nth(25) |> roll(Preceding, on: bizDay)——毎月 25 日を作り、営業日でなければ手前に寄せる。
  • 第 10 営業日。Excel は =WORKDAY(EOMONTH(A2,-1),10,祝日)(前月末の 10 営業日後)。Kairos は bizDay |> within(month) |> nth(10)——営業日の列を月で区切って、10 番目。
  • 四半期末の 3 営業日前。Excel は =WORKDAY(EOMONTH(A2,2)+1,-4,祝日)(翌四半期 1 日の 4 営業日前)。Kairos は bizDay |> within(quarter) |> last |> shift(-3, unit: bizDay)——四半期の最終営業日から、営業日の目盛りで 3 つ戻る。

|> は「左の列を右の操作に渡す」の印で、左から右へ読む。roll が「寄せる」、shift が「数える」で、別の操作である(roll と shift の回)。2026 年の 1 年分を一度に聞く:

$ kairos list --from 2026-01-01 --to 2027-01-01 --tz Asia/Tokyo keiri.kairos
# 式 1(12 件)
2026-01-30
2026-02-27
2026-03-31
2026-04-30
2026-05-29
2026-06-30
2026-07-31
2026-08-31
2026-09-30
2026-10-30
2026-11-30
2026-12-31
# 式 2(12 件)
2026-01-23
2026-02-25
2026-03-25
2026-04-24
2026-05-25
2026-06-25
2026-07-24
2026-08-25
2026-09-25
2026-10-23
2026-11-25
2026-12-25
# ⚠ 範囲外 2026-01-01..2026-01-02(holidays covering 2026-01-01..2026-12-31)
# 式 3(12 件)
2026-01-16
2026-02-16
2026-03-13
2026-04-14
2026-05-19
2026-06-12
2026-07-14
2026-08-17
2026-09-14
2026-10-15
2026-11-16
2026-12-14
# 式 4(4 件)
2026-03-26
2026-06-25
2026-09-25
2026-12-28
# ⚠ 範囲外 2026-12-29..2027-01-01(holidays covering 2026-01-01..2026-12-31)
# 被覆サマリ
#   holidays covering 2026-01-01..2026-12-31 残走路 0 日

1 月末(1/31 土)と 5 月末(5/30 土)が金曜に退き、1 月 25 日(日)の支払いは 23 日(金)に、第 10 営業日は成人の日(1/12)と連休を数えに入れずに 1/16・5/19 になった。12 行コピーも、月ごとの手直しもない。

⚠ の 2 行は、祝日表が 2026 年分しかないことから来る。式 2 の「2026-01-01..2026-01-02」は 1 月 1 日だけ(右端を含まない)で、「1 月 1 日に点が落ちたら手前の営業日は 2025 年の表に依存する」という知らせ。式 4 の「12-29..01-01」は、2027 年の表が無いという知らせが3 営業日戻る算術と一緒に 12 月 29〜31 日へ移ってきたもので、12/28 の点そのものは正しい。表の外では黙らない、という話は第 34 弾と第 36 弾にある。

3. 数え方の罠——4 と 3

四半期末の 3 営業日前は、Excel と Kairos で数が違う。Excel は「翌四半期 1 日から 4 つ戻る」で -4、Kairos は「最終営業日から 3 つ戻る」で -3。どちらも 12/28 に着く:

図 1: 2026 年 12 月 21 日から 2027 年 1 月 6 日までの 17 日を数直線に並べ、営業日 12 日に点を打つ。土日は灰、1 月 1 日の元日は赤。上の段は Excel の WORKDAY(DATE(2027,1,1), -4, 祝日) で、1 月 1 日から営業日を 4 つ戻って 12 月 28 日に着く。下の段は Kairos の bizDay |> within(quarter) |> last |> shift(-3, unit: bizDay) で、最終営業日の 12 月 31 日から営業日を 3 つ戻って同じ 12 月 28 日に着く(2026-10-21 図を追加)
図 1: 2026 年 12 月 21 日から 2027 年 1 月 6 日までの 17 日を数直線に並べ、営業日 12 日に点を打つ。土日は灰、1 月 1 日の元日は赤。上の段は Excel の WORKDAY(DATE(2027,1,1), -4, 祝日) で、1 月 1 日から営業日を 4 つ戻って 12 月 28 日に着く。下の段は Kairos の bizDay |> within(quarter) |> last |> shift(-3, unit: bizDay) で、最終営業日の 12 月 31 日から営業日を 3 つ戻って同じ 12 月 28 日に着く(2026-10-21 図を追加)

Excel で -4 を -3 と書くと 12/29 になり、セルは黙って 12/29 を表示する。要件の「3」と式の「4」が違うので、確かめるには一度カレンダーを数え直すしかない。Kairos で -3 を -2 と書いても 12/29 だが、式が「最終営業日から 2 つ戻る」と読めるので、数と言葉が一致している。間違えないのではなく、間違いが読める。

4. Excel に戻す

--tsv で、1 点 1 行のタブ区切りに書き出す。註釈と被覆サマリは画面(標準エラー)に出て、ファイルには混ざらない:

$ kairos list --tsv --from 2026-01-01 --to 2027-01-01 --tz Asia/Tokyo keiri.kairos > keiri.tsv
# 式 1(12 件)
# 式 2(12 件)
# ⚠ 範囲外 2026-01-01..2026-01-02(holidays covering 2026-01-01..2026-12-31)
# 式 3(12 件)
# 式 4(4 件)
# ⚠ 範囲外 2026-12-29..2027-01-01(holidays covering 2026-01-01..2026-12-31)
# 被覆サマリ
#   holidays covering 2026-01-01..2026-12-31 残走路 0 日
$ cut -f 1,2,4,7 keiri.tsv | head -3
expr	source	date	note
1	bizDay |> within(month) |> last	2026-01-30	
1	bizDay |> within(month) |> last	2026-02-27	

見出し 1 行と 40 行(12 + 12 + 12 + 4)。expr 列が式の番号なので、1 つのファイルから 4 つの表が切り出せる。note 列は、その点が「表の外」の区間に入るときだけ註釈文が入る。空なら表の内側の計算である。列はほかに uid・time・epoch_ms・label があり、label は表に名前を付けたときに入る(前回)。この例では空。

Excel では、ファイルをダブルクリックせず「データ → テキストまたは CSV から」で開き、文字コードに UTF-8、区切り記号にタブを選ぶ。date は日付型で入るので、そのまま VLOOKUP や条件付き書式の材料になる。PowerShell なら`Import-Csv keiri.tsv -Delimiter "t” -Encoding utf8“。Windows での導入は Windows 管理者のための Kairosにあり、インストールなしで動く単体の exe も配布している。

5. 置き換えではない——日付の一覧係と、集計の係

  • Kairos は Excel を置き換えない。日付の一覧を作る係を Kairos に、集計・突き合わせ・見た目を Excel に。WORKDAY の式を全部消す話ではなく、年間表の「日付列」を定義から出す話である。
  • 祝日の正は内閣府「国民の祝日について」。毎年 2 月に翌年分が公示される。式は表を読むだけで、祝日を決めない。
  • 営業日の定義は会社で違う。土曜出勤がある、創立記念日が休み、年末年始が長い——その違いは holidays の行と satSun の式に書く。レシピの @JP 標準前提は土日と国民の祝日だけの最小形で、ここから足す。

6. 落とし穴

  • 祝日表の範囲。WORKDAY の 3 つ目の引数が 2026 年分で止まっていても、2027 年の日付を計算すれば祝日ゼロとして答えを返す。1 月 1 日が営業日になる。Kairos では covering: の外を聞くと ⚠ と残走路のマイナスが出る(祝日表は黙って腐る)。表を延ばすのは、行を足して covering: を 1 年延ばすだけ。式は触らない。
  • --tz を書かない。機械のタイムゾーンで印字され、日付に時刻が付くことがある。定義の tz と揃える。
  • コピーの運用。Excel の式を 12 行コピーする運用は、1 行だけ直して他を直し忘れる事故が起きる。Kairos は式が 1 本なので、直す場所が 1 つになる。
  • 「3 営業日ごと」「第 1・第 3 水曜」。Excel では作業列や WEEKDAY の式が要る型で、レシピに書き方がある。「月 2 回」は第 31 弾。

7. 動かす

年間表の生成はコマンド 1 本なので、月末最終営業日の自動実行まで通すの型がそのまま使える。毎朝「今日は支払日か」を聞く判定も、同じ定義ファイルで動く。年に 1 回の表の生成と、日々の判定で、書く場所が 1 つになる。

まとめ

  • WORKDAY の式は「翌月 1 日の 1 営業日前」と裏返して読む。Kairos は bizDay |> within(month) |> last と、要件の順に書く
  • 4 本の要件を 1 ファイルに並べ、--from・--to で 1 年分を 1 回で出す。12 行コピーはない
  • 四半期末の 3 営業日前は、Excel が -4、Kairos が -3。間違えても Excel は黙り、Kairos は式が読める
  • --tsv で Excel に戻す。expr 列で表を切り分け、note 列が空なら表の内側
  • Kairos は日付の一覧係、Excel は集計の係。祝日の正は内閣府で、式は表を読むだけ

▶ Playground で定義を実行する——2026 年の月末最終営業日 12 点が出る。コメントにある他の 3 本と最後の行を入れ替えて試せる。ブラウザ内で完結し、何も送信しない。


Kairos はスケジュール定義言語です——決めたら、いつでも。仕様と参照実装はGitHub で公開しています。

コメント

タイトルとURLをコピーしました