勤続年数を計算する方法

Excelで2つの日付の差を求める場合に、勤続年数のように年月数で求めたい場合、結構難儀します。

方法としてDATEDIF関数で引数”YM”を指定する方法と、EXCEL関数を複数組み合わせる方法の、2通りがあります。しかしいずれの方法も問題があります。それは、DATEDIF関数は正しく計算できない場合があり、EXCEL関数を組み合わせる方法はメンテナンスが大変です。

以下ではこのような問題を解消したVBAで作成した関数を紹介します。

DATEDIF関数のようにセルに入力して勤続年数を求めることも可能ですし、VBA内の処理で使うことももちろん可能です。

なお、DATEDIF関数の何が問題なのかも簡単にですが最後に説明します。

Excelの日付計算は人間の感覚と違う場合がある

先に、Excelは日付の計算と人間の感覚は違う場合がある、ということを書いておきます。

2つの日付の差を求める場合、一般的な感覚では「その間の日数」を求めます。例えば、1月1日と1月2日の日数差は1日です。これはExcelの仕様と同じです。

ところが、「1月1日から1月2日までは何日ありますか?」と聞かれたら、2日、という答えがほしいです。勤続年数の考え方はこれです。ここがExcelの仕様とは異なります。

日数差の場合は2つの日付自体を含めませんが、何日間かを求める場合(勤続年数の考え方)は、指定した日付自体を含めます。

このように人間は感覚的に日数差なのか何日間なのかのどちらを要求しているかを理解できますが、Excelの日付の処理は「日数差」を求めます。

そのため、DATEDIF関数を使う場合「DATEDIF(開始日付, 終了日付 + 1, “YM”)」なんてことをして+1の調整を入れる妙なテクニックが必要になります。

以下のVBAの関数は勤務年数の考え方で作成しています。「終了日付+1」のような記述は不要になります。


VBAでの勤続年数の算出方法

以下は2つの日付の差を求める関数で、引数に開始日付と終了日付を渡すと、ExcelのDATEDIF関数で単位を”YM”で指定した場合のように「〇年〇か月」という結果を返します。

DATEDIF関数にはいくつかの問題や使い勝手の悪さがありますが、以下のようにそれらを解消しています。

  • うるう年に対応している。
  • 日数差の1か月を正しく計算する。(1/28~2/27は1か月と判定するようにしている。Excelは2/28にならないと1か月とみなさない。)
  • 終了日付+1、のような日付調整をしなくてよい。
  • 開始日付と終了日付が逆転している場合はエラーにならずマイナス差を返すようにしている。

使い方

VBAでの使い方

VBAで使う場合のサンプルです。引数に開始日付と終了日付を渡して、戻り値で「〇年〇か月」を受け取ります。

シートでの使い方

この関数を勤続年数を表示したいブックか、Personal.xlsbに保存しておけば、勤続年数を表示したいセルに「=DateDifYM(A1,B1)」のように書くことでシート上でも勤続年数を表示することができます。

DATEDIF関数での勤続年数の算出は何が問題か?

先にも書きましたが、一般的には勤続年数などの日付の期間を求める場合にはDATEDIF関数が紹介されますが、いくつかの問題があります。

大別すると4つ挙げられます。

  1. 日付が逆転しているとエラーになる。
  2. うるう年の場合に正しく計算できない場合がある。
  3. 単位の6種類のうち4種類(”M”、”MD”、”YM”、”YD”)で正しく動作しない場合がある。
  4. そもそもDATEDIF関数は非推奨。(2002年が最終版のLotus 1-2-3との互換性のために残してある)

DATEDIF関数の使い方ですが、「=DATEDIF(開始日, 終了日, 単位)」の数式で扱います。開始日>終了日の場合はエラー(#NUM!)になります。

「単位」には6つあります。

単位 戻り値 補足
Y 年数差 同年の場合は0が返る。
M 月数差 同月の場合は0が返る。月末日同士で、かつ、開始日の日>終了日の日の場合に1か月ずれる。
D 日数差 同日の場合は0が返る。セルの引き算「=A1-B1」と同じ。
MD 年月を除いた日のみの日数差 うるう年の場合に正しく動作しない場合がある。(2000/1/31~2000/3/1で-1など)
YM 年と日を除いた月のみの月数差 月末日同士で、かつ、開始日の日>終了日の日の場合に1か月ずれる
YD 年を除いた月日での日数差 うるう年を考慮せずに計算されるため、うるう年の場合は1日ずれる

補足に書いた通りですが、いろいろと問題があります。既知の問題ですがずっと放置されているため、Microsoftが直すことはおそらくないでしょう。

勤続年数を求める場合は月末日になることも多いでしょうから、DATEDIF関数を使う場合は事前に問題がないか確認した方がいいと思われます。