• ベストアンサー

Excel VBAで年度をまたぐ期間の月末日を求める方法

タイトルの通り 03年○○月~04年○○月の間の 各月の月末日を求めるものです。 年・月とも一定でなく、TextBoxで入力したものを使います。 04年1月~04年10月のような場合 開始月<終了月で For文で簡単に出来るのですが 03年11月~04年4月と云うような場合For文も使えず 処理の仕方がわかりません。 最初に開始月の月末日を求め、DateAdd文で求めようとしたのですが、やりかたがわるかったのか正しい数字がもとめられませんでした。

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

  • ベストアンサー
  • soma3
  • ベストアンサー率39% (16/41)
回答No.3

簡単ではありますが、ソースを紹介します。 Dim startDate As String Dim endDate As String Dim iLoop As Integer startDate = Sheet1.TextBox1.Text endDate = Sheet1.TextBox2.Text For iLoop = 0 To DateDiff("m", CDate(startDate), CDate(endDate)) - 1 MsgBox DateAdd("d", -1, DateAdd("m", iLoop + 1, CDate(startDate))) Next Sheet1.TextBox1.Textのテキストボックスに開始月が 「03年11月」という形式で入力されています。 Sheet1.TextBox2.Textのテキストボックスに終了月が 「04年4月」という形式で入力されています。 このような場合、メッセージボックスでの表示となりますが、 「2003/11/30」 「2003/12/31」 「2004/01/31」 「2004/02/29」 「2004/03/31」 と3月分まで表示されます。

biwajima
質問者

お礼

有難うございました。 まさに私の求めていたコードです。 > For iLoop = 0・・・ ゼロから初めて良いんですね~ イマイチ意味が分かりません

その他の回答 (4)

  • soma3
  • ベストアンサー率39% (16/41)
回答No.5

#3です。 「For iLoop = 0・・・」の部分ですけど、ただの私の癖です。 For iLoop = 0 To DateDiff("m", CDate(startDate), CDate(endDate)) - 1 MsgBox DateAdd("d", -1, DateAdd("m", iLoop + 1, CDate(startDate))) Next と書いてある自分のコードを見ますと、 For iLoop = 1 To DateDiff("m", CDate(startDate), CDate(endDate)) MsgBox DateAdd("d", -1, DateAdd("m", iLoop, CDate(startDate))) Next と書いた方がわかりやすいかもしれませんね。 結局、ループする回数なので、 0から始めようが1から始めようが 終わりの部分(For iLoop = 1 TO ***)と                     ~~~~ ループの対象となる DateAdd("d", -1, DateAdd("m", iLoop, CDate(startDate)))                    ~~~~~~~ の部分を合わせれば問題ないと思います。 ここら変は、開発者の癖なんかがもろに出ちゃうような気もします。

biwajima
質問者

お礼

有難うございました。 普段For文で1から初めているもので、何か意味が有るものかと思ったものですから・・・ 配列も0から始まるようですし、0から始める癖をつけましょうかね~ #3は大変参考になりました。DateDiff関数のこういった使い方は 目から鱗です。 他の方も参考になったんじゃないですか。

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

A列に日付を入れるとして その月末日をB列に出す場合 Sub test01() For i = 1 To 10 Cells(i, 2) = DateSerial(Year(Cells(i, 1)), Month(Cells(i, 1)) + 1, 1) - 1 Next i End Sub (テスト実行データ) 2003/12/16 2003/12/31 2004/1/17      2004/1/31 2004/2/18      2004/2/29 2004/3/19      2004/3/31 2004/4/20      2004/4/30 2004/5/21      2004/5/31 2004/6/22      2004/6/30 2004/7/23   2004/7/31 2004/9/24      2004/9/30 2004/10/25 2004/10/31 次月の1日の日付シリアル値を求めその前日が、月末日です(常套手段)。

biwajima
質問者

お礼

有難うございました。 参考になりました。

noname#148473
noname#148473
回答No.2

もし、月末日ではなく「その月の最終営業日」とかなら、それなりに複雑な処理になりますから、VBAも役不足にならないとは思いますが・・・単なる月末日なんですよね? 質問文だけではプログラムの全貌が見えませんので、とりあえず基本方針だけを。 年をまたぐ場合、For文では無理なので、Do~Loop文を使い、処理が期間の最終月になったら、Exit Doでループを抜けるという方法がより適していると思います。ループの最後で月を+1しておき、もし月が13になった場合は、月を1にして年を+1する、というふうにしておけば、年をまたいだ処理が可能です。 DateAddは「翌月の同日」などを求めるのには向いていますが、月末日を求めるのには使えません。月末日の出し方は、#1の方が書かれているように、DateSerial関数に「求めたい年」と「求めたい月+1」、そして日のところに「0」を入れることで求められます。

biwajima
質問者

お礼

有難うございました。 基準日を月末にして、DateAddで mを+1しても月末日は求められないのですね

  • papayuka
  • ベストアンサー率45% (1388/3066)
回答No.1

2月以外の月末日は毎年固定では? Sub Test() Dim s  s = "2004/2/1"  s = DateSerial(Year(s), Month(s) + 1, 0)  MsgBox DateValue(s) End Sub

biwajima
質問者

お礼

有難うございました

関連するQ&A