1. 「人」テーブルの定義
以下のような、「人」テーブルがあるとする。
- id : 主キー
- 名前
- 性別id : 01 男、02 女
- 生年月日
各々の「人」に対して、次のことを知りたい。
- 現在の年齢
- 今年度末に何歳になるか?
2. 年齢を求めるための関数を定義
現在の年齢を求める関数
生年月日から年齢を求めるには、
「今年の誕生日が来ているかどうか?」
がわかればよい。
そのため、
- 「指定された日付に、何歳になっているか求める」関数を定義し、
- 現在の日付を渡すことによって、
- 今の年齢を求める。
関数の定義は、
- 「データベース > モジュール」
において、新規モジュールを作成する。
日付の関数については
- 「VB 日付操作」
を参考にした。
' ある誕生日の人が、指定した日付に何歳になっているか返す。 Function Age(birthday As Date, theDate As Date) As Integer If AfterThisYearsBirthday(birthday, theDate) Then Age = Year(theDate) - Year(birthday) Else Age = Year(theDate) - Year(birthday) - 1 End If End Function ' 指定された日付に今年の誕生日が来ているか? Function AfterThisYearsBirthday(birthday As Date, theDate As Date) As Boolean If Month(birthday) < Month(theDate) Or _ (Month(birthday) = Month(theDate) And Day(birthday) <= Day(theDate)) Then AfterThisYearsBirthday = True Else AfterThisYearsBirthday = False End If End Function
年度末における年齢を求める関数
次に、年度末に何歳になっているか知りたい。
上記と同様に「指定された日付の年度末を返す」関数を書く。
' 指定された日付の年度末の日付を返す Function Nendomatu(theDate As Date) As Date Const DATE_331 = "/3/31" If 4 <= Month(theDate) And Month(theDate) <= 12 Then Nendomatu = CDate(Year(theDate) + 1 & DATE_331) Else Nendomatu = CDate(Year(theDate) & DATE_331) End If End Function
3. クエリから関数を呼び出す
上記の関数を、クエリから呼出すようにする。
- 「人」テーブルを対象にしたクエリを作成し、
- 「年齢、年度末の年齢」を求めたい列で、右クリック > ビルド... を選択し、
- 式ビルダを呼出す。
左下を見ると、「関数」フォルダに、先ほど作成したモジュール名が表示され、定義した関数が属しているのがわかる。
それぞれ以下のように定義する。
年齢: Age([生年月日],Now())
年度末の年齢: Age([生年月日],Nendomatu(Now()))
クエリの結果。今日の日付は 2009.4.13 。
追記(2009.4.25) : 学校の学年においては、 4/1 生まれは早生まれになるので、年度末の翌日における年齢を求める。
年度末の年齢: Age([生年月日],nendomatu(Now())+1)
(参考: 法制執務コラム集「4月1日生まれの子どもは早生まれ?」)
4. クエリの中だけで計算するには
「生年月日から年齢を計算する方法」には、次のようなクエリが書かれていた
年齢: IIf(Right(Format([誕生日],"yyyy/mm/dd"),5)>Right(Format(Now(), "yyyy/mm/dd"),5),DateDiff("yyyy",[誕生日],Now())-1,DateDiff("yyyy", [誕生日],Now()))
(via 生年月日の入力によって年齢を出したい。 --Access Club 超初心者 FORUM—)
うへぇ~、一行だと読みにくい… (+_+)
そもそも、これは何だろう?
Right(Format([誕生日],"yyyy/mm/dd"),5)
関数をテストしてみる。
Debug.Print CDate("1/1") ‘ 2009/01/01 Debug.Print CDate("1") ‘ 1899/12/31 Debug.Print CDate("366") ‘ 1900/12/31 Debug.Print CDate("0") ‘ 0:00:00
CDate のヘルプを見ると、
CDate 日付型 (Date) 任意の有効な日付式
「日付式」とは、
日付として解釈可能な式。… 日付と解釈できる文字列、
結果を見ると、そこまで無理に解釈しなくても…と言いたくなるような仕様。 ^^;
日付の内、「年」を省略すると、「現在の年」と解釈されるようだ。
5. シンプルな計算方法
「生年月日から年齢を計算する簡単な計算式:ITpro」には、次のような計算式が書かれている。
(今日の日付-誕生日)/10000の小数点以下切捨て。
なるほど、「年月日」をわざと一連の数値として扱う方法のようだ。確かに、年月だけ見れば、年月を各々二桁で表現しているなら、誕生日が来ていれば、今日の日付よりも誕生日の数値が小さくなる。
先ほどの方法でパフォーマンスが悪ければ、こちらに変更しようかな。
ただし、次の注意点が述べられている。
「誕生日の前日が終了する瞬間(すなわち誕生日をむかえる午前0時00分の直前)に1歳を加えることになる」の部分の解釈には前日に1日加えると解釈される場合と当日に1日加えると解釈される場合の2種類があるようです。特に自治体においては前者で解釈される場合が多いとのことです。
(同上より)
ん?これは自治体の特殊ルールで、「年齢」と「年齢をどう解釈するか」とは別の話だよねぇ。
0コメント:
コメントを投稿