0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Accessで満年齢を求める関数を作る

Last updated at Posted at 2021-02-11

意外と難しい年齢計算

 ある日を基準日として満年齢を計算することは事務を行う中で意外と多くあります。
 会社などでは、社員や顧客の生年月日をデータベース化しているので、一見年齢を求めるのは簡単そうですが、日本で法令に沿った満年齢を求めることは意外と難しいのです。
 日本国内で年齢計算の根拠になっているのは「年齢計算ニ関スル法律」という法律です。
 これによると生まれた日から年齢を計算しはじめることになつているので、誕生日の前日に満一歳、年をとることになります。
 事務作業でデータベース処理を行う際、Accessを利用することが一般的ですが、これらには経過年数を求めるDatediff関数があり、Datediff("yyyy",誕生日,基準日)とすると、満年齢が求められそうです。
 しかし、この関数では期間を計算する際、特定の基準を何回、経過しているかを求めるだけです。先の事例では誕生日から基準日までの間の1月1日を何回経過したかを求めているだけなので、基準日が誕生日を過ぎていない場合、年齢を一歳多くカウントしてしまいます。
 このため、ある日の満年齢を求める関数をVBAで作成します。
 

資料集めとテストケースの設定

 さきの根拠法の解説だけでは、具体的なブログラムを組むには参考となる適切な事例があげられていない。
 そこでネットを調べてみると参議院法制局のサイトの「法律の窓」というコラムに「4月1日生まれの子どもは早生まれ?」という記事を発見。この記事では4月1日生まれが早生まれになることを事例に年齢計算の法的根拠を解説しています。
 この記事を元にテストケースを設定すると、2020年4月1日生まれの人が満六歳になる2026年3月31日の前後で正しく満年齢が計算されているか確認すれば良さそうです。

テストケース
 年月日     年齢
 2026/3/30   5才
 2026/3/31   6才
 2026/4/1    6才

満年齢を求める手順

 満年齢を求める手順は
  基準日の年から生年を引いて経過年数を求める
  基準日が誕生日の前日を過ぎているかを確認
   もし、誕生日の前なら経過年数から1年引いたものを満年齢とする
   そうでなければ、経過年数を満年齢とする。
 となります。

実際のコード

 以上の検討を行い作成したAccessで満年齢を計算する関数はつぎのとおり。
 使い方 getAge(誕生日,基準日)
 戻り値 long
test_getAgeがテストのためのコードです。

getAge.vba

Option Compare Database
Option Explicit
 
Function getAge(BirthDay As Date, tmpDay As Date) As Long
'参議院法制局のコラム「4月1日生まれの子供は早生まれ?」を参考とした。
'「年齢計算に関する法律」によると出生日を一日目として含める。→満年齢がカウントアップされるのは誕生日の前日。
'tmpdayは基準日
 
    Dim retAge As Variant   'エラーが返ることを想定しvariantとする。
    
    'BirthdayからtmpDayまでに経過した1月1日の数を返す。
    retAge = DateDiff("yyyy", BirthDay, tmpDay)
    
    '基準日が誕生日を過ぎているか確認する。
    '基準日と誕生日の前後関係を簡単に比較するため日付型の変数同士の比較にする。
    If tmpDay < DateSerial(Year(tmpDay), Month(BirthDay), Day(BirthDay) - 1) Then
    '基準日が誕生日を過ぎていない→満年齢を-1する。
        retAge = retAge - 1
    End If
    
    getAge = CLng(retAge)
    
End Function
 
Sub test_getAge()
'2020/4/1生まれの人を想定
'2026/3/30まで5歳
'2026/3/31以降6歳
'テストケースは2026/3/30,3/31,4/1
 
    Dim curDate As Date
    Dim tmpCnt As Long
    
    curDate = #3/30/2026#
    
    For tmpCnt = 0 To 2
        Debug.Print tmpCnt, "birthday:2020/4/1-> 今日は", curDate + tmpCnt, getAge(#4/1/2020#, curDate + tmpCnt) & "才"
    Next
    
    Debug.Print "2026年1/1の満年齢", getAge(#4/1/2020#, #1/1/2026#) & "才"
    Debug.Print "2026年5/3の満年齢", getAge(#4/1/2020#, #3/3/2026#) & "才"
    Debug.Print "2026年11/3の満年齢", getAge(#4/1/2020#, #11/3/2026#) & "才"
 
End Sub


EUCなどの問題、お願い

 EUCなどといって、事務現場にデータ加工を担当させることが一般的になってきていますが、このような法令に基づく計算については、組織として計算方法を職員に示しておく必要があると思いますが、皆さんの会社ではどうでしょうか。
 村上陽一郎東大名誉教授が『科学の現在を問う』(講談社新書現代新書)で東海村臨界事故を題材に現場任せの「カイゼン」の危険性を指摘されていますが、適切な社員教育を行ってプログラムの基礎的なスキルの向上と関連する知識の普及をはからないEUCもRPAも同じような問題をはらんでいると思います。
 最後に、プログラムに誤りなどがありましたら教えてくださると大変助かります。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?