年間カレンダーの作成

「祝日情報を含めたカレンダーを」というリクエストは大変多いのです。
祝日判定関数や、カレンダーフォームは提供しましたが....  もう、既に「ヒント」はたくさんあるのですが、VBAで作成する祝日の判断を含めたカレンダーの自動作成についての質問はいっこうに減りません。 考えてみたら、「計算式」での「営業日数(ユーザー定義関数)の計算」や、「ダウンロード」の「カレンダー入力用フォーム」でこのようなことのプロシージャを紹介しているものの、 「VBA応用」では、「カレンダーによる日付入力」「営業日数の算出」という「カレンダー」そのものを必要としている人には解りにくいテーマしかなかったので、気付いていただけなかったようです。 そこで、祝日テーブルの取り出し方も少し変えて、期間指定でのカレンダーの作成を題材にしてみることにしました。
なお、「祝日」の算定ロジックについては専門分野ではありません。本件については私自身もAddinBox「祝日について」で勉強させてもらいました。 特に「春分日/秋分日の算出法」とか、9月に「国民の休日」が登場する件などは結構勉強になるので見ていただくと良いと思います。
プログラム修正なく祝日の変更に対応できないか!?   このページの方法では、年間各月の祝日の判定はプログラムソース記述で行なっているのが現状でした。
2019年になって、平成天皇の退位や新しい天皇の即位や「天皇誕生日」の移動などで、この数年は祝日判定プログラムを変更する必要が毎年発生してしまいます。
であれば、このような祝日変更をプログラムの修正なく対応できないものか、と考えたのです。

春分の日、秋分の日は特殊な計算が必要ですが、それ以外の祝日はテーブル登録から計算できないかと考える時期が来ました。
そこで考えたのが「年間カレンダーの作成2」です。営業日数算出のプロシージャも含めてあります。
祝日の定義は「祝日パラメータ」シートで設定するようになっており、会社休日の追加も行なえるようになっています。 このページは「以前の方法のサンプル」として残しますが、今後は「年間カレンダーの作成2」の方法をご利用下さい。
まず、サンプルの動作を見てみましょう。
年間カレンダー作成の画面
(この画像をクリックすると、2種類のサンプルExcelブックを収容した圧縮ファイルがダウンロードできます。)
「年間カレンダー作成」のボタンをクリックすると、処理年を指定する入力ダイアログが現われ、年を入力して「OK」をクリックするとしばらくして「年間カレンダー」が表示されます。

年間カレンダー作成の作成結果画面
ここでのサンプルの「年間カレンダー」はこのような表示です。日曜は赤字、土曜は緑字となっていますが、赤の太字になっている場合は「祝日」です。ここでの説明は日付、曜日、祝日の判定方法ですから、シート上での並べ方についてはそれぞれ工夫してみて下さい。

このようなコードです。
まずは、祝日テーブル作成を受け取って、カレンダーを表示する、メインの記述です。

'*******************************************************************************
'   年間カレンダー作成  ※祝日テーブル作成(modGetSyukujitsu3)のテスト
'
'   作成者:井上治  URL:http://www.ne.jp/asahi/excel/inoue/ [Excelでお仕事!]
'*******************************************************************************
Option Explicit
Const cnsTitle = "年間カレンダー作成"

'*******************************************************************************
'   年間カレンダー作成
'*******************************************************************************
Sub MAKE_CALENDAR()
    Dim GYO As Long, COL As Long
    Dim intY As Integer, cntSyuku As Integer, intIX As Integer
    Dim dteDate As Date, dteToDate As Date, dtePrevDate As Date
    Dim strYear As String
    Dim tblSyuku As Variant

    ' 処理年の指定
    If Month(Date) >= 9 Then
        ' 現在月が9月以降の場合は翌年を初期表示
        intY = Year(Date) + 1
    Else
        intY = Year(Date)
    End If
    ' InputBoxで作成年の指定を受ける
    strYear = Application.InputBox("年を入力して下さい。", cnsTitle, intY, Type:=1)
    If StrPtr(strYear) = 0 Then Exit Sub
    intY = Val(strYear)
    ' 一応、範囲を限定!?
    If ((intY < 2000) Or (intY > Year(Date) + 3)) Then
        MsgBox "年が範囲外です。", vbExclamation, cnsTitle
        Exit Sub
    End If

    '---------------------------------------------------------------------------
    With Application
        .ScreenUpdating = False
        .Cursor = xlWait
        .StatusBar = "カレンダー作成中...."
    End With
    ' 年間カレンダー初期化サブ処理
    Call GP_CLEAR_CALENDAR_SUB
    ' 当年月初日⇒dteDate, 当年最終日⇒dteToDate
    dteDate = DateSerial(intY, 1, 1)        ' xxxx年 1月 1日から
    dteToDate = DateSerial(intY, 12, 31)    ' xxxx年12月31日まで
    dtePrevDate = dteDate - 1               ' 初日の前日を退避
    Cells(1, 1).Value = Year(dteDate) & "年"
    ' 祝日テーブル作成(modGetSyukujitsu3)
    tblSyuku = modGetSyukujitsu3.fncGetHoliDay1(intY, 1, 12)
    ' 先頭日の曜日からカラムを判定
    COL = Weekday(dteDate, vbSunday) + 1
    If COL = 2 Then
        GYO = 1
    Else
        GYO = 0
    End If

    '---------------------------------------------------------------------------
    ' 最終日(xxxx年12月31日)まで繰り返す
    intIX = 0
    Do While dteDate <= dteToDate
        ' 直前日と月が違うか判定(月替わり)
        If Month(dteDate) <> Month(dtePrevDate) Then
            ' 月の更新(月間に1行空白を作成)
            If COL = 2 Then
                ' カラムが2の場合は既に改行しているので+1行
                GYO = GYO + 1
            Else
                ' それ以外は+2行
                GYO = GYO + 2
            End If
            ' A列に月を表示
            Cells(GYO, 1).Value = Month(dteDate) & "月"
        End If
        ' 日付セット
        Cells(GYO, COL).Value = Day(dteDate)
        ' 祝日テーブルの参照(探し出しマッチング処理)
        Do While tblSyuku(intIX) < dteDate
            intIX = intIX + 1
        Loop
        ' 祝日テーブル上の日付と一致したか
        If tblSyuku(intIX) = dteDate Then
            ' 祝日は赤太字
            Cells(GYO, COL).Font.ColorIndex = 3
            Cells(GYO, COL).Font.Bold = True
        End If
        ' 翌日位置を設定(カラムが2〜8までを繰り返す)
        COL = COL + 1
        ' 土曜のカラム(8)を超えるか判断
        If COL > 8 Then
            ' 土曜のカラム(8)を超える場合は次行へ
            GYO = GYO + 1
            ' カラムを2(日曜)に戻す
            COL = 2
        End If
        ' 日付を直前日に退避しておく
        dtePrevDate = dteDate
        ' 翌日に進む
        dteDate = dteDate + 1
    Loop

    '---------------------------------------------------------------------------
    ' 終了
    With Application
        .StatusBar = False
        .Cursor = xlDefault
        .ScreenUpdating = True
    End With
    ThisWorkbook.Saved = True
End Sub

'*******************************************************************************
'   年間カレンダー初期化
'*******************************************************************************
Sub CLEAR_CALENDAR()
    Application.ScreenUpdating = False
    ' 年間カレンダー初期化サブ処理
    Call GP_CLEAR_CALENDAR_SUB
    Range("A1").ClearContents
    Application.ScreenUpdating = True
    ThisWorkbook.Saved = True
End Sub

'*******************************************************************************
'   年間カレンダー初期化サブ処理
'*******************************************************************************
Private Sub GP_CLEAR_CALENDAR_SUB()
    With Range("B2:B500").Font
        .ColorIndex = 3
        .Bold = False
    End With
    With Range("C2:G500").Font
        .ColorIndex = xlColorIndexAutomatic
        .Bold = False
    End With
    With Range("H2:H500").Font
        .ColorIndex = 10
        .Bold = False
    End With
    Rows("2:65536").ClearContents
End Sub

'--------------------------------<< End of Source >>----------------------------
まず、「日付型」というデータ型を理解する必要があります。
このページを見る段階の方にはこのような説明は不要なはずですが、「日付型」の「中身」と「視覚的な見かけ」の区別が解っていない人が結構いるようなので、念のため説明しておきます。 「日付型」とは、190011日を「1」として、1日が1の増分を持つ「シリアル値」です。例えば「200711日」は実際の値は「39083」です。これはワークシート上でも書式を変更するだけで確認できます。
2007年1月1日は「39083」

1日が1の増分ですから時刻については小数値となります。 ここでのカレンダーでは日付しか利用しないので、「日付型」での値の中身は整数値ということになります。上記コードで「翌日に進む」の記述の所で1を加えている理由がここで分かると思います。
「曜日」については、「日付(日付型の値)」に対して「WeekDay関数」で求められます。「WeekDay関数」の結果は1〜7の整数値ですが、曜日に対する値は第2引数の指定によって変化します。 今回は左端が日曜日なので、日曜日が「1」、土曜日が「7」になってくれると都合が良いので「vbSunday」を指定していますが、これは省略時の値でもあるので省略しても同じ結果となります。 今回のサンプルでの配置の場合、この「WeekDay関数」の結果に1を加えるとカラム位置になるわけです。 ですが、「WeekDay関数」による曜日の判定はループに入る前の先頭でしか行ないません。これは当然ながら、日曜日から土曜日の繰り返しには例外がないからです。 ループに入ってからは単にカラムが2から8を繰り返すように記述しているわけです。

問題は「祝日」です。「祝日」については、年間の「祝日」の日付だけをテーブル(配列)に納めておいて、カレンダーを作成しながら現在日付と「祝日」のテーブルをマッチング比較しながら、一致した場合はその日が「祝日」だと判定する方法を採っています。 ここでは、「祝日」テーブルの作成については、

    ' 祝日テーブル作成(modGetSyukujitsu3)
    tblSyuku = modGetSyukujitsu3.fncGetHoliDay1(intY, 1, 12)
だけです。 「modGetSyukujitsu3.bas」がインポートされているプロジェクトであれば、この1行を加えるだけで良いわけです。
あとは、実際のカレンダーを作成する段階で日毎の日付が祝日テーブルにある日付と一致すれば「祝日」そうでなければ通常の日付と判断すれば良いわけです。

今回、使用している「祝日テーブル作成(modGetSyukujitsu3)」は、以前に他ページで紹介したものから期間(取得月数)指定ができるプロシージャとして若干変更を加えています。

'*******************************************************************************
'   祝日判定処理        ※年月指定により祝日(振休補正後)を配列で返す
'
'   作成者:井上治  URL:http://www.ne.jp/asahi/excel/inoue/ [Excelでお仕事!]
'*******************************************************************************
Option Explicit

'*******************************************************************************
' 当該年月の祝日(振替休日補正後)を配列で返す
'
' 戻り値:祝日の配列(当該月に祝日がない場合はブランク)
' 引数 :Arg1=開始年(Integer)
'     Arg2=開始月(Integer)
'     Arg3=取得月数(Integer)
'*******************************************************************************
Public Function fncGetHoliDay1(intSTR_Y As Integer, _
                               intSTR_M As Integer, _
                               intCNT As Integer) As Variant
    Dim tblHoliDay() As Date    ' 振休補正後の祝日テーブル
    Dim tblIX As Integer
    Dim IX As Integer
    Dim intY As Integer
    Dim intM As Integer

    intY = intSTR_Y
    intM = intSTR_M
    If intCNT < 1 Then intCNT = 1
    tblIX = -1
    ReDim tblHoliDay(0)
    For IX = 1 To intCNT
        ' 当該年月の祝日判定
        Call GP_GetHoliday_Sub(intY, intM, tblHoliDay, tblIX)
        ' 次月をセット
        If intM >= 12 Then
            intY = intY + 1
            intM = 1
        Else
            intM = intM + 1
        End If
    Next IX
    ' ブレーク処理用に翌年の日付を追加
    tblIX = tblIX + 1
    ReDim Preserve tblHoliDay(tblIX)
    tblHoliDay(tblIX) = DateSerial(intY + 1, 1, 1)
    fncGetHoliDay1 = tblHoliDay
End Function

'*******************************************************************************
' 当該年月の祝日(振替休日補正後)を配列で返す(サブ処理)
'
' 戻り値:(なし)
' 引数 :Arg1=年(Integer)
'     Arg2=月(Integer)
'     Arg3=祝日日付(Array)
'     Arg4=テーブル格納件数(Integer)
'*******************************************************************************
Private Sub GP_GetHoliday_Sub(intY As Integer, _
                              intM As Integer, _
                              tblDate() As Date, _
                              IX As Integer)

    ' 月による分岐
    Select Case intM
        '-----------------------------------------------------------------------
        ' 1月
        Case 1
            IX = IX + 2
            ReDim Preserve tblDate(IX)
            ' 元旦(1/1)
            tblDate(IX - 1) = FP_GetHoliday2(DateSerial(intY, intM, 1))
            ' 成人の日
            If intY < 2000 Then
                ' 1999年までは15日固定
                tblDate(IX) = FP_GetHoliday2(DateSerial(intY, intM, 15))
            Else
                ' 2000年以降は第2月曜日
                tblDate(IX) = FP_GetHoliday3(intY, intM, 2, 2)
            End If
        '-----------------------------------------------------------------------
        ' 2月
        Case 2
            IX = IX + 1
            ReDim Preserve tblDate(IX)
            ' 建国記念の日(2/11)
            tblDate(IX) = FP_GetHoliday2(DateSerial(intY, intM, 11))
        '-----------------------------------------------------------------------
        ' 3月
        Case 3
            IX = IX + 1
            ReDim Preserve tblDate(IX)
            ' 春分の日(※専用処理)
            tblDate(IX) = FP_GetSyunbun(intY)
        '-----------------------------------------------------------------------
        ' 4月
        Case 4
            IX = IX + 1
            ReDim Preserve tblDate(IX)
            ' みどりの日(4/29) ⇒ 昭和の日(2007年〜)
            tblDate(IX) = FP_GetHoliday2(DateSerial(intY, intM, 29))
        '-----------------------------------------------------------------------
        ' 5月
        Case 5
            If intY >= 1985 Then
                IX = IX + 3
                ReDim Preserve tblDate(IX)
                If intY < 2007 Then
                    ' 憲法記念日(5/3)
                    tblDate(IX - 2) = DateSerial(intY, intM, 3)
                    ' 国民の休日(5/4) ⇒ みどりの日(2007年〜)
                    tblDate(IX - 1) = DateSerial(intY, intM, 4)
                    ' 子供の日(5/5)
                    tblDate(IX) = FP_GetHoliday2(DateSerial(intY, intM, 5))
                Else
                    ' 2007年以降は5/3,5/4が日曜の場合、5/6が振り返られる
                    If Weekday(DateSerial(intY, intM, 3), vbSunday) = vbSunday Then
                        tblDate(IX - 2) = DateSerial(intY, intM, 4)
                        tblDate(IX - 1) = DateSerial(intY, intM, 5)
                        tblDate(IX) = DateSerial(intY, intM, 6)
                    ElseIf Weekday(DateSerial(intY, intM, 4), vbSunday) = vbSunday Then
                        tblDate(IX - 2) = DateSerial(intY, intM, 3)
                        tblDate(IX - 1) = DateSerial(intY, intM, 5)
                        tblDate(IX) = DateSerial(intY, intM, 6)
                    Else
                        tblDate(IX - 2) = DateSerial(intY, intM, 3)
                        tblDate(IX - 1) = DateSerial(intY, intM, 4)
                        tblDate(IX) = FP_GetHoliday2(DateSerial(intY, intM, 5))
                    End If
                End If
            Else
                IX = IX + 2
                ReDim Preserve tblDate(IX)
                ' 憲法記念日(5/3)
                tblDate(IX - 1) = FP_GetHoliday2(DateSerial(intY, intM, 3))
                ' 子供の日(5/5)
                tblDate(IX) = FP_GetHoliday2(DateSerial(intY, intM, 5))
            End If
        '-----------------------------------------------------------------------
        ' 6月
        Case 6
            ' 祝日なし
        '-----------------------------------------------------------------------
        ' 7月
        Case 7
            If intY >= 1996 Then
                IX = IX + 1
                ReDim Preserve tblDate(IX)
                If intY >= 2003 Then
                    ' 海の日(第3月曜日)
                    tblDate(IX) = FP_GetHoliday3(intY, intM, 3, 2)
                Else
                    ' 海の日(7/20)
                    tblDate(IX) = FP_GetHoliday2(DateSerial(intY, intM, 20))
                End If
            End If
        '-----------------------------------------------------------------------
        ' 8月
        Case 8
            If intY >= 2016 Then
                IX = IX + 1
                ReDim Preserve tblDate(IX)
                ' 山の日(8/11) ※2016年より
                tblDate(IX) = FP_GetHoliday2(DateSerial(intY, intM, 11))
            End If
        '-----------------------------------------------------------------------
        ' 9月
        Case 9
            IX = IX + 2
            ReDim Preserve tblDate(IX)
            If intY >= 2003 Then
                ' 敬老の日(第3月曜日)
                tblDate(IX - 1) = FP_GetHoliday3(intY, intM, 3, 2)
                ' 秋分の日(※専用処理)
                tblDate(IX) = FP_GetSyuubun(intY)
                ' 敬老の日の翌々日が秋分の日の場合、間の日は「国民の休日」になる
                If (tblDate(IX) - tblDate(IX - 1)) = 2 Then
                    IX = IX + 1
                    ReDim Preserve tblDate(IX)
                    tblDate(IX) = tblDate(IX - 1)
                    tblDate(IX - 1) = tblDate(IX - 2) + 1
                End If
            Else
                ' 敬老の日(9/15)
                tblDate(IX - 1) = FP_GetHoliday2(DateSerial(intY, intM, 15))
                ' 秋分の日(※専用処理)
                tblDate(IX) = FP_GetSyuubun(intY)
            End If
        '-----------------------------------------------------------------------
        ' 10月
        Case 10
            IX = IX + 1
            ReDim Preserve tblDate(IX)
            If intY >= 2000 Then
                ' 体育の日(第2月曜日)
                tblDate(IX) = FP_GetHoliday3(intY, intM, 2, 2)
            Else
                ' 体育の日(10/10)
                tblDate(IX) = FP_GetHoliday2(DateSerial(intY, intM, 10))
            End If
        '-----------------------------------------------------------------------
        ' 11月
        Case 11
            IX = IX + 2
            ReDim Preserve tblDate(IX)
            ' 文化の日(11/3)
            tblDate(IX - 1) = FP_GetHoliday2(DateSerial(intY, intM, 3))
            ' 勤労感謝の日(11/23)
            tblDate(IX) = FP_GetHoliday2(DateSerial(intY, intM, 23))
        '-----------------------------------------------------------------------
        ' 12月
        Case 12
            If intY >= 1989 Then
                IX = IX + 1
                ReDim Preserve tblDate(IX)
                ' 天皇誕生日(12/23)
                tblDate(IX) = FP_GetHoliday2(DateSerial(intY, intM, 23))
            End If
    End Select
End Sub

'*******************************************************************************
' 当該祝日が日曜なら翌日を返す
'*******************************************************************************
Private Function FP_GetHoliday2(dteHoliday As Date) As Date
    If Weekday(dteHoliday, vbSunday) = vbSunday Then
        FP_GetHoliday2 = dteHoliday + 1
    Else
        FP_GetHoliday2 = dteHoliday
    End If
End Function

'*******************************************************************************
' 年月第n週のm曜日を算出
'*******************************************************************************
Private Function FP_GetHoliday3(intY As Integer, _
                                intM As Integer, _
                                intW As Integer, _
                                intG As Integer) As Date
    Dim dteDate As Date
    Dim intG2 As Integer

    dteDate = DateSerial(intY, intM, 1)     ' 月初日
    intG2 = Weekday(dteDate, vbSunday)      ' 月初日の曜日
    If intG2 > intG Then intW = intW + 1    ' 初週調整
    FP_GetHoliday3 = dteDate - intG2 + (intW - 1) * 7 + intG
End Function

'*******************************************************************************
' 春分の日の算出
'*******************************************************************************
Private Function FP_GetSyunbun(intY As Integer) As Date
    Dim intD As Integer, intY2 As Integer

    ' 祝日法施行(1947年)以前,2151年以降(簡易計算不可)は無視
    intY2 = intY - 1980
    Select Case intY
        Case Is <= 1979
            intD = Int(20.8357 + (0.242194 * intY2) - Int(intY2 / 4))
        Case Is <= 2099
            intD = Int(20.8431 + (0.242194 * intY2) - Int(intY2 / 4))
        Case Else
            intD = Int(21.851 + (0.242194 * intY2) - Int(intY2 / 4))
    End Select
    FP_GetSyunbun = FP_GetHoliday2(DateSerial(intY, 3, intD))
End Function

'*******************************************************************************
' 秋分の日の算出
'*******************************************************************************
Private Function FP_GetSyuubun(intY As Integer) As Date
    Dim intD As Integer, intY2 As Integer

    ' 祝日法施行(1947年)以前,2151年以降(簡易計算不可)は無視
    intY2 = intY - 1980
    Select Case intY
        Case Is <= 1979
            intD = Int(23.2588 + (0.242194 * intY2) - Int(intY2 / 4))
        Case Is <= 2099
            intD = Int(23.2488 + (0.242194 * intY2) - Int(intY2 / 4))
        Case Else
            intD = Int(24.2488 + (0.242194 * intY2) - Int(intY2 / 4))
    End Select
    FP_GetSyuubun = FP_GetHoliday2(DateSerial(intY, 9, intD))
End Function

'--------------------------------<< End of Source >>----------------------------
この「祝日テーブル作成(modGetSyukujitsu3)」は、官報等での祝日に関する内容が変更されない限り、記述の変更はありませんから、内容の理解なくそのまま使用されることでも問題はないと思います。 但し、この「祝日テーブル作成(modGetSyukujitsu3)」に年末年始などの特別な会社休日などを付加させる利用もできるわけですが、その場合はきちんとした内容理解が必要です。

もうひとつ、祝日名まで表示させるものも用意してみました。
「祝日」の判断ができて印が付くような用途であればここまでの説明で終わりですが、ついでですからその「祝日」が「〜の日」なのかも表示させるようにしてみます。
年間カレンダー作成の画面
やっていることは最初のサンプルと同じですが、セルのコメントに「祝日名」を収容することを追加しています。

これを実現させるために、「祝日テーブル作成(modGetSyukujitsu4)」を用意しています。 日付、振替休日かの判定、祝日名の3項目をテーブルとするため、ユーザー定義型の変数を用意していますが、これをFunctionプロシージャも戻り値に使用するにはExcel2000以降というバージョン制限に掛かってしまうため、 今回は戻り値では配列の要素数だけ返すことにして、ユーザー定義型のテーブル自体はPublicレベルで参照する方法としています。 また、このテーブルにはブレーク判定がしやすいように期間最終日より後の「祝日」判定になるようなダミー日付を追加してあるため、マッチング処理ではテーブルの収容件数を絡めて確認しなくても済みます。

まずは、メインのコードです。

'*******************************************************************************
'   年間カレンダー作成  ※祝日テーブル作成(modGetSyukujitsu4)のテスト
'
'   作成者:井上治  URL:http://www.ne.jp/asahi/excel/inoue/ [Excelでお仕事!]
'*******************************************************************************
Option Explicit
Const cnsTitle = "年間カレンダー作成"

'*******************************************************************************
'   年間カレンダー作成
'*******************************************************************************
Sub MAKE_CALENDAR()
    Dim GYO As Long, COL As Long
    Dim intY As Integer, intIX As Integer, intIXMAX As Integer
    Dim dteDate As Date, dteToDate As Date, dtePrevDate As Date
    Dim strYear As String

    ' 処理年の指定
    If Month(Date) >= 9 Then
        ' 現在月が9月以降の場合は翌年を初期表示
        intY = Year(Date) + 1
    Else
        intY = Year(Date)
    End If
    ' InputBoxで作成年の指定を受ける
    strYear = Application.InputBox("年を入力して下さい。", cnsTitle, intY, Type:=1)
    If StrPtr(strYear) = 0 Then Exit Sub
    intY = Val(strYear)
    ' 一応、範囲を限定!?
    If ((intY < 2000) Or (intY > Year(Date) + 3)) Then
        MsgBox "年が範囲外です。", vbExclamation, cnsTitle
        Exit Sub
    End If

    '---------------------------------------------------------------------------
    With Application
        .ScreenUpdating = False
        .Cursor = xlWait
        .StatusBar = "カレンダー作成中...."
    End With
    ' 年間カレンダー初期化サブ処理
    Call GP_CLEAR_CALENDAR_SUB
    ' 当年月初日⇒dteDate, 当年最終日⇒dteToDate
    dteDate = DateSerial(intY, 1, 1)        ' xxxx年 1月 1日から
    dteToDate = DateSerial(intY, 12, 31)    ' xxxx年12月31日まで
    dtePrevDate = dteDate - 1               ' 初日の前日を退避
    Cells(1, 1).Value = Year(dteDate) & "年"
    ' 祝日テーブル作成(modGetSyukujitsu4)
    intIXMAX = modGetSyukujitsu4.fncGetHoliDay2(intY, 1, 12)
    ' 先頭日の曜日からカラムを判定
    COL = Weekday(dteDate, vbSunday) + 1
    If COL = 2 Then
        GYO = 1
    Else
        GYO = 0
    End If

    '---------------------------------------------------------------------------
    ' 最終日(xxxx年12月31日)まで繰り返す
    intIX = 0
    Do While dteDate <= dteToDate
        ' 直前日と月が違うか判定(月替わり)
        If Month(dteDate) <> Month(dtePrevDate) Then
            ' 月の更新(月間に1行空白を作成)
            If COL = 2 Then
                ' カラムが2の場合は既に改行しているので+1行
                GYO = GYO + 1
            Else
                ' それ以外は+2行
                GYO = GYO + 2
            End If
            ' A列に月を表示
            Cells(GYO, 1).Value = Month(dteDate) & "月"
        End If
        ' 日付セット
        Cells(GYO, COL).Value = Day(dteDate)
        ' 祝日テーブルの参照(探し出しマッチング処理)
        Do While g_tblSyuku(intIX).dteDate < dteDate
            intIX = intIX + 1
        Loop
        ' 祝日テーブル上の日付と一致したか
        If g_tblSyuku(intIX).dteDate = dteDate Then
            ' 祝日は赤太字にして祝日名をコメントでセット
            With Cells(GYO, COL)
                .Font.ColorIndex = 3
                .Font.Bold = True
                ' 祝日名をコメントに加えてコメントを書式を設定
                With .AddComment(g_tblSyuku(intIX).strName)
                    With .Shape.TextFrame
                        .Characters.Font.ColorIndex = 5
                        .Characters.Font.Bold = True
                        .AutoSize = True
                    End With
                End With
            End With
        End If
        ' 翌日位置を設定(カラムが2〜8までを繰り返す)
        COL = COL + 1
        ' 土曜のカラム(8)を超えるか判断
        If COL > 8 Then
            ' 土曜のカラム(8)を超える場合は次行へ
            GYO = GYO + 1
            ' カラムを2(日曜)に戻す
            COL = 2
        End If
        ' 日付を直前日に退避しておく
        dtePrevDate = dteDate
        ' 翌日に進む
        dteDate = dteDate + 1
    Loop

    '---------------------------------------------------------------------------
    ' 終了
    With Application
        .StatusBar = False
        .Cursor = xlDefault
        .ScreenUpdating = True
    End With
    ThisWorkbook.Saved = True
End Sub

'*******************************************************************************
'   年間カレンダー初期化
'*******************************************************************************
Sub CLEAR_CALENDAR()
    Application.ScreenUpdating = False
    ' 年間カレンダー初期化サブ処理
    Call GP_CLEAR_CALENDAR_SUB
    Range("A1").ClearContents
    Application.ScreenUpdating = True
    ThisWorkbook.Saved = True
End Sub

'*******************************************************************************
'   年間カレンダー初期化サブ処理
'*******************************************************************************
Private Sub GP_CLEAR_CALENDAR_SUB()
    With Range("B2:B500").Font
        .ColorIndex = 3
        .Bold = False
    End With
    With Range("C2:G500").Font
        .ColorIndex = xlColorIndexAutomatic
        .Bold = False
    End With
    With Range("H2:H500").Font
        .ColorIndex = 10
        .Bold = False
    End With
    Range("B2:H500").ClearComments          ' コメントのクリア
    Rows("2:65536").ClearContents
End Sub

'--------------------------------<< End of Source >>----------------------------
このように、テーブルの日付の参照が「g_tblSyuku(intIX).dteDate」と変わっているのと、コメント(祝日名)の処理が加わっているところが違いますが、それ以外は先頭のコードと変わりありません。

「祝日」テーブルの作成は、

    ' 祝日テーブル作成(modGetSyukujitsu4)
    intIXMAX = modGetSyukujitsu4.fncGetHoliDay2(intY, 1, 12)
と変わっていますが、左辺の「intIXMAX」はテーブルの収容件数であり、前の説明にもあるように以降で使用されていません。 ですから、SubプロシージャのようにCallステートメントで呼び出すことでも構わないわけです。

以下は、「祝日テーブル作成」である「modGetSyukujitsu4」モジュールの内容です。

'*******************************************************************************
'   祝日判定処理        ※年月指定により祝日(振休補正後)を配列で返すB
'
'   作成者:井上治  URL:http://www.ne.jp/asahi/excel/inoue/ [Excelでお仕事!]
'*******************************************************************************
' 修正日   修正内容------------------------------------------------------------>
' 09/03/01 春分の日の処理で空テーブル要素ができてしまう件を修正
'*******************************************************************************
Option Explicit
Private Const g_cnsFURI = "(振替休日)"
Private Const g_cnsKYU2 = "国民の休日"
' 祝日テーブル(ユーザー定義)
Public Type typSyuku
    dteDate As Date                 ' 日付
    intFuri As Integer              ' 振替休日SW(1=振替休日, 0=通常)
    strName As String               ' 祝日名称
End Type
' 下記処理で作成される祝日テーブル
Public g_tblSyuku() As typSyuku    ' 祝日テーブル(呼び元で利用する)

'*******************************************************************************
' 当該年月の祝日(振替休日補正後)を配列で返す
'
' 戻り値:祝日の配列の上限インデックス(-1の場合は祝日なし)
'     ⇒実際の祝日テーブルはg_tblSyukuを参照すること
' 引数 :Arg1=開始年(Integer)
'     Arg2=開始月(Integer)
'     Arg3=取得月数(Integer)
'*******************************************************************************
Public Function fncGetHoliDay2(intSTR_Y As Integer, _
                               intSTR_M As Integer, _
                               intCNT As Integer) As Integer
    Dim intY As Integer, intM As Integer, IX As Integer, tblIX As Integer

    intY = intSTR_Y
    intM = intSTR_M
    If intCNT < 1 Then intCNT = 1
    tblIX = -1
    ReDim g_tblSyuku(0)
    For IX = 1 To intCNT
        ' 当該年月の祝日判定
        Call GP_GetHolidaySub(intY, intM, tblIX)
        ' 次月をセット
        If intM >= 12 Then
            intY = intY + 1
            intM = 1
        Else
            intM = intM + 1
        End If
    Next IX
    ' テーブル上は要素数に1を加えて期間外の日付をセット(ブレーク判定用)
    tblIX = tblIX + 1
    ReDim Preserve g_tblSyuku(tblIX)
    g_tblSyuku(tblIX).dteDate = DateSerial(intY + 1, intM, 1)
    ' テーブルの有効要素数を返す
    fncGetHoliDay2 = tblIX - 1
End Function

'*******************************************************************************
' ※以下はサブ処理
'*******************************************************************************
' 祝日情報のテーブルを作成(1ヶ月分共通処理)
'
' 戻り値:(なし)
' 引数 :Arg1=年(Integer)
'     Arg2=月(Integer)
'     Arg3=テーブル最終位置(Long)  ※直前項目の登録位置
'*******************************************************************************
Private Sub GP_GetHolidaySub(intY As Integer, _
                             intM As Integer, _
                             IX As Integer)
    Dim strName As String, strName2 As String

    ' 月による分岐
    Select Case intM
        '-----------------------------------------------------------------------
        ' 1月
        Case 1
            ' 元旦(1/1)
            Call GP_GetHolidaySub2(DateSerial(intY, intM, 1), IX, "元旦")
            ' 成人の日
            strName = "成人の日"
            If intY < 2000 Then
                ' 1999年までは15日固定
                Call GP_GetHolidaySub2(DateSerial(intY, intM, 15), IX, strName)
            Else
                ' 2000年以降は第2月曜日
                Call GP_GetHolidaySub3(intY, intM, 2, 2, IX, strName)
            End If
        '-----------------------------------------------------------------------
        ' 2月
        Case 2
            ' 建国記念の日(2/11)
            Call GP_GetHolidaySub2(DateSerial(intY, intM, 11), IX, "建国記念の日")
        '-----------------------------------------------------------------------
        ' 3月
        Case 3
            ' 春分の日(※専用処理)
            Call GP_GetSyunbun(intY, IX)
        '-----------------------------------------------------------------------
        ' 4月
        Case 4
            ' みどりの日(4/29) ⇒ 昭和の日(2007年〜)
            If intY >= 2007 Then
                strName = "昭和の日"
            Else
                strName = "みどりの日"
            End If
            Call GP_GetHolidaySub2(DateSerial(intY, intM, 29), IX, strName)
        '-----------------------------------------------------------------------
        ' 5月
        Case 5
            strName = "憲法記念日"
            strName2 = "子供の日"
            If intY >= 1985 Then
                IX = IX + 3
                ReDim Preserve g_tblSyuku(IX)
                ' 憲法記念日(5/3)
                g_tblSyuku(IX - 2).dteDate = DateSerial(intY, intM, 3)
                g_tblSyuku(IX - 2).strName = strName
                ' 国民の休日(5/4) ⇒ みどりの日(2007年〜)
                g_tblSyuku(IX - 1).dteDate = DateSerial(intY, intM, 4)
                If intY >= 2007 Then
                    g_tblSyuku(IX - 1).strName = "みどりの日"
                Else
                    g_tblSyuku(IX - 1).strName = g_cnsKYU2
                End If
                ' 子供の日(5/5)
                If intY < 2007 Then
                    IX = IX - 1     ' 一旦減算(下位Procで加算されるため)
                    Call GP_GetHolidaySub2(DateSerial(intY, intM, 5), IX, strName2)
                Else
                    g_tblSyuku(IX).dteDate = DateSerial(intY, intM, 5)
                    g_tblSyuku(IX).strName = strName2
                    ' 2007年以降は5/3,5/4が日曜の場合も、5/6が振り返られる
                    If ((Weekday(g_tblSyuku(IX - 2).dteDate, vbSunday) = vbSunday) Or _
                        (Weekday(g_tblSyuku(IX - 1).dteDate, vbSunday) = vbSunday) Or _
                        (Weekday(g_tblSyuku(IX).dteDate, vbSunday) = vbSunday)) Then
                        IX = IX + 1
                        ReDim Preserve g_tblSyuku(IX)
                        g_tblSyuku(IX).dteDate = DateSerial(intY, intM, 6)
                        g_tblSyuku(IX).intFuri = 1
                        g_tblSyuku(IX).strName = g_cnsFURI
                    End If
                End If
            Else
                ' 憲法記念日(5/3)
                Call GP_GetHolidaySub2(DateSerial(intY, intM, 3), IX, strName)
                ' 子供の日(5/5)
                Call GP_GetHolidaySub2(DateSerial(intY, intM, 5), IX, strName2)
            End If
        '-----------------------------------------------------------------------
        ' 6月
        Case 6
            ' 祝日なし
        '-----------------------------------------------------------------------
        ' 7月
        Case 7
            If intY >= 1996 Then
                strName = "海の日"
                If intY >= 2003 Then
                    ' 海の日(第3月曜日)
                    Call GP_GetHolidaySub3(intY, intM, 3, 2, IX, strName)
                Else
                    ' 海の日(7/20)
                    Call GP_GetHolidaySub2(DateSerial(intY, intM, 20), IX, strName)
                End If
            End If
        '-----------------------------------------------------------------------
        ' 8月
        Case 8
            If intY >= 2016 Then
                ' 山の日(8/11) ※2016年より
                Call GP_GetHolidaySub2(DateSerial(intY, intM, 11), IX, "山の日")
            End If
        '-----------------------------------------------------------------------
        ' 9月
        Case 9
            strName = "敬老の日"
            If intY >= 2003 Then
                ' 敬老の日(第3月曜日)
                Call GP_GetHolidaySub3(intY, intM, 3, 2, IX, strName)
            Else
                ' 敬老の日(9/15)
                Call GP_GetHolidaySub2(DateSerial(intY, intM, 15), IX, strName)
            End If
            ' 秋分の日(※専用処理)
            Call GP_GetSyuubun(intY, IX)
        '-----------------------------------------------------------------------
        ' 10月
        Case 10
            strName = "体育の日"
            If intY >= 2000 Then
                ' 体育の日(第2月曜日)
                Call GP_GetHolidaySub3(intY, intM, 2, 2, IX, strName)
            Else
                ' 体育の日(10/10)
                Call GP_GetHolidaySub2(DateSerial(intY, intM, 10), IX, strName)
            End If
        '-----------------------------------------------------------------------
        ' 11月
        Case 11
            ' 文化の日(11/3)
            Call GP_GetHolidaySub2(DateSerial(intY, intM, 3), IX, "文化の日")
            ' 勤労感謝の日(11/23)
            Call GP_GetHolidaySub2(DateSerial(intY, intM, 23), IX, "勤労感謝の日")
        '-----------------------------------------------------------------------
        ' 12月
        Case 12
            If intY >= 1989 Then
                ' 天皇誕生日(12/23)
                Call GP_GetHolidaySub2(DateSerial(intY, intM, 23), IX, "天皇誕生日")
            End If
    End Select
End Sub

'*******************************************************************************
' 当該祝日が日曜なら翌日を振替休日にしてテーブルセット(共通Sub処理)
'
' 戻り値:(なし)
' 引数 :Arg1=祝日日付(Date)
'     Arg2=テーブル最終位置(Long)  ※直前項目の登録位置
'     Arg3=祝日の名称(String)
'*******************************************************************************
Private Sub GP_GetHolidaySub2(dteHoliday As Date, _
                              IX As Integer, _
                              strName As String)
    ' 当該祝日
    IX = IX + 1
    ReDim Preserve g_tblSyuku(IX)
    g_tblSyuku(IX).dteDate = dteHoliday
    g_tblSyuku(IX).strName = strName
    If Weekday(dteHoliday, vbSunday) = vbSunday Then
        ' 日曜と重なった場合の翌日を振替休日とする
        IX = IX + 1
        ReDim Preserve g_tblSyuku(IX)
        g_tblSyuku(IX).dteDate = dteHoliday + 1
        g_tblSyuku(IX).intFuri = 1          ' 振替休日
        g_tblSyuku(IX).strName = g_cnsFURI
    End If
End Sub

'*******************************************************************************
' 年月第n週のm曜日を算出してテーブルセット(共通Sub処理)
'
' 戻り値:(なし)
' 引数 :Arg1=年(Integer)
'     Arg2=月(Integer)
'     Arg3=週(Integer)
'     Arg4=曜日コード(Integer)     ※1=日曜, 2=月曜...7=土曜(2のみ利用)
'     Arg5=テーブル最終位置(Long)  ※直前項目の登録位置
'     Arg6=祝日の名称(String)
'*******************************************************************************
Private Sub GP_GetHolidaySub3(intY As Integer, _
                              intM As Integer, _
                              intW As Integer, _
                              intG As Integer, _
                              IX As Integer, _
                              strName As String)
    Dim dteDate As Date
    Dim intG2 As Integer

    IX = IX + 1
    ReDim Preserve g_tblSyuku(IX)
    dteDate = DateSerial(intY, intM, 1)     ' 月初日
    intG2 = Weekday(dteDate, vbSunday)      ' 月初日の曜日
    If intG2 > intG Then intW = intW + 1    ' 初週調整
    g_tblSyuku(IX).dteDate = dteDate - intG2 + (intW - 1) * 7 + intG
    g_tblSyuku(IX).strName = strName
End Sub

'*******************************************************************************
' 春分の日の算出(簡易計算方式)
'
' 戻り値:(なし)
' 引数 :Arg1=年(Integer)
'     Arg2=テーブル最終位置(Long)  ※直前項目の登録位置
'*******************************************************************************
Private Sub GP_GetSyunbun(intY As Integer, _
                          IX As Integer)
    Dim intD As Integer, intY2 As Integer

    ' 祝日法施行(1947年)以前,2151年以降(簡易計算不可)は無視
'**********2009/03/01DEL↓(不要記述)
'    IX = IX + 1
'    ReDim Preserve g_tblSyuku(IX)
'**********2009/03/01DEL↑
    intY2 = intY - 1980
    Select Case intY
        Case Is <= 1979
            intD = Int(20.8357 + (0.242194 * intY2) - Int(intY2 / 4))
        Case Is <= 2099
            intD = Int(20.8431 + (0.242194 * intY2) - Int(intY2 / 4))
        Case Else
            intD = Int(21.851 + (0.242194 * intY2) - Int(intY2 / 4))
    End Select
    ' 春分の日
    Call GP_GetHolidaySub2(DateSerial(intY, 3, intD), IX, "春分の日")
End Sub

'*******************************************************************************
' 秋分の日の算出(簡易計算方式)
'
' 戻り値:(なし)
' 引数 :Arg1=年(Integer)
'     Arg2=テーブル最終位置(Long)  ※直前項目の登録位置
'*******************************************************************************
Private Sub GP_GetSyuubun(intY As Integer, _
                          IX As Integer)
    Dim intD As Integer, intY2 As Integer, dteDate As Date

    ' 祝日法施行(1947年)以前,2151年以降(簡易計算不可)は無視
    intY2 = intY - 1980
    Select Case intY
        Case Is <= 1979
            intD = Int(23.2588 + (0.242194 * intY2) - Int(intY2 / 4))
        Case Is <= 2099
            intD = Int(23.2488 + (0.242194 * intY2) - Int(intY2 / 4))
        Case Else
            intD = Int(24.2488 + (0.242194 * intY2) - Int(intY2 / 4))
    End Select
    dteDate = DateSerial(intY, 9, intD)
    ' 2003年以降は敬老の日の翌々日が秋分の日の場合、間の日は「国民の休日」になる
    If ((intY >= 2003) And ((dteDate - g_tblSyuku(IX).dteDate) = 2)) Then
        IX = IX + 1
        ReDim Preserve g_tblSyuku(IX)
        g_tblSyuku(IX).dteDate = dteDate - 1
        g_tblSyuku(IX).strName = g_cnsKYU2
    End If
    ' 秋分の日
    Call GP_GetHolidaySub2(dteDate, IX, "秋分の日")
End Sub

'--------------------------------<< End of Source >>----------------------------
会社独自の休日を追加して表示させたい....  質問で「会社独自の休日を追加して表示させる方法は?」というのを多くいただきます。
この場合は上記のソースコードの「GP_GetHoliday_Sub」プロシージャの中を修正して下さい。 「営業日数の算出」の中のサンプルコードでは12/29〜1/3を会社休日にするというような記述になっており、変更部分は説明のコメントを付けてあります。
なお、「GP_GetHoliday_Sub」プロシージャは祝日名を表示させる機能の有無で記述が異なるのでそのままコピーするのではなく、参考として独自に記述変更させて下さい。