当ACCESS相談室では主に初・中級者の方に向け、ACCESSを活用していく上でのさまざまな疑問に対して、的確なアドバイスを提供していきます。
|
■クエリ/SQL編
VBAで次のようなSQLを作り、試してみましたが、「該当レコードがない」といわれてしまいます。2001年5月3日のデータが存在しているのは確認済みなのですが。出荷予定日フィールドは日付型フィールドです。
Dim datOrder As Date Dim strSQL
As String Dim rst As DAO.Recordset
datOrder =
#01/05/03# strSQL = "SELECT * FROM tblOrder WHERE
[出荷予定日]
= #"
& datOrder & "#" set rst =
CurrentDb.OpenRecordset(strSQL)
|
※は、実際は1行のところをページ幅の都合上折り返している事を示しています。
これには、2つの問題があります。1つは、VBAおよびJet
SQLの日付フォーマットについて誤解があることです。もう1つは、Windowsの日付フォーマットとSQLの日付フォーマットの不一致です。
●正しく日付フォーマットを理解する
まず、VBAおよびJet SQLの日付フォーマットについて見てみましょう。Access
IDEのイミディエイト・ウィンドウで、
datOrder = #01/05/03# ? datOrder
|
と入力してみてください。
と表示されたはずです。
あなたが2001年5月3日のつもりで入力した日付は違っていたのです。VBAの(SQLでも同じ)日付フォーマットは
"#MM/DD/YY#" あるいは "#MM/DD/YYYY#"
です(YYは年、MMは月、DDは日)。これはアメリカの標準的な日付フォーマットにもとづいています。 今まで"#98/05/03#"は、正しく1998年5月3日と解釈されていましたね。だから誤解されたのだと思いますが、これは、98などというあり得ない月数が出てきたので、YY/MM/DDという入力なのだと、システムが自動的に解釈し直してくれていたに過ぎません。"#01/05/03#"の場合にはそうした手がかりがありませんので、標準的なフォーマットだと解釈して、2003年1月5日と解釈されてしまうのです。 こうした誤解を避けるためには、年をきちんと4桁で入力することです。
●WindowsとSQLの日付フォーマットの不一致
次にもう1つの問題です。今、最初のコードを
と直しました。これで日付の解釈の誤りはなくなりました。ところが、それでもやはり、レコードセットに該当レコードは含まれてきません。なぜでしょう?
イミディエイト・ウィンドウで確認してもわかるとおり、画面に表示される日付フォーマットは通常
"YY/MM/DD"
となっています。これは日付変数の値を文字列中に展開する場合でも同じです。ですから、コード中で組み上げたSQL文字列であるstrSQL変数の内容を見ると、
SELECT * FROM tblOrder WHERE [出荷予定日]
= #01/05/03# |
となっているはずです。おやおや、これでは意図と違って2003年1月5日と解釈されてしまいます。日付型変数の内容が
"YY/MM/DD" のフォーマットで展開されるのは、Windowsのコントロール・パネルでの [地域] - [日付] -
[短い形式] が "YY/MM/DD"
になっているからです。といって、この設定を変えてしまうのは得策ではありません。コントロール・パネルのこの設定はさまざまなソフトウェアに影響を与えるからです。
いちばんよい解決策は、Format関数を使ってSQL文を次のような形で組み上げることです。
strSQL = "SELECT * FROM tblOrder
WHERE [出荷予定日] = #" & _
strSQL = Format$(datOrder, "MM\/DD\/YY")
& "#" |
これで、正しい結果が得られるようになります。
ところで、最初のコードでも、日付が "#00/05/03#"
のときには、意図したとおりに動作します。システムがきちんと2000年の日付だと解釈できるからです。つまり、2000年以前の日付を扱っているかぎり一見正しく動作しているように見えるのです。ところが、2001年以降の日付を扱うようになったとたんに問題が露呈します。これを俗に「2001年問題」と呼んでいます。結局、潜在的なバグ・コードなわけですから、正しく動いているシステムも、過去のコードまで含めて点検する必要があるでしょう。
※参考までに、Access 97とAccess
2000では、"#01/01/29#" までは2029年1月1日に、"01/01/30#"
からは1930年1月1日と解釈されます。
|
1/3 |
|
本サイト掲載の記事・写真等の無断での転載・複写を禁じます。
本ページは、技術評論社様のご好意により掲載許可をいただいたものです。
| |