VBAで祝日を含めた年間予定表を自動生成する方法|Dictionary・色分け・InputBoxで年指定

VBAで祝日を含めた年間予定表を自動生成するには、祝日一覧をDictionaryに読み込んでおき、1月1日から12月31日をループしながら「平日・土日・祝日」を判定して書き出します。毎年手作業でカレンダーを作り直す手間がなくなり、祝日の判定ミスも防げます。

この記事では、次の内容を順番に解説します。

  • 祝日シートの準備と読み込み方
  • 年間予定表を自動生成する基本コード
  • 土日・祝日に背景色をつける書式設定コード
  • 対象年をInputBoxで指定できるようにする方法
  • よくある質問(祝日の取得先・振替休日の扱い・翌年への流用等)

祝日シートの準備と読み込み方を理解するには?

Excelには祝日を自動判定する機能がないため、あらかじめ「祝日」シートに日付一覧を用意しておく必要があります。A列に日付だけをシンプルに入力してください。

A列(祝日の日付)
2026/01/01
2026/01/12
2026/02/11
(以下続く)

祝日データは内閣府の祝日一覧(https://www8.cao.go.jp/chosei/shukujitsu/gaiyou.html)からCSVで取得できます。毎年更新されるため、年初に最新版を確認して「祝日」シートに貼り付けておくのがおすすめです。

この祝日シートをDictionaryに読み込む処理は次の通りです。

' 祝日シートからDictionaryに登録する
Dim dict As Object
Dim holidaySh As Worksheet
Dim i As Long

Set dict = CreateObject("Scripting.Dictionary")
Set holidaySh = Worksheets("祝日")

i = 1
Do While holidaySh.Cells(i, 1).Value <> ""
    dict.Add Format(holidaySh.Cells(i, 1).Value, "yyyy/mm/dd"), True
    i = i + 1
Loop

日付を Format(..., "yyyy/mm/dd") で文字列に統一しているのがポイントです。後でループ内の日付と照合する際も同じ形式で変換するため、確実に一致判定できます。

年間予定表を自動生成する基本コードを理解するには?

Sub MakeYearlySchedule()

    Dim ws         As Worksheet
    Dim holidaySh  As Worksheet
    Dim dict       As Object
    Dim d          As Date
    Dim i          As Long
    Dim rowNum     As Long
    Dim yearVal    As Integer
    Dim kubun      As String

    yearVal = Year(Date)  ' 今年を対象にする

    ' 出力シートをリセット
    Application.DisplayAlerts = False
    On Error Resume Next
    Worksheets("年間予定表").Delete
    On Error GoTo 0
    Application.DisplayAlerts = True

    Set ws = Worksheets.Add
    ws.Name = "年間予定表"

    ' 祝日をDictionaryに読み込む
    Set dict = CreateObject("Scripting.Dictionary")
    Set holidaySh = Worksheets("祝日")

    i = 1
    Do While holidaySh.Cells(i, 1).Value <> ""
        dict.Add Format(holidaySh.Cells(i, 1).Value, "yyyy/mm/dd"), True
        i = i + 1
    Loop

    ' ヘッダー
    ws.Range("A1:D1").Value = Array("日付", "曜日", "区分", "備考")
    ws.Range("A1:D1").Font.Bold = True

    ' 1月1日〜12月31日をループ
    rowNum = 2
    For d = DateSerial(yearVal, 1, 1) To DateSerial(yearVal, 12, 31)

        ws.Cells(rowNum, 1).Value = d
        ws.Cells(rowNum, 1).NumberFormatLocal = "yyyy/m/d"
        ws.Cells(rowNum, 2).Value = Format(d, "aaa")  ' 月〜日(日本語曜日)

        ' 区分を判定
        If dict.exists(Format(d, "yyyy/mm/dd")) Then
            kubun = "祝日"
        ElseIf Weekday(d, vbSunday) = 1 Then
            kubun = "日曜"
        ElseIf Weekday(d, vbSunday) = 7 Then
            kubun = "土曜"
        Else
            kubun = "平日"
        End If

        ws.Cells(rowNum, 3).Value = kubun
        rowNum = rowNum + 1

    Next d

    ws.Columns("A:D").AutoFit
    MsgBox yearVal & "年の年間予定表を作成しました(" & (rowNum - 2) & "行)。", vbInformation, "完了"

End Sub

このコードのポイントは次の通りです。

  • Format(d, "aaa") で「月」「火」「水」など日本語の短縮曜日が取得できる
  • 祝日の判定を土日より先に行うことで、祝日が土曜に重なった場合でも「祝日」と表示される
  • DateSerial(yearVal, 1, 1) To DateSerial(yearVal, 12, 31) でその年の全日付をループする
  • 出力シートを毎回削除・再作成するため、何度実行しても正しい状態になる

土日・祝日に背景色をつけるには?

区分の判定後に背景色を設定することで、一覧の視認性が大きく上がります。

' 区分に応じて背景色を設定する(上記ループ内の「ws.Cells(rowNum, 3).Value = kubun」の後に追加)
Select Case kubun
    Case "祝日"
        ws.Rows(rowNum).Interior.Color = RGB(255, 199, 206)  ' 薄い赤
    Case "日曜"
        ws.Rows(rowNum).Interior.Color = RGB(255, 230, 230)  ' 淡い赤
    Case "土曜"
        ws.Rows(rowNum).Interior.Color = RGB(221, 235, 247)  ' 淡い青
End Select

祝日を土日より目立たせたい場合は、祝日の色を少し濃くするか太字にするとわかりやすくなります。

対象年をInputBoxで指定できるようにするには?

来年・再来年の予定表を先に作りたい場合など、年を指定して実行できるようにする方法です。

' yearVal = Year(Date) の代わりに使う
Dim input As String
input = InputBox("対象年を入力してください(例:2027)", "年間予定表", Year(Date))

If input = "" Or Not IsNumeric(input) Then
    MsgBox "キャンセルされました。", vbInformation
    Exit Sub
End If

yearVal = CInt(input)

これにより、コードを変更せずに任意の年の予定表を生成できます。祝日シートに対象年の祝日データが入っていることを確認してから実行してください。

まとめ

  • 祝日判定には 「祝日」シートへの事前入力+Dictionary読み込み が必要
  • 曜日取得は Format(d, "aaa") で日本語短縮曜日(月〜日)が取得できる
  • 祝日・土日・平日の判定順は 祝日を最初に判定 することで重複を避ける
  • 背景色は Select Case kubun で区分ごとに設定する
  • 対象年を InputBox で入力できると翌年以降もコード変更不要で使い回せる

よくある質問

祝日データはどこから取得すればいい?

内閣府の「国民の祝日について」のページ(https://www8.cao.go.jp/chosei/shukujitsu/gaiyou.html)で毎年更新されるCSVファイルが公開されています。このCSVをExcelで開き、日付列を「祝日」シートのA列に貼り付けるだけで準備完了です。振替休日もこのCSVに含まれているため、別途対応する必要はありません。

振替休日は自動で判定できない?

Excelには振替休日を自動計算する機能がないため、VBAだけでは判定できません。ただし、内閣府のCSVには振替休日も「休日」として記載されているため、そのデータをそのまま「祝日」シートに取り込めば問題なく対応できます。

翌年の予定表を今年中に作りたい場合は?

InputBoxで年を指定する方法(上記「対象年をInputBoxで指定」参照)を使えば、翌年の年を入力するだけです。ただし「祝日」シートに翌年分の祝日データが入っていないと祝日が判定されないため、内閣府サイトで翌年分が公開され次第、シートを更新してください。

祝日名(元日・成人の日など)も表示したい場合は?

「祝日」シートにB列として祝日名を追加しておき、DictionaryのAddの第2引数にTrueの代わりに祝日名を入れることで取得できます。

' B列に祝日名が入っている場合
dict.Add Format(holidaySh.Cells(i, 1).Value, "yyyy/mm/dd"), holidaySh.Cells(i, 2).Value

' ループ内で名前を取得する
If dict.exists(Format(d, "yyyy/mm/dd")) Then
    ws.Cells(rowNum, 4).Value = dict(Format(d, "yyyy/mm/dd"))  ' D列に祝日名を出力
End If

月ごとに別シートに分けて出力したい場合は?

ループ内で月が変わるタイミング(Month(d) <> Month(d - 1))を検知してシートを切り替える方法があります。シートが12枚になるためファイルが重くなる場合は、1シートに月ごとの区切り行を入れる方が管理しやすいケースも多いです。

動画で学びたい方へ

「記事を読んでも、実際に自分で書けるか不安…」という方には、動画で基礎からじっくり学べる講座がおすすめです。

VBAが初めての方を前提に、つまずきやすいポイントを先回りして解説しています。サンプル動画は無料でご覧いただけます。

動画で学ぶExcelマクロ|JIMOVEオンラインスクール

コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

上部へスクロール