【PowerQuery】生年月日から基準日時点の年齢を出力するカスタム関数

PowerQueryカスタム関数の練習で、生年月日から基準日(又は現在日付)時点の年齢を出力するものを考えてみました。

(1) 条件

  • ExcelのDATEDIF関数と同じ結果が得られること。
  • 関数に設定する引数は、birthdate(生年月日)、basedate(基準日)の二つ。但し、基準日は省略可能とし、省略した場合は現在日付を設定する。

(2) 作成手順(要約)

 ①生年月日から基準日間の日数を取得

 ②期間の日付リストを作成

 ③年齢の計算(②から生年月日の数をカウント、但しうるう年2/29生まれの場合は

  2/28でカウント)

 

(3) コード

空のクエリを挿入して、詳細エディターに以下を貼り付けたらそのまま使えると思います。関数名は Age としています。(決まりはありません)

(birthdate  as date, optional basedate as date ) =>
let
   // ①生年月日から基準日間の日数を取得
   durationx = if basedate <> null
                // basedate入力の場合= basedate~birthdateの日数
               then  Duration.Days( DateTime.Date(basedate)-birthdate ) 
                // basedate未入力の場合= 現在日付~birthdateの日数
               else  Duration.Days( DateTime.Date(DateTime.LocalNow())-birthdate ) ,
 

   

// ②期間の日付リストを作成
   dateList =  List.Generate(
                             ()=> [ days=0, dateYmd = birthdate ],
                             each [days]<= durationx,
                             each [days=[days]+1, dateYmd = Date.AddDays([dateYmd],1)],
                             each [dateYmd]
                                   ),
       
   // ③年齢の計算(②から生月日の数をカウント、但しうるう年2/29生まれの場合は2/28でカウント)
   Ages =  if Date.Month(birthdate)<>2 and Date.Day(birthdate)<>29 
            
           then List.Count(
                 List.Select( 
                      List.Select(dateList,each Date.Month(_)=Date.Month(birthdate))
                               ,each Date.Day(_)=Date.Day(birthdate)
                                       )
                                    )-1
                           
            // うるう年の対応
           else List.Count(
                     List.Select(
                       List.Select(dateList,each Date.Month(_)=Date.Month(birthdate))
                              ,each Date.Day(_)= Date.Day(birthdate)-1 // 2/28をカウント
                                     )
                                   )
in
    Ages
 

 

エディターに貼り付けた関数は下図のよう表示されます。

f:id:shusoshin:20211203175748g:plain

(4) 関数の実行

作成した関数が想定通りの結果となるかテストしてみます。

テスト①生年月日:1981/10/28 基準日:2021/4/1 として呼び出しをクリック。

f:id:shusoshin:20211203175955g:plain

39歳となり、正しく計算されました。

f:id:shusoshin:20211203180002g:plain

テスト②生年月日:1981/10/28 基準日:省略 として呼び出しをクリック。

f:id:shusoshin:20211203180008g:plain

40歳となりました。基準日を省略した場合は現在日付(テスト時点は2021/12/2)で計算されますのでこちらもOKです。

f:id:shusoshin:20211203180015g:plain

 

(5) 実際の使用例

下図は、ワークシートからエディターに取り込んだデータです。今回は検証のためにDATEDIF関数で計算【 =DATEDIF(生年月日,基準日),"Y") 】した結果をdatedif列に置いています。

f:id:shusoshin:20211203180020g:plain

列の追加タブ → カスタム列 をクリックします。

f:id:shusoshin:20211203180027g:plain

作成したカスタム関数 Age を使用します。ageと入力すると下図のように候補に出てきます。

f:id:shusoshin:20211203180035g:plain

下図の通り数式を入力します。生年月日 列は右の使用できる列でクリックすることで選択できます。今回ワークシート上のDATEDIFの基準日を2021/4/1としましたので合わせて、#date(2021,4,1) とします。省略する場合は、null を入力する必要があります。

f:id:shusoshin:20211203180042g:plain

 

年齢列が追加されました。datedifの結果と一致することが確認できました。最下行の山田四郎の生年月日は2012/2/29 (うるう年)としていますが、これも正しく計算されています。

f:id:shusoshin:20211203180048g:plain

(6) さいごに

下図のようにカスタム関数クエリ上で右クリック→コピーした後に、他のブックのエディターへ貼り付けることが可能です。汎用的に使用するカスタム関数をひとつのブックに集めておくと便利かもしれません。

f:id:shusoshin:20211203180056g:plain

以上です。