[[20070604224521]] 『IsDate関数でのカレンダーチェックにて』(HT) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]

 

『IsDate関数でのカレンダーチェックにて』(HT)

 いつもお世話になっております。
 エクセルシートを擬似画面に見立てオンライン処理を行っているエクセルブックがあります。
 その中で、日付8桁を入力するセルがあり、その入力値に対し、IsDate関数を使用してチェックをしておりますが、
 ExcelVBA中で
 If IsDate(l_strHiduke) = False Then
    処理A
 Else
    処理B
 End If

 という処理があり、入力値が"00000101"でもTrueを返してしまい、正しい判定が行えません。
 (セルの入力値をl_strHidukeに代入する際に「yyyy/mm/dd」形式に事前に変換しています。
 l_strHidukeはString型にて定義済み)

 ExcelVBAのヘルプでIsDate関数を調べてみましたが、以下のように記載がありました。

 Microsoft Windowsで有効な日付の範囲は、西暦100年1月1日から西暦9999年12月31日までです。
 この範囲は、オペレーティングシステムによって異なります。

 上記のルールに基づくと、「西暦0000年1月1日」はIsDateの本来の戻り値はFalseだと思うのですが、
 Trueを返しているのが現状です。
 ちなみに
 「2006年2月29日」はFalse
 「2004年2月29日」はTrue
 「000A年1月1日」はFalse
 「2007年3月31日」はTrue
 「2007年13月1日」はFalse
 等、通常のカレンダーチェックがIsDate関数にて、正常に行われることは確認済みです。
 条件文を駆使してロジックで対応する事は造作も無いとは思いますが、折角Excel環境下での処理なので
 出来れば関数で処理したく考えております。
 後学の為という観点からも知りたく思いますので、この解決方法につきまして、もし御存知の方が
 いらっしゃいましたら、御教授頂きたく思います。
 (WindowsXP,Excel2000)

 外しているかもしれませんが、、、
 こういうことでしょうか???
 
 =NOT(ISERR(--A1))
 
 (キリキ)(〃⌒o⌒)b

 >「yyyy/mm/dd」形式に事前に変換しています。
この手法の問題だと思います。
どのようにされているのでしょう。
(みやほりん)(-_∂)b


 >「西暦0000年1月1日」
 1900年、2000年のどちらかで処理しているみたいです?
 これも俗に言う2000年問題の尾を引いているのでしょうね?

 st = "00000101"
 MsgBox CDate(Format(st, "yyyy/mm/dd"))
 MsgBox DateSerial(Left(st, 4), Mid(st, 5, 2), Right(st, 2))

 DateSerialで、年号と該当数字、月と該当数字などを個々に比較したらどうでしょう?
 BJ

 職場がインターネットの使用出来ない環境の為、ご返事が遅くなりました。

 ★キリキさん★
 確かにこれなら正常な値を返します。私の不勉強で恐縮なのですが、ISERRで使用している引数の(--A1)とはどういう意味なのでしょうか?
 ISERRは何度か使用している関数なので知ってはいたのですが、この引数に関しては、実は初めて見ました。

 ★みやほりんさん★
 BJさんも記述されていますが、Format関数を使用して変換しているのをソース上で確認しました。
 実験的に、Excelシート上にコマンドボタンを配置し、VBEで以下のコードを直接記述して試してみたのですが、
 やはり結果は同じくTrueに。。。

 Private Sub テスト_Click()
   MsgBox (IsDate("0000/01/01"))
 End Sub

 ちなみに"0000/01/01"を"9999/12/31"に置換して実行しましたが同じくTrueになりました。
 日付だから、という固定概念で普通にリアルな西暦を入れていたので気付かなかったのですが、同僚から
 「こんな値入れたら、通っちゃいました♪」と指摘され、再現したのでビックリしてしまいました。
 過去ログを検索したのですが、こういう値で試された人の事例そのものがなく、単純なケースですが
 何か盲点を突かれた感じがして躍起になって調べてみたものの、情報が全く無かったので投稿した次第です。

 ★BJさん★
 やはり年号、月、日で分割してチェックするしかないのでしょうね。キリキさんの御提示のものは正しいチェックが出来るのですが、
 如何せん、私自身、説明出来ないコーディングなのが悔しい(>_<)
 西暦年の部分だけがどうやらおかしいようです。EXCELシート上でDATE関数を使用して同様に以下のように試してみました。

 =DATE(0000,1,1)
 =1900/01/01

 =DATE(1900,1,1)
 =1900/01/01

 やはり変ですねぇ。
 会社(客先)のチームリーダーにこの件を相談したのですが、「この日付をキーにしたデータベースのデータ自体が
 絶対に存在しないし、最終的にエラーとしてメッセージが返るから、別にこのままでいいんじゃないですか?」
 と言われてしまい、何かウヤムヤにされてしまいました。
 ただ、日付チェックの関数としてリリースされているわけですし、結構頻繁にしようしているものでも
 ありますので、本心としては今後の為にも何か対策を打てないか?と感じてはいます。

 折を見てマイクロソフトに問い合わせてみようかと考えております。皆様、有難うございました。
 (HT)

 >ISERRで使用している引数の(--A1)とはどういう意味なのでしょうか?
 こちらを参考にしてみてください。
[[20040530061813]]『「--」と「!」の意味?』(masabou5)
 
 (キリキ)(〃⌒o⌒)b

 ★キリキさん★
 御紹介頂いた過去ログの内容を確認し、会社で擬似環境を構築して試してみました。
 同僚からは「極力セル上に関数を組み込んで処理をしたくない。ユーザーが不用意に入力してしまい、
 関数の入ったセルを壊してしまうから」という指摘を受け、私なりに変更してみました。
 以下、結果報告です。

 Private Sub テスト_Click()
   Range("AA1") = Mid(CStr(Cells(3,5)),1,4) & "/" & Mid(CStr(Cells(3,5)),5,2) & "/" & Mid(CStr(Cells(3,5)),7,2)
 'AA2のセルに「=--AA1」を組み込み、AA列を非表示にしておく
 '使用するセルは入力領域以外では、AA1とAA2のみ使用。
   MsgBox (Not (IsError(Range("AA2"))))
 End Sub

 もしくは、西暦年部分のみ「"0100"未満か?」という判定を行い、偽("0100"以上の場合)の時は、日付8桁で「IsDate関数」で判定を行う。

 もちろんあくまでもユーザーの判断及び、チーム内の上席者の判断に依存しますので、私としてはここまでしか提案出来ませんでした。
 多分、上記2案のいずれかを共通クラス化していく方針になるのだと思います。
 御教授頂き有難うございました。「=NOT(ISERR(--A1))」の件、今後、積極的に利用してみたく思います。
 (HT)

コメント返信:

[ 一覧(最新更新順) ]


YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki. Modified by kazu.