和風スパゲティのレシピ

日本語でコーディングするExcelVBA

生年月日から年齢を計算する - DateDif関数

生年月日から年齢を計算する方法を解説します。

シート関数のDATEDIF関数とは異なり、
VBAのDateDiff関数では一発で求めることができませんのでご注意ください。

VBAのDateDiff関数について

VBAのDateDiff関数はシート関数のDATEDIF関数とは異なり、
経過した年数ではなく単純に「年の差」しか計算できません。

例えば「2024/12/31」生まれの赤ちゃんは翌日「2025/1/1」では当然0歳ですが、
DateDiff関数では「2025と2024の差」である「1」を返してしまいます。


つまりDateDiff関数は、
「Year(日付2) - Year(日付1)」を計算するだけの関数ということです。


また困ったことに、シート関数のDATEDIFは隠し関数(非推奨)であるためか、
WorksheetFunction.DateDifは残念ながら存在しません。

よって以下の3つの方法のどれかで対応することになります。

  • Formulaプロパティを使用してシート関数で計算する
  • EVALUATEメソッドを使用する
  • 自作関数で対応する

Formulaプロパティを使用してシート関数で計算する

A列に生年月日が入っているシートのB列に年齢を計算する場合は、
以下のコードで実行することができます。

Sub A列の生年月日からB列の年齢を計算する()

    Dim ws処理シート As Worksheet
    Set ws処理シート = Worksheets("○○")
    
    Dim 最終行 As Long
    最終行 = ws処理シート.Cells(ws処理シート.Rows.Count, "A").End(xlUp).Row

    Dim 年齢データ範囲 As Range
    Set 年齢データ範囲 = ws処理シート.Range("B2:B" & 最終行)
    
    ' シート数式で計算
    年齢データ範囲.Formula = "=DATEDIF(A2,TODAY(),""y"")"

    ' 値貼り付けで数式を切る
    年齢データ範囲.Value = 年齢データ範囲.Value

End Sub

セルに数式を入力する「Formula」プロパティを使用して年齢を計算し、
直後に値貼り付けで数式を切るコードです。

別に数式が残ってもいいという場合は、.Value=.Valueのコードを削除してください。

 
セル範囲のFormulaプロパティに一括で数式を入力した場合は、
「代入した数式を第1セルに入れ、それを範囲全体にコピー」
したように数式が入力されます。

条件付き書式の数式設定と同じものと思えばイメージしやすいですね。


このFormulaプロパティを利用したコードの素晴らしい点は、
速度面でも通常のループと比較して圧倒的に超速であるという点です。

詳しい説明は下記の記事で行っていますが、
For文で1セルずつ回すより圧倒的に高速で処理が完了します。


今回のDATEDIFに限らず処理するデータ量が多い場合は、
Formulaプロパティを活用していきましょう。

www.limecode.jp


なお、上記コードはTODAY()を使用して当日年齢を調べていますが、
例えば2025年度の年度年齢を調べる場合は以下のコードに差し替えてください。

年齢データ範囲.Formula = "=DATEDIF(A2,DATE(2026,3,31),""y"")"

 

EVALUATEメソッドを使用する

セルに出力したいわけではなく、コード上で年齢が欲しい場合は、
Formulaプロパティは使用できません。

※ だとしても流石に年齢列は作ってしまった方がいいように思いますが。


値を変数などコード上に格納したいだけの場合は、
「EVALUATEメソッド」と呼ばれる機能を使用します。

Dim ws処理シート As Worksheet
Set ws処理シート = Worksheets("○○")

Dim 最終行 As Long
最終行 = ws処理シート.Cells(ws処理シート.Rows.Count, "A").End(xlUp).Row

Dim R As Long
Dim 年齢 As Long
For R = 2 To ws処理シート.Cells(ws処理シート.Rows.Count, 1).End(xlUp).Row

    年齢 = Evaluate("DATEDIF(""" _
        & Format(ws処理シート.Cells(R, 1), "yyyy/mm/dd") & """,TODAY(),""y"")")
    
Next

 
EVALUATEメソッドは「シート数式をVBA上で実行する」メソッドで、
架空のセルに渡した数式を入れた結果を取得したかのように動きます。

上記のコードでは、Evaluateメソッドに

DATEDIF(A列の生年月日,TODAY(),"y")

を渡して動かしています。

聞きなれないメソッドではじめは面食らうかもしれませんが、
慣れると便利なメソッドなので覚えておきましょう。


なお、数式を文字列で管理するため、"を"内で多用することになります。

その場合は「""」と2つつなげることで「"」として動きますので、
"の数に注意して実行してください。

自作関数で対応する

最後は自作関数を作成する方法です。

DATEDIF関数は非推奨の隠し関数であるため、
なるべく使いたくないという方はこちらの方法で実装してください。

' 経過年数を求める汎用関数
Function Get経過年数(日付1 As Date, 日付2 As Date) As Long
    
    Dim mmdd日付1 As Long: mmdd日付1 = Month(日付1) * 100 + Day(日付1)
    Dim mmdd日付2 As Long: mmdd日付2 = Month(日付2) * 100 + Day(日付2)
    
    If mmdd日付2 >= mmdd日付1 Then
        Get経過年数 = Year(日付2) - Year(日付1)
    Else
        Get経過年数 = Year(日付2) - Year(日付1) - 1
    End If
    
End Function
' 実行例
Dim ws処理シート As Worksheet
Set ws処理シート = Worksheets("○○")

Dim 最終行 As Long
最終行 = ws処理シート.Cells(ws処理シート.Rows.Count, "A").End(xlUp).Row

Dim R As Long
Dim 年齢 As Long
For R = 2 To ws処理シート.Cells(ws処理シート.Rows.Count, 1).End(xlUp).Row

    年齢 = Get経過年数(ws処理シート.Cells(R, 1), Date)
    
Next

コードの内容は単純で、日付2より日付1の月日が進んでいるかを判定し、
進んでいれば年数差、進んでいなければそこから1を引いた値を取得しています。


隠し関数を使いたくない場合は、こちらの関数を使用して下さい。