<HOME  <お願い事項   <Access2002 TOP   <Access97 TOP   <サイト内検索
 MS-Access2000超入門部屋--2001年問題? 1



みなさん、VBA使いますか?よく使います?

ぜんぜん使わないで、マクロやクエリで処理を組み立ててる人はあまり気にしなくてもよいことだと思います。
そう考えると、VBAを好んで使ってる人は、こういう配慮は必ずなさっているかもしれませんね・・・。
でも、用心にこしたことはありませんよね。もしよかったらお使いのPCで問題となる可能性があるかどうか検証してみてください。

01/09/22 と日付の入力をすると、 2022/01/09 と表示されてしまうことがある・・・。

なんて経験は、ありませんか?

この問題は以前からいろいろなところで話題になっています。

Accessだけでなく、ExcelやVisualBasicでも、同じようなケースがあるようです。
ネット上で大きく取り上げて解説してらっしゃる方もたくさんいらっしゃいますので、この問題について既にいろいろご存知の方も多いかもしれないですね。

わたしはこれから、VBAで日付/時刻型のデータを扱うときに生じる不具合について書きます。
これをバグと思うかどうかは皆さんの自由です(わたしはバグだとは思ってませんのでこれに関して討論するつもりはありませんです)。
ですが、「バグ」という言葉を使う前に・・・・ご自分のPCで、自身の目で確かめて、症状を確認してみてください。


これからお話することは、Windows(95、98、2000、NT、Me….)で「日付時刻」をどのように扱っているのか、ということに関係してきます。したがって、皆さんお使いのPCの環境によって、まったく無関係の場合と、うわーまじ??という場合と、ばっくり分かれるところだと思います。

Windowsの世界で「日付時刻型」というと、扱いは「数値」になります。

Accessのヘルプで「日付時刻型(Date型)」の解説を読むと、

日付型(Date)の変数は、IEEE 64ビット(8バイト)の浮動小数点数の変数です。西暦100年1月1日〜西暦9999年12月31日の範囲の日付と、0:00:00〜23:59:59の範囲の時刻を表すことができます。日付型の変数には、日付リテラルとして認識可能な任意の値を代入できます。日付リテラルの形式は、#1993 January 1# または#93 Jan 1 #のようにシャープ記号(#)で囲む必要があります。
日付型の変数では、日付はコントロールパネルで設定されている短い日付形式に従って表示されます。時刻はコントロールパネルで設定されている時刻の形式 (12時間制か24時間制) に従って表示されます。

日付型以外の数値型の変数を日付型に変換すると、整数部の値は日付、小数部の値は時刻として表されます。午前0時は 0、正午は 0.5 です。負の整数は1899年12月30日より前の日付を表します。

と書いてあります。数字扱いです。


簡単な実験をしてみましょうか。ヒマだったら試してみてください。

こんな感じのテーブル↓を作って、

データシートビューに切り替えて、1レコードだけ入力します。

で、すぐさまデザインビューに戻ってきて、データ型を「日付時刻型」に変えて、テーブルを保存し、

データシートビューに切り替えると・・・・

こうなりました。↑

つまり、1899年12月31日が1、1900年1月1日が2、1899年12月30日はマイナス1・・・という具合に、内部では数値として扱われているわけです。小数点以下の値を持つことで、時刻まで解釈します。この場合、小数点以下の値は0って解釈されて、00:00:00となります。

仮に、今日の日付とか入力してみて↓

また数値型に戻して保存しなおして↓

見てみると・・・こうなりますね。↓

日付時刻型のフィールドの中は、2001/01/15(にぜろぜろいちすらっしゅぜろいちすらっしゅいちご)という「数字と記号が並んでいる」のではなく、36906.0という数値が入っていて、それを一定の規格に基づいて年月日という形式で表示をしているのです。

では、36906.0をどういう形で表示するか、という規格はどこで設定されているのか・・・。まず「書式プロパティ」っていうのがありますよね。あと、Format関数なんていうのもありました。
要するに、データベースの作り手であるわたしたちが表示方法を設定してやる、という仕組みになっているわけです。

でもー・・・36906.0のまま使う人は、多分いないですよね。

もう、ゼッタイに何らかの形で日付の表示方法を設定する、って言い切っちゃっていいと思います。

なので、AccessとかExcelとか、各ソフトウェア個々に設定するのではなく、もっと根っこの部分で基本的な日付時刻の扱いを設定しています。それが「コントロールパネル」の「地域」という設定です。

「マイコンピュータ」の中の「コントロールパネル」→「地域のプロパティ」を開くと、このPCの中での共通設定項目がいくつか現れます。「日付」欄を見ると、各ソフトウェアの中で特に何も仕様や設定がない場合の、スの状態の日付形式の設定を見ることができます。

2000年問題で苦しい思いをなさった方は、「短い形式」も「長い形式」も、西暦4桁で表示するようになさっているかもしれませんね。みなさんのPCはどうなっていますか?
わたしのはこうなってました↓

あ、同じにする必要はありませんですよ。とりあえず、「短い形式」がyy/mm/ddになさってる方はちょっと注意、ってことです。


では、Accessの方に戻って、もうひとつ実験をしてみましょう。
わたしは、WindowsNTあんどAccess97、Windows2000あんどAccess2000、Windows98あんどAccess2000という3パターンで試してみました。でも、必ずしも「WindowsとAccessのバージョンによって限定される現象」ではありませんので、ぜひとも皆さんのPCで確認をしてみてくださいね。再現されなければそのPCはとりあえず安心、ってところではないでしょうか。
以下の解説で掲載している図は、WindowsNTあんど97の組み合わせですが、他の2パターンでもほぼ同じ現象を確認することができました。

モジュールを新しく作成し、プロシージャをひとつ作ります。

こんなふうに↑簡単なSubプロシージャを書き込みます。プロシージャの作り方がわからないという人は、カーソルがピカピカしているところに上のように一文字ずつ入力してください。
2001年9月22日、というつもりで、01/09/22と入力したとします。

多分、改行するとこんな↓ふうな表示になるんじゃないかと思います。いかがでしょう?

じゃあ、変数AAAにどういう値が入ってくるのか、試してみましょうか。

ええと、手っ取り早くデバッグウィンドウ(イミデイトウィンドウ)を使いますかね。

4行目にDebugコマンドを入力して、変数AAAの中身を教えろ、と命令します。

で、デバッグウィンドウ(もしくはイミデイトウィンドウ)を表示させます。メニューバーの「表示」ってとこ見ればありますよ。

このプロシージャの名前は、heboheboですので、heboheboと打ってEnterキーを押します。

と、変数AAAの中身が表示されるはず・・・あ?12時7分16秒?

・・・どうやら・・・割り算やっちゃってるみたいですね。1割る9割る22・・・小数点以下の数字は、時刻になるんですよね。
VBAで日付を直接入力するときは,#で囲まないとこういうことになっちゃうのかしら。え?こんなの常識ですか?あ、これは失敬。
まあー・・見ようによっては割り算に見えないこともないですもんね。

じゃあ、お説に従って↑イゲタで囲んで・・・

・・・な、なんか↑この時点で既に妖しいんですけど・・・


実験してみると、なんじゃこりゃー。↑

22年1月9日???なんでこうなるの???


んじゃあ2001年09月22日、と、西暦四桁全部入力してみるか・・・。

わたしのは↓こうなりました。皆さんのはどうですか?

なんか・・・↑年と月と日が入れ替わってるように見えますが・・・。

でも、試してみると、

デバッグウィンドウには2001/09/22が↑西暦2桁表示で出てきました。これなら正しいですよね。
日付をいろいろ変えて、それぞれどういう表示になるか試してみてください。


ここまでお読みいただいて、あ、なるほど・・・っておわかりいただけた方も多いんじゃないかと思います。
日本で西暦日付の表示をする場合、たいてい yy/mm/dd か yyy/mm/dd か yyyy/mm/dd か・・・とにかく、年 月 日の順ですよね。

でも、たまに、海外の書類とかで、Jan. 4.01なんて表記、見かけません?
そう・・・コンピュータ一般で言うところの「英語(US)表記」というのは、mm/dd/yy(mm/dd/yyyy)なんです。

ExcelとかWordなんかの日付の書式にも、こういうパターンあると思います。

どうやら・・・Accessでは、テーブルとかクエリとかフォームとかのデザインビューとか、式ビルダとかでは「yy/mm/dd」が標準書式として扱われますが、VBAのエディタでは「mm/dd/yy」と解釈されるようです。

どうでしょう。みなさんのPCのVBAエディタだと、mm/dd/yyってなります?
これは・・・先の「コントロールパネル」の設定がyyyy/mm/ddでも、入力された日付の西暦が2桁だとmm/dd/yyになるみたいですね・・・。何でなのかはわたしにはわかんないんですが、どうやらそういう仕様らしい。。。西暦を4桁入力すればとりあえず区別してくれるみたいです。だから、2001/09/22って入力したときはちゃんと「01/09/22」って出てくれたんですね。