Excel Macro

休日の判定

日曜(土曜)、国民の祝日、年末年始の休日を判定するマクロ。

Download: isHoliday.zip

書式

isHoliday(シリアル値, 土曜日)

シリアル値
日付のシリアル値( Date 型)
土曜日
省略可。 True を指定した場合は土曜日を休日と判定する。デフォルトは False 。

解説

引数のシリアル値に指定した日付が以下の条件に当てはまる場合は True を返す。

  1. 日曜日
  2. (土曜日):引数の土曜日に True を指定した場合。
  3. 国民の祝日( 2008 年現在の国民の祝日に関する法律による)
  4. 年末年始:御用納めを 12 月 28 日、御用始めを 1 月 4 日とし、その間の 12 月 29 日から 1 月 3 日までを休日とする。

コード

Public Function isHoliday(シリアル値 As Date, Optional 土曜日 As Boolean = False) As Boolean

'-----------------------------------------------------------------------------------------
' 日曜 | 国民の祝日 | 年末年始であるか判定する。
'
'   シリアル値 :Date型の日付
'   土曜日   :土曜日を休日とする可否
'
'   戻り値:休日の場合はTrue、そうでない場合はFalse
'-----------------------------------------------------------------------------------------

    Dim y As Integer, m As Integer, d As Integer
    Dim holiday(15, 1) As Integer
    Dim w(6) As Integer
    Dim tempDate As Date
    Dim i As Integer, j As Integer, flag As Boolean

    ' 曜日の休日
    If Weekday(シリアル値) = vbSunday Or (土曜日 = True And Weekday(シリアル値) = vbSaturday) Then
        isHoliday = True
        Exit Function
    End If

    ' シリアル値を年月日へ分解
    y = year(シリアル値)
    m = month(シリアル値)
    d = day(シリアル値)
    
    ' 年末年始
    Dim osameDay As Integer, hajimeDay As Integer
    osameDay = 28 ' 御用お納め:28日
    hajimeDay = 4 ' 御用始め :4日
    
    If (m = 12 And d > osameDay) Or (m = 1 And d < hajimeDay) Then
        isHoliday = True
        Exit Function
    End If


    ' 以降の処理は、国民の祝日に対する処理

    w(0) = 5
    w(1) = 6
    w(2) = 0
    w(3) = 1
    w(4) = 2
    w(5) = 3
    w(6) = 4

    ' 元日:1月1日
    holiday(0, 0) = 1
    holiday(0, 1) = 1

    ' 成人の日:1月の第2月曜日
    holiday(1, 0) = 1
    holiday(1, 1) = 14 - w(Weekday(DateSerial(y, 1, 14)))

    ' 建国記念の日:政令で定める日(2月11日)
    holiday(2, 0) = 2
    holiday(2, 1) = 11

    ' 春分の日:春分日
    holiday(3, 0) = 3
    holiday(3, 1) = Int(20.8431 + 0.242194 * (y - 1980) - Int((y - 1980) / 4))

    ' 昭和の日:4月29日
    holiday(4, 0) = 4
    holiday(4, 1) = 29

    ' 憲法記念日:5月3日
    holiday(5, 0) = 5
    holiday(5, 1) = 3

    ' みどりの日:5月4日
    holiday(6, 0) = 5
    holiday(6, 1) = 4

    ' こどもの日:5月5日
    holiday(7, 0) = 5
    holiday(7, 1) = 5

    ' 海の日:7月の第3月曜日
    holiday(8, 0) = 7
    holiday(8, 1) = 21 - w(Weekday(DateSerial(y, 7, 21)))

    ' 敬老の日:9月の第3月曜日
    holiday(9, 0) = 9
    holiday(9, 1) = 21 - w(Weekday(DateSerial(y, 9, 21)))

    ' 秋分の日:秋分日
    holiday(10, 0) = 9
    holiday(10, 1) = Int(23.2488 + 0.242194 * (y - 1980) - Int((y - 1980) / 4))

    ' 体育の日:10月の第2月曜日
    holiday(11, 0) = 10
    holiday(11, 1) = 14 - w(Weekday(DateSerial(y, 10, 14)))

    ' 文化の日:11月3日
    holiday(12, 0) = 11
    holiday(12, 1) = 3

    ' 勤労感謝の日:11月23日
    holiday(13, 0) = 11
    holiday(13, 1) = 23

    ' 天皇誕生日:12月23日
    holiday(14, 0) = 12
    holiday(14, 1) = 23

    ' 国民の休日:敬老の日と秋分の日に挟まれた平日が1日の場合、その日
    If holiday(9, 1) + 2 = holiday(10, 1) Then
        holiday(15, 0) = 9
        holiday(15, 1) = holiday(9, 1) + 1
    Else
        holiday(15, 0) = 0
        holiday(15, 1) = 0
    End If
    
    ' 振替休日(国民の休日は対象にしない)
    For i = 0 To 14
        If Weekday(DateSerial(y, holiday(i, 0), holiday(i, 1))) = vbSunday Then
            tempDate = DateSerial(y, holiday(i, 0), holiday(i, 1)) + 1
            holiday(i, 0) = month(tempDate)
            holiday(i, 1) = day(tempDate)
            Do
                flag = False
                For j = 0 To 14
                    If i <> j And holiday(i, 0) = holiday(j, 0) And holiday(i, 1) = holiday(j, 1) Then
                        tempDate = DateSerial(y, holiday(i, 0), holiday(i, 1)) + 1
                        holiday(i, 0) = month(tempDate)
                        holiday(i, 1) = day(tempDate)
                        flag = True
                    End If
                Next j
            Loop Until flag = False
        End If
    Next i

    ' 祝日判定
    For i = 0 To 15
        If holiday(i, 0) = m And holiday(i, 1) = d Then
            isHoliday = True
            Exit Function
        End If
    Next i

    ' 土日祝日ではない
    isHoliday = False

End Function