| 「Accessの日付型の2001〜2012年問題」 |
皆様は当然気付かれていると思いますが、私 (pPoy) は昨年迄、事の重大さに気付かずにおりました。これは、2000年問題の時に言われていた事です。ただし、その時は日付型データを文字列型に格納して扱うときの注意が強調されるあまり、この「日付型」自体の不思議な動きに気付かれた方は少ないのではないでしょうか?(私もその1人です)
以下に、不具合とその発生する条件を書きます。 これは Access のみに留まらず、Oracle でも、MS-SQLでも同様です。Excel でも、VBA を使用して RecordSet を作成し、 日付型データを検索・抽出した場合、起こり得ます。 私の場合、もっぱら Access を使用しておりますので、Access の場合の注意事項についてまとめてみます。 この現象は、マイクロソフトのサポート技術情報にも公開されています。
「今回新たに気づいた不具合」 1. 「コマンドボタンウィザード」による不具合
このままで、[登録日]の中の、 "2001/02/03" を検索した場合、
- [フォームの操作]-[フォームを開く]-[検索結果]-[特定のレコードを表示する]
「検索の対象が日付型の場合」 ウィザードの記述は、
- stLinkCriteria = "[登録日]=" & "#" & Me![検索日] & "#"
DoCmd.OpenForm stDocName, , , stLinkCriteria
帰ってくる結果は、地域の日付設定の短い形式が "yy/mm/dd" だった場合、
"2003/01/02" が検索されてしまいます。(もちろん、登録されていなければダメですが) ここの、 Me![検索日] の部分は、
Format(Me![検索日],"yyyy/mm/dd") と言う感じで、
明示的に書式を設定して渡すように書き直すと、
短い形式が "yy/mm/dd" の場合、きちんと 2001/02/03 を検索します。
2. 検索結果を 一旦日付型変数に格納後、検索した場合の不具合
- Dim myDate as Date
myDate = Format(Me![検索日], "yyyy/mm/dd")
stLinkCriteria = "[登録日]=" & "#" & myDate & "#"
DoCmd.OpenForm stDocName, , , stLinkCriteria
これは、ウィーザードで作った時と同様、実行時に "mm/dd/yy" に翻訳されてしまうため(?)エラーとなります。
再度書式設定すれば OK。でも2度手間です。
つまり、
stLinkCriteria = "[登録日]=" & "#" & Format(myDate, "yyyy/mm/dd") & "#"
と、修正する必要があります。
3. 検索結果を一旦バリアント型に格納後、検索実行すればOK
- Dim myDate as Variant
myDate = Format(Me![検索日], "yyyy/mm/dd")stLinkCriteria = "[登録日]=" & "#" & myDate & "#"
DoCmd.OpenForm stDocName, , , stLinkCriteriaこの場合は、まるっきり不都合は起こりません。
2.の式の場合、データの宣言部分を Variant にする方が修正が簡単かもしれません。
これらを簡単に確認する方法は、
モジュール入力画面(VBE画面)を表示して、「デバッグウィンドウ」を表示し、
「イミディエイト ペイン」(ウィンドウの下半分) に、?#01/02/03# と入力し、エンターを押します。
ここで、表示された日付が、明示的に型指定しない場合の結果です。
○ マイクロソフトのサポート技術情報に記述があります」
タイトル: [VB] 日付リテラルにより日付を設定するときの注意
文書番号: 413605
URL: http://support.microsoft.com/default.aspx?scid=kb;JA;413605 です。
たとえば(現在が2001年だとして)"yy/mm" 形式で、テキストボックスに入力したデータを検索した場合
- 《表示上は "yy/mm" でも、実際は全ての日付をデータとして持っている》
これは Access が、指定した書式に関係なく、実際に格納されている日付データを 「日」 の部分まで含めて、持っているからです。 年/月のみ "yy/mm" の書式で入力した場合、Access は自分で後の 日 部分を "01" として、補完します。 しかも、US式で Access は検索するわけですから、最初の数字は月として判断し、次の数字は日と判断します。 入力されなかった年の部分は、自動的に システム年 とします。 それで、入力者の意図しなかった、不思議な年月が検索されてしまうのです。 つまり、日付書式の「短い形式」の設定が "yy/mm/dd" であり、且つ検索の書式が "yy/mm" の場合意図した結果とは異なる検索結果が出てしまうのです。 これを避ける為には、常に明示的に日付の書式を指定することが必要です。尚且つ、自分で日付部分も持たせる必要があります。
- テキストボックスに、"01/02"と入力した場合、
検索結果は、2001年1月となってしまいます。- テキストボックスに、"02/12"と入力した場合、
検索結果は、2001年2月となります。
例) myDate = Format(Me![検索日] & "/01","yy/mm/dd") と修正します。
(テキストボックスの書式が "yy-mm" の場合は、Me![検索日] & "-01" の様に、書式に合わせて書き換えてください。)
☆ 感想をお知らせください (直接ブラウザから送信致します。メールアカウントは不要です。)
form mail はこちら
☆ Microsoft(株) の文書番号変更に伴い、このページのリンク先を変更しました。 2003/06/28 pPoy