日付の扱い方(文字列の日付の変換・月末日・締め日の計算)
CSV から取り込んだ文字列の日付を日付型に変換する方法、DateSerial を使った月末日や締め日の計算、和暦の表示など、日付で間違えやすい点をまとめます。
日付でつまずく理由
基幹システムから出力したデータでは、日付が「20261005」や「2026/10/05」のような文字列で入っていることがよくあります。見た目は日付でも文字列のままだと、並べ替えや期間の比較が正しくできません。
また、月末日や締め日の計算を「31日」などの固定値で書くと、2月や小の月で誤ります。VBA には日付を安全に組み立てる関数があるので、それを使います。
文字列の日付を日付型に変換する
スラッシュ区切りの文字列は CDate で変換できますが、区切りのない8桁の数字は DateSerial で年・月・日に分けて組み立てます。変換できない値で止まらないよう、チェックしてから変換します。
Function ToDate(ByVal v As Variant) As Variant
Dim s As String
s = Trim(CStr(v))
If Len(s) = 8 And IsNumeric(s) Then ' 20261005 形式
ToDate = DateSerial(CInt(Left(s, 4)), CInt(Mid(s, 5, 2)), CInt(Right(s, 2)))
ElseIf IsDate(s) Then ' 2026/10/05 形式など
ToDate = CDate(s)
Else
ToDate = Empty ' 変換できない値は空にする
End If
End Function月末日・翌月末・締め日の計算
DateSerial は「日」に 0 を指定すると前月の末日になる性質があり、これを使うと月末日を簡単に求められます。月をまたぐ計算も自動で繰り上がるため、12月の翌月なども正しく扱えます。
Sub DateSamples()
Dim d As Date
d = DateSerial(2026, 2, 15)
Debug.Print DateSerial(Year(d), Month(d) + 1, 0) ' その月の末日:2026/02/28
Debug.Print DateSerial(Year(d), Month(d) + 2, 0) ' 翌月の末日:2026/03/31
Debug.Print DateSerial(Year(d), Month(d), 1) ' その月の1日
' 20日締め:21日以降は翌月の締め日になる
If Day(d) <= 20 Then
Debug.Print DateSerial(Year(d), Month(d), 20)
Else
Debug.Print DateSerial(Year(d), Month(d) + 1, 20)
End If
End Sub和暦で表示する
帳票で和暦が必要な場合は、値は日付型のまま持ち、表示だけを書式で変えるのが基本です。セルの表示形式に「ggge年m月d日」を指定するか、VBA では Format 関数を使います。計算に使う値まで和暦の文字列にしてしまうと、後で比較や並べ替えができなくなります。
Debug.Print Format(Date, "ggge年m月d日") ' 例:令和8年10月5日
ws.Range("B2").NumberFormatLocal = "ggge年m月d日"よくある間違い
日付の比較で文字列どうしを比べてしまうと、「2026/9/1」と「2026/10/1」の大小が逆になります。比較の前に必ず日付型にそろえます。また、Now は時刻を含むため、「今日の日付と一致するか」を判定するときは Date を使います。
- 文字列のまま比較しない(先に日付型へ変換する)
- 当日の判定には Now ではなく Date を使う
- 月末日は DateSerial(年, 月 + 1, 0) で求める
※和暦の表示は Windows の設定や Excel のバージョンによって元号の扱いが異なる場合があります。