LoginSignup
0
1

More than 5 years have passed since last update.

VBA 指定した年 月 の指定した曜日の第5週の日付があれば返す関数

Posted at

第5週の日本だけの必要性

第5週というのはオフィスでは無視されています。
1. 海外では28日を超えると翌月の週にカウントしている
2. ヨーロッパは月単位ではなく第何週というカウントをしている。
1年は365日...なので72週でカウントする。なに1日に足りないって?たぶんバカンスなのかな。ヨーロッパで使われるWeekカレンダーとは|2014年のウィークカレンダー
3. アメリカも給料は隔週単位で出る(もちろん月1もあり)ことが少なくないので、やっぱり第5週がいらない。
4. そんな感じでどこも必要とされないので存在しない

あとはイスラム圏と日本以外のアジア、ロシアあたりですが、あまりなさげ。

使用方法

前提条件

まず第5週は29日以降しか存在しません。つまり最大で3日しか存在しません。
2月はうるう年でなければ、第5週は存在しません。
DateSerialであらわすと
DateSerial(iYear, iMonth, 29)
DateSerial(iYear, iMonth+1, 0)
0というのは翌月の1日から見た前日、つまり常に月末を表します。

引数、曜日は定数

第5週がありそうな4桁の西暦、月、曜日をいれます。
曜日は1~7ですが、vbMondayなどの定数が使えます。

エラーチェック

1900年代以前や、月が1~12ではない。曜日が定数の1~7でなければ 00:00:00が返ります。vbEmpty
また第5週に指定した曜日が存在しなければ00:00:00を返します。

Function Dayof5thWeekday(iYear, iMonth, iWeekday) As Date
Dim Dt As Date
'for MicroSoft Office Suit VBA
'Q11Q From Qiita
'Exsample:Dayof5thWeekday(2018,4,vbMonday) return 2018/4/30
'You can Use vbSunday(=1) to vbSaturday(=7)
'If Error Occur Then Return '00:00:00'
'///// Error Check Block '/////
On Error GoTo Terminator
If iYear < 1900 Then Dayof5thWeekday = vbEmpty: Exit Function
If iMonth < 0 Or iMonth > 13 Then Dayof5thWeekday = vbEmpty: Exit Function
If iWeekday < 1 Or iWeekday > 8 Then Dayof5thWeekday = vbEmpty: Exit Function
'///// Calculation Blocik /////
Dt = DateSerial(iYear, iMonth, 35 - weekday(DateSerial(iYear, iMonth, 0), iWeekday + 1))
If Month(Dt) < iMonth + 1 Then
Dayof5thWeekday = Dt
Exit Function
Else
Dayof5thWeekday = vbEmpty
End If
Exit Function
Terminator:
If Err.Number <> 0 Then Debug.Print Err.Number, Err.Description: Err.Clear
Dayof5thWeekday = vbEmpty: Exit Function
End Function
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1