VBA DateAddで完璧!経理向け「翌月末」支払期限を正確に算出するテクニック(閏年対応)
経理の皆さん、毎月の支払期限の計算、正確に行えていますか?特に「翌月末」の支払期日を算出する際、基準日が月の途中であろうと月末であろうと、「厳密な翌月末」を導き出すのは意外と骨が折れるものです。2月は28日?それとも閏年の29日?30日?31日?――支払遅延は会社の信用問題に直結するため、日数のズレは絶対に避けたいですよね。
VBAのDateAdd関数は非常に便利ですが、月末日の計算にはいくつか落とし穴があります。この記事では、それらの課題をクリアし、入力された日付がいつであっても、常に正しい「翌月末の支払期限」を算出するVBAコードと、その仕組みをVBAエキスパートが徹底解説します。コピペで使える実務的なコード付きですので、ぜひ日々の業務にお役立てください。
コピペで即解決!翌月末の支払期限を導き出すVBAコード
以下のVBA関数は、引数として渡された日付を基準に、その「翌月末日」を正確に返します。例として、2026/1/31を基準日とした場合の翌月末は2026/2/28となりますが、閏年や月の途中の日付でも正確に計算されます。
Function GetNextMonthEndPaymentDate(ByVal baseDate As Date) As Date
'***************************************************************
' 機能: 指定された日付の翌月末日を算出する
' 引数:
' baseDate (Date): 基準となる日付 (例: 2026/1/31)
' 戻り値:
' Date: 基準日の翌月末日 (例: 2026/2/28)
' 備考:
' DateAdd関数の月末処理の落とし穴を回避し、
' 閏年や月の途中の日付でも正確な翌月末を導き出します。
'***************************************************************
' 1. 基準日の「翌々月」の「1日」を算出します。
' DateSerial(年, 月, 日) を使用し、
' 月には Month(baseDate) + 2 を指定することで翌々月へ進めます。
' 日には 1 を指定し、常に月の初日を取得します。
Dim nextNextMonthFirstDay As Date
nextNextMonthFirstDay = DateSerial(Year(baseDate), Month(baseDate) + 2, 1)
' 2. 翌々月の1日から「1日」を引くことで、
' 自動的に「翌月」の正確な月末日を取得します。
' これにより、28日、29日、30日、31日といった月末日の変動や
' 閏年の影響を意識することなく、常に正しい月末日が得られます。
GetNextMonthEndPaymentDate = nextNextMonthFirstDay - 1
End Function
Sub TestPaymentDateCalculation()
Dim inputDate As Date
Dim paymentDueDate As Date
' --- テストケース ---
' 例1: 通常の月末日を基準とした場合 (2026/1/31 -> 2026/2/28)
inputDate = #1/31/2026# ' 2026年1月31日
paymentDueDate = GetNextMonthEndPaymentDate(inputDate)
Debug.Print "基準日: " & Format(inputDate, "yyyy/mm/dd") & _
", 翌月末支払期限: " & Format(paymentDueDate, "yyyy/mm/dd")
' 例2: 月途中の日付を基準とした場合 (2026/1/15 -> 2026/2/28)
inputDate = #1/15/2026# ' 2026年1月15日
paymentDueDate = GetNextMonthEndPaymentDate(inputDate)
Debug.Print "基準日: " & Format(inputDate, "yyyy/mm/dd") & _
", 翌月末支払期限: " & Format(paymentDueDate, "yyyy/mm/dd")
' 例3: 閏年前年の月末日を基準とした場合 (2024/1/31 -> 2024/2/29)
' ※2024年は閏年
inputDate = #1/31/2024# ' 2024年1月31日
paymentDueDate = GetNextMonthEndPaymentDate(inputDate)
Debug.Print "基準日: " & Format(inputDate, "yyyy/mm/dd") & _
", 翌月末支払期限: " & Format(paymentDueDate, "yyyy/mm/dd")
' 例4: 閏年2月29日を基準とした場合 (2024/2/29 -> 2024/3/31)
inputDate = #2/29/2024# ' 2024年2月29日
paymentDueDate = GetNextMonthEndPaymentDate(inputDate)
Debug.Print "基準日: " & Format(inputDate, "yyyy/mm/dd") & _
", 翌月末支払期限: " & Format(paymentDueDate, "yyyy/mm/dd")
' 例5: 通常年2月の日付を基準とした場合 (2025/2/15 -> 2025/3/31)
' ※2025年は平年
inputDate = #2/15/2025# ' 2025年2月15日
paymentDueDate = GetNextMonthEndPaymentDate(inputDate)
Debug.Print "基準日: " & Format(inputDate, "yyyy/mm/dd") & _
", 翌月末支払期限: " & Format(paymentDueDate, "yyyy/mm/dd")
End Sub
「翌月末」計算の落とし穴と、その確実な回避方法(閏年対応)
なぜ、上記のような少し回りくどい方法で「翌月末」を算出する必要があるのでしょうか?それにはVBAの日付関数の特性が関係しています。
【重要】DateAdd("m", 1, [月末日]) の落とし穴
VBAのDateAdd("m", 1, #1/31/2026#)を実行すると、結果として2026/02/28を返します。これは一見正しく見えますが、必ずしも「翌月末」を意図しているわけではありません。
例えば、基準日が#2/15/2026#(月の途中)だった場合、DateAdd("m", 1, #2/15/2026#)は#3/15/2026#を返します。しかし、私たちが本当に欲しいのは「翌月末」、つまり#3/31/2026#です。
DateAdd関数は、指定された日付の「日」の部分を保持しようとします。そのため、基準日が月末日(例: 1月31日)で、翌月に同じ日付(2月31日)が存在しない場合、自動的にその月の最終日(2月28日または29日)に調整されます。これは便利に思えることもありますが、「翌月末」を厳密に求めたい場合には意図しない結果を招く可能性があります。
今回紹介した関数は、基準日が月の途中であっても、常に厳密な「翌月末」を算出します。このアプローチであれば、月末日の日数変動(28日、29日、30日、31日)や閏年の影響を気にする必要がなく、常に正確な支払期限を計算できるのです。
この問題を解決するために採用したのが、「翌々月の1日から1日引く」というテクニックです。
- まず、
DateSerial(Year(baseDate), Month(baseDate) + 2, 1)で、基準日の「翌々月の1日」を算出します。DateSerial関数は、年、月、日を数値で指定して日付を作成するため、存在しない日付(例: 2月31日)を指定しても自動的に正しい日付(3月3日など)に調整してくれます。この特性を利用し、Month(baseDate) + 2とすることで、確実に「翌々月」へ進めます。 - 次に、この「翌々月の1日」から1日を引きます(
- 1)。そうすることで、その前日、つまり「翌月の月末日」が正確に算出されます。この方法であれば、28日、29日、30日、31日といった月末の変動や閏年の29日も自動的に考慮され、常に厳密な「翌月末」が手に入ります。
このロジックは非常に堅牢で、VBAにおける日付計算のベストプラクティスの一つと言えるでしょう。
まとめ:VBAで経理業務の正確性と効率を向上させよう
VBAのDateAdd関数を直接使うだけでは見落としがちな月末日計算の落とし穴も、今回ご紹介した「翌々月の1日から1日引く」テクニックで完全に回避できます。この方法は、月の途中の日付が入力されても、月の最終日が28日であろうと29日(閏年)であろうと、30日であろうと31日であろうと、常に厳密な翌月末支払期限を正確に算出することが可能です。
支払遅延は会社の信用に大きな影響を与えます。VBAによる正確な日付計算は、経理業務の信頼性を高め、ミスのリスクを大幅に削減します。ぜひこのコードをあなたのExcel業務に組み込み、日々のルーティンをより効率的かつ正確にこなしてください。VBAは、経理担当者の強力な味方となることでしょう。