• ベストアンサー

エクセルVBAで日付計算

Sub test01() x = Date - 38383 '2005/01/31から今日まで何日 x = Format(x, "##") '数字であらわす MsgBox x & "日です。" End Sub 試行錯誤の結果、上記コードで特定の日から今日まで何日かわかるようになりましたが、とても不細工なコードだと思います。 もっとすんなりもとめるにはどうすればよいでしょうか?

質問者が選んだベストアンサー

  • ベストアンサー
  • euga
  • ベストアンサー率100% (1/1)
回答No.3

Excelには隠しで関数があります。 DateDiff 関数 2 つの指定した日付の時間間隔を表すバリアント型 (内部処理形式 Date の Variant) の値を指定します。 Sub Test() Dim a As Long   '2005年1月31日から今日までの日数 a = DateDiff("d", "2005/01/31", Date) MsgBox a End Sub

merlionXX
質問者

お礼

な~んと、やはりこういう技があるんですね。 完璧です! ありがとうございました。

その他の回答 (10)

  • hana-hana3
  • ベストアンサー率31% (4940/15541)
回答No.11

>だからFormatで数字に直したのですが。 プログラムがXの値を日付として処理したので、1900年+差の日数 =1900/09/24 と言う日付型の表示がされただけです。 #9さんが書かれたように変数Xの型を指定すると、日付では無くて数値として処理されますから、Format文は不要になります。 正しい答えが出るなら処理方法に誤りは無いといえますが、変数型を宣言して目的に合った値を格納できるようにする事が大切かと思います。

merlionXX
質問者

お礼

> 変数型を宣言して目的に合った値を格納できるようにする事が大切かと思います。 仰せのとおりでございました。 ありがとうございます。

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.10

こんにちは。Wendy02です。 >MsgBox Date - 38383 & "日です。" だけだと。「1900/09/24日です。」とでてしまうんです。だからFormatで数字に直したのですが。 それは、Date型にキャストされてしまっています。私が、DateDiffを選んだ理由は、片方の数字が、Date型だからです。データ型の変換をしなくて済むからです。別に、格好がよいとかいう理由ではありません。 引き算する場合は、Dateを一旦、Long型に変換をしてから、引き算をしたほうがよいですが、Date関数と、Clng関数が重なるのに、サンプル・コードとしては少し抵抗を感じました。関数式とは違いますから、データ型の推移をきちんと把握しながら、出力値に持ってきたほうがよいと考えました。あまり値のキャスト変換を暗黙的に使わないほうがよいですね。

merlionXX
質問者

お礼

何度もありがとうございます。 ほんとに変数の型の宣言はする習慣をつけたほうがよいですね。 おさわがせしました。

  • mshr1962
  • ベストアンサー率39% (7418/18948)
回答No.9

#1,8のmshr1962です。 >MsgBox Date - 38383 & "日です。"だけだと。「1900/09/24日です。」とでてしまうんです 整数、長整数にすればいいですね。 MsgBox CInt(Date - 38383) & "日です。" MsgBox CLong(Date - 38383 & "日です。" なら数値になります。 変数を使う場合は Dim X As Integer X= Date - 38383 MsgBox X & "日です。"

merlionXX
質問者

お礼

Dim X As Integerを宣言しなかったわたしがお馬鹿でした。 ありがとうございました。

  • mshr1962
  • ベストアンサー率39% (7418/18948)
回答No.8

#1のmshr1962です。 >シリアル値にして引かないといけないんだろうということ 他の方の回答でもでてますが DateSerialやDateValueの日付関数を使う方法と CDateというデータ型変換関数を使う方法があります。 DateSerial(2005,1,31) DateValue("2005/01/31") CDate("2005/01/31") は同じ日付のシリアル値になります。 >Formatを使わないと計算結果が数値にならないんだろうという 別段Format関数を使う必要はありません。 Formatは書式が必要な場合に使う関数です。 "0日です。"がOKであれば MsgBox (Date-DateValue("2005/01/31"))&"日です。" でもかまいません。 例の場合は、##なので0日の場合、"日です。"になります。

merlionXX
質問者

お礼

ありがとうございます。 >> Formatを使わないと計算結果が数値にならないんだろうという > 別段Format関数を使う必要はありません。 MsgBox Date - 38383 & "日です。" だけだと。「1900/09/24日です。」とでてしまうんです。だからFormatで数字に直したのですが。

  • imogasi
  • ベストアンサー率27% (4737/17068)
回答No.7

>不細工なコード どの行について感じたのか書かないと判りません。 全体というか、なんと無くもあるでしょうが。 雑感 (1)引き算説 DateDiffがかっこいいと言うのは反対。 せっかくエクセルが、引き算で日数を出せるように、シリアル値というすばらしいアイデアを採用したのに。 エクセル関数のように第3引数にy、m、dなどを指定する場合は威力を発揮するでしょうが。 (2)38383説 これは可視性が悪いですね。Dateserial(2002,3,23)とか#2002/3/23#の法がわかりやすい。 (3)その他雑感 私が感じたのは、エクセルVBAでありながら、MSGBOXを使っていること。セルにセットするのが本筋ではないでしょうか。そして セルの日付書式を設定する。手動でもNumberFormatをVBAで設定する方法もあります。 (4)X,Xと同じ変数を違う内容に割り当てている。 (5)Xの右辺を関数の中に組み込む方法あり。かえって不細工かも 知れませんが。 MsgBox Format(Date - 38383, "##") & "日です。"

merlionXX
質問者

お礼

ありがとうございます。

  • bin-chan
  • ベストアンサー率33% (1403/4213)
回答No.6

MsgBox Format(Date - #2005/01/31#, "##日です。") でもOKですね。

merlionXX
質問者

お礼

ありがとうございました。

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.5

merlionXX さん、こんばんは。 最初に、失礼な書き方に思えたらすみませんです。 merlionXXは、人に教えるレベルであって、そのコード自体が、私の目からは、「不細工」とはいえないと思います。いままで、merlionXXのご質問などのやり取りをみていて、ものすごく勘の良い方だなって思います。だから、なんとなく、感覚的に、そのようにされたのだろうなって思います。でも、何かが足りないと感じたのではありませんか? もし、そうだとすれば、なるべく簡単なコードでも、変数の型の宣言はする習慣をつけたほうがよいですね。そうすると、見えないものが見えると思います。 VBAやVBは、値が自動変換するとは言っても、やはり、値の移動の時にきちんと、定義づけるようにしたほうがよいと思います。 x = Date - 38383 '変数 x は、ここでは、数値ですね。 x = Format(x, "##") '次に、Variant になっていますね。 MsgBox x & "日です。" '文字列ですね。 それぞれ変数の型は変化しています。このように、変数の使い回しは、あまりしないほうがよいですね。では、コードを一本化させた良いかというと、それは違うようです。今度は、可読性の問題や修正時の問題が出てきます。 例えば、Format関数を使う場合、文字列に直すのでしたら、Format$を使います。 Format(x, "##")  ↓ Format$(x, "##") か、CStr(x) とします。 私は、リテラル値を使って以下のように書きました。 VBAの場合は、代入する値は、なるべく変数として、外に出したほうがよいですね。ワークシートの書き方とは、ちょっと違う作法が必要のようです。VBAで作法というのもヘンですけれども。最近、基礎に戻って勉強中です。 Sub test02()   Dim x As Long   Dim FirstDate As Date   FirstDate = #1/31/2005#   x = DateDiff("d", FirstDate, Date)   MsgBox CStr(x) & "日です。" End Sub

merlionXX
質問者

お礼

ありがとうございます。 ぜんぜん。勘なんてにぶいのですが。 勉強になりました。

  • hana-hana3
  • ベストアンサー率31% (4940/15541)
回答No.4

>わたしが不細工と感じたのは MsgBox DateDiff("d", "2005/1/31", Date) & "日"

merlionXX
質問者

お礼

No3さんとおなじですね。 ありがとうございました。

  • bin-chan
  • ベストアンサー率33% (1403/4213)
回答No.2

MsgBox Format(Date - datevalue("2005/01/31"), "##日です。") でよいですか?

merlionXX
質問者

お礼

なるほど、DateValueでシリアル値をもとめているんですね。 ありがとうございました。

  • mshr1962
  • ベストアンサー率39% (7418/18948)
回答No.1

単純に MsgBox Format(Date-38383,"##日です。") では駄目なのですか?

merlionXX
質問者

お礼

さっそくありがとうございました。 わたしが不細工と感じたのは まず、Date-38383の部分で、なんでわざわざシリアル値にして引かないといけないんだろうということとFormatを使わないと計算結果が数値にならないんだろうという点なんです。 これはどうしようもないのでしょうか?

関連するQ&A

  • ただ、今日の日付を求めたいときはどちらのVBAコー

    VBA初心者のため教えてほしいのですが ただ、今日の日付を求めたいときはどちらのVBAコードを使えばいいですか? Sub test1() MsgBox DateValue(Date) End Sub Sub test2() MsgBox Date End Sub です。 ご教授よろしくお願いします。

  • エクセルVBAでファイル操作

    既出でしたら、すみません。 VBAでコードを書いているのですが、試行錯誤したうえで質問させていただきます。 以下、自分で書いたエラーになるコードです。(実行時エラー 424) If Dir("C:\業務\データ蓄積\ zaiko" & Format(Date, "yyyymmdd").xls) = "" Then MsgBox "該当なし" Else MsgBox "該当あり" End If データ蓄積にzaiko+"今日の日付"の.xlsが存在しなければ MsgBox "該当なし" 存在するなら MsgBox "該当あり" と、したいのですが どうにか、お力添えください。 宜しくお願いします。

  • 今の自分の年齢を取得するvbaコードが知りたい

    今の自分の年齢を取得するvbaコードが知りたいのですが Sub test1() Dim dtm誕生日 As Date dtm誕生日 = #7/1/1986# MsgBox Format(Date - dtm誕生日, "yyyy/mm/dd") MsgBox DateDiff("yyyy", dtm誕生日, Date) End Sub を作ってみたのですが 違うのが返りました。 DateDiff("yyyy", dtm誕生日, Date) は、30が返ってしまいます。 今日の時点ではまだ29歳なのですが そういう場合どうすればいいでしょうか? 「現在は29歳です」と返したいのですが、 どのようにすればいいでしょうか?

  • VBA dateの戻り値

    ExcelVBA初心者です。 下記プログラムを組んでいるのですがMyDateの戻り値が常に -1された数字になってしまいます。 たとえば、25を入力したら24になる。これはなぜなのでしょうか? また、0だと30になってしまいます。 Sub hani() Dim MyDate As Date MyDate = Application.InputBox("報告する日を入力してください", "報告日", Format(Now, "dd")) If Format(MyDate, "dd") > 0 And Format(MyDate, "dd") > 32 Then MsgBox Format(MyDate, "dd") MsgBox "範囲内" Else MsgBox Format(MyDate, "dd") MsgBox "範囲外" End If End Sub

  • エクセルVBA/ Formatで文字列が数値に化ける?

    いつもお世話様です。 エクセルVBAでFormatを使うと、文字列中にeが一つ入っていると、「指数」とみなされて勝手に数値に化けてしまうようです。 話を簡単にするため、問題のコートを簡易化したコードが下記のtest1です。 入力されるのは常に3文字以内の英数です。 test1のコードは、ab9と入れればAB9、01とか20とか入れると、予定通り001や020を返してくれます。 ところが、なかには1E1や4E3なども入力する必要があり、これを入れると010や4000に化けてしまいます。 現在は、対処するため、下記test2のように、文字列中に"E"があるかどうかで処理を分岐させていますが、ほかに何か良い方法はないでしょうか? Sub test1() Dim x As String, y As String, z As String x = Application.InputBox("CODEを入力してねん。", Type:=2) y = StrConv(StrConv(x, vbUpperCase), vbNarrow) z = Format(y, "000") MsgBox z & " Typeだよ。" End Sub Sub test2() Dim x As String, y As String, z As String x = Application.InputBox("CODEを入力してねん。", Type:=2) y = StrConv(StrConv(x, vbUpperCase), vbNarrow) If InStr(y, "E") > 0 Then z = y Else z = Format(y, "000") End If MsgBox z & " Typeだよ。" End Sub

  • vba 「02」を返したいのですが

    Sub test() Debug.Print Month(Date) End Sub のようなコードの時に 月の表記を02のように2桁で返すにはどうすればいいですか? Debug.Print Format(Month(Date), "mm") これだと、なぜか「01」が返ります。 「02」を返したいのですが、どうすればいいでしょうか?

  • エクセルVBAの日付の表示で教えてください

    A1セルに「2021年9月5日(日)です」と表示したいのですが、下記のマクロを実行すると「9月04日(木)です」と表示され、日付も曜日も違う結果が表示されてしまいます。 初心者で良く分からないため、マクロに詳しい方、教えていただけないでしょうか。 Sub test() Dim niti As Date niti = "2021/ 9 /5" Range("A1").Value = Month(niti) & "月" & Format(Day(niti), "dd") & "日" & Format(Day(niti), "(aaa)") & "です" End Sub

  • VBA IFについて

    Sub コピー() Dim x As Variant MsgBox "作成を開始します" Application.ScreenUpdating = False For Each x In Excel.Workbooks.Item("test1.xls") _ .Worksheets.Item(1).Range("B2:B20").Value If VBA.Len(x) > 0 Then FileCopy "C:\test\フォーマット.xls" , "C:\test2\" & CStr(x) & ".xls" End If Next MsgBox "作成が完了しました" End Sub 上記のコードで”B2:B20”セルの値の名前にしてファイルをコピーしているのですが、”B2:B20”値の名前のファイルがtest2フォルダにあればコピーしないようにしたいのです。 変数xがtest2フォルダになければというコードがどうしてもかけません。 どなたかご教授ください。

  • エクセルVBAでお願いします。

    エクセル2002使用です。 セルA1に 日付型で2004/9/25と間違いなく入っています。 その条件で下記のようにコードを打ちました。 Sub test() If Day(Range("A1")) = 30 Then MsgBox "yes" End If End Sub 25=30ならばmsgboxを表示なので、上記の例では表示してはいけないのに表示されます。 ちなみに=を<>不等号にしてもMsgboxが開きます。 おそらく型の問題だと思ったのですが、DAY関数はVariant型のintergerなので問題ないと思うのですが、理由がわかりません。 よろしくお願いします。

  • エクセルVBA サブルーチンの使い方

    下記コードにて、MSGBOXで88を表示するには、どう変更すればよいですか? Sub aaa() bbb MsgBox b End Sub Sub bbb() b = 88 End Sub

専門家に質問してみよう