[[20070625152124]] 『データ型(Date)』(真夏) ページの最後に飛ぶ

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

 

『データ型(Date)』(真夏)

 変数の宣言について教えて下さい。

 Sub test()
    前日 = DateValue(Now - 1)
    前日 = Format(前日, "mm.dd")
    msgbox 前日
 end sub
 上を実行するとメッセージボックスで06.24と出ます。

 変数の宣言をしてやろうと思い、日付なんで日付型で宣言したところ
 Sub test2()
    Dim 前日 As Date
    前日 = DateValue(Now - 1)
    前日 = Format(前日, "mm.dd")
    msgbox 前日
 end sub
 メッセージボックスは06:24:00と時間のようになってしまいます。
 なぜなんでしょうか?

 単純に日付なんで日付型かと思ったんですが違うのでしょうか?
 ヘルプを見ると、Date型は日付だけでなく時刻も表すことが出来き、小数部分は時刻として扱われるようですが
 Format(前日, "mm.dd")
 としているので06.24となって欲しいんです。

 変数の宣言をしないか、バリアント型で宣言すると06.24となってくれるんで
 宣言の仕方が悪い(型がちがう?)のだと思いますが
 日付を日付型で宣言してうまくいかないのは何か間違っているんでしょうか?

 ご指導お願い致します。

    Dim 前日 As String

    前日 = Format(Date - 1, "mm.dd")
    MsgBox 前日

 Date型で宣言しているのに
    前日 = Format(前日, "mm.dd")
Format関数で「表示したい形式での」文字列型のデータを代入していますよね。
ここに混乱が起きています。変数代入時に勝手に時刻に変換されています。
 
つまり、日付を表す文字列として区切り文字として「.」はイレギュラーで
時間の区切り文字として認識されてしまうようです。
詳細はローカルウィンドウを表示しながらステップ実行してみてください。
 
最初のコードで06.24がmsgboxに表示されるのは、変数『前日』が暗黙宣言による
variant型のため。variant型はその時々で内部処理形式が変化します。
 
 Sub test()
    前日 = DateValue(Now - 1) ' 内部処理形式日付型。
    前日 = Format(前日, "mm.dd") ' Format関数の結果が文字列なので内部処理形式文字列に変化。
    msgbox 前日 ' 結果として文字列が表示。
 end sub
 
msgboxで前日の日付を表示したいのなら、DateValue(Now - 1)で前日のリテラル値は
求められているはずだから、変数『前日』に格納しなおさずに、msgboxで直接。
 
 Sub test()
    Dim 前日 As Date
    前日 = DateValue(Now - 1)
    MsgBox Format(前日, "mm.dd")
 End Sub
 
これでいいんじゃないでしょうか。
 
(みやほりん)(-_∂)b


 みやほりんさん、ななしさん、ありがとうございます。

 まだまだ未熟でして、せっかく説明して頂いたのに誤解してしまっているといけないので
 みやほりんさんの説明を自分なりにまとめてみるので、(解りにくいですが)
 間違っていたら訂正して頂けるとありがたいです。

 Date型で宣言する場合
 Date型だと思っている変数【前日】を、基本的には日付や時刻を現すものではない"mm.dd"という形式で
 Formatしようとしているため、日付なのか時間なのか混乱する。
 【.】が時刻を表す【:】に近いので?、勝手にExcelが時刻だと解釈し
 結果"mm:dd"と認識される。

 Variant型で宣言する場合
 その時々で適切な型に勝手に変換してくれる?ため、
 日付でも時刻でもない"mm.dd"という形式をただの文字列と認識して、
 素直に"mm.dd"という形式で表示される。
 (ななしさんがご提示して下さっているString型も文字列として扱うのでそのまま"mm.dd"になる)

 あと、
 変数【前日】に格納しなおさずにmsgboxで直接
 Msgbox Format(前日, "mm.dd")
 とすればDate型で宣言しても大丈夫な理由が解らないです。
 日付型の【前日】を日付でも時刻でもない"mm.dd"という形式で
 フォーマットしようとするとおかしくなる
 と解釈したのですが、間違ってますでしょうか? 

 何度もすみませんが教えていただけるとありがたいです。

 (真夏)

 Format 関数が返す値が 「文字列型」であるという点が明確になれば、
 全体の流れが理解できないでしょうか。
 (Mook)

 Mookさん、返信ありがとうございます。

 Date型で宣言したものを文字列型にしようとしたのでおかしくなった。
 Variant型,文字列型で宣言していれば文字列型にできるのでOK。

 ここまでは解るんですが、みやほりんさんが最後に書いて下さっている
 Date型の変数【前日】に格納しなおさなければOKというのが

 と、ここまで少し解ったような気がしてきました。
 【前日】をDate型で宣言している場合
 前日 = Format(前日, "mm.dd") だと
 Date型である【前日】に文字列型の"mm.dd"を入れようとしているからダメということでしょうか?
 なので、変数【前日】に格納せず、そのままmsgboxで表示させれば大丈夫と。

 ただ
 Format(前日, "mm.dd") の時点でおかしくならないんでしょうか?
 msgbox Format(前日, "mm.dd") でも、
 Date型である【前日】を文字列型である"mm.dd"にしてメッセージとして出すので
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 私の解釈では↑の部分でダメになるように思うんです。

 すいません、どこかで勘違いしてるんでしょうが。。。
 (真夏)

 >前日 = Format(前日, "mm.dd") 
では、Date型の変数に"mm.dd"という「日付として認識するには不適切な」文字列を
無理やり押し込んだため、意図したデータとして格納できないという事態が起こって
います。きつい言い方ですが変数の内容の検証を行なっていない、乱暴なやり方に思
えます。この時点でデータは変質していますので、意図した結果は返りません。
 
 >Msgbox Format(前日, "mm.dd")
 >とすればDate型で宣言しても大丈夫な理由が解らないです。
 
Format関数は変数「前日」の内容を"mm.dd"の形式の文字列に変換、MsgboxでFormat
関数で変換された文字列を表示しているだけです。そのまえの、
    前日 = DateValue(Now - 1)
で格納された変数の内容はMsgbox表示している間も一切変化していません。
Msgboxでただ計算結果を利用しているのと、変数に格納し直すことを混同されている
ような印象を受けます。
 
>詳細はローカルウィンドウを表示しながらステップ実行してみてください。
↑これらのデバッグ手段をおろそかにしてはいけません。
 
『プログラムは思ったとおりに動くのではない、作ったとおりに動くのだ』
 
「こうなるはず」では動きません。検証の方法を身につけてください。
(みやほりん)(-_∂)b

 みやほりんさん、返信ありがとうございます。
 最初にみやほりんさんの返信の後、ステップ実行はしてみました。
 で、おかしくなる箇所とご提示の直接msgboxで表示させれば大丈夫なことを確認はしてたんです。
 しかし、なんでそうなるのかが解ってなかったです。

 >Format関数は変数「前日」の内容を"mm.dd"の形式の文字列に変換、MsgboxでFormat
 >関数で変換された文字列を表示しているだけです。そのまえの、
 >    前日 = DateValue(Now - 1)
 >で格納された変数の内容はMsgbox表示している間も一切変化していません。
 >Msgboxでただ計算結果を利用しているのと、変数に格納し直すことを混同されている
 >ような印象を受けます。

 この辺が解っていませんでした。
 Date型の変数をFormat関数で文字列に変換することは出来る
 ただし文字列に変換したものを再びDate型の変数に入れようとするとおかしくなる
 ということなんですね。

 前日 = DateVlue(Now - 1) までは06.24となっているのに
 前日 = Format(前日, "mm.dd") で06:24:00となっていたんで
 ここがおかしいというのは解ったんですが、その理由を
 Date型である前日に文字列を入力しているから というのが解っておらず
 Date型である前日を文字列に変換しようとしたから だと思ってしまってました。
 だから Msgbox Format(前日, "mm.dd") もダメなんじゃないかなと思ったんです。
 実際やってみると06.24となるんで、どうしてなのかなと。

 今最初のみやほりんさんのレスを見れば
 >Format関数で「表示したい形式での」文字列型のデータを代入していますよね。
 >ここに混乱が起きています。変数代入時に勝手に時刻に変換されています。
 と書いてあるんですが、これを変換すること自体ダメだと読み違えてしまっていました。
 思いっきり「変数代入時に」って書いてるんですけどね。

 と、いうことで納得できました。
 ありがとうございました。
 (真夏)

 文字列を代入するにしても"06/24"の形式なら認識するんです。
私はむしろ、"06.24"を代入して 1900/01/05 午前05:45:36 にならないのが不思議。
"06.24"は(VBAにおける日付としては)それくらい突飛なものだと思ってください。
 
Date型変数に代入するなら日付の区切りは"/"を使用して、"."が必要な段階でFormat
関数でそのような形式の文字列を作成、という方法を採ってください。
(みやほりん)(-_∂)b


 おまけ、
 Date型変数は、コントロールパネルの地域での設定仕方によっても変わるので
 直接出力するのは避けた方が良いと思います。
 (思わぬ落とし穴があったりします。)
 BJ

コメント返信:

[ 一覧(最新更新順) ]


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