開始日、終了日を入力すると自動で月数を計算する
プログラムを考えています。
・したい事
1.2/17〜3/16と入力…1を返す
2.2/17〜4/16と入力…2を返す
3.2/01〜2/28と入力…1を返す
4.2/01〜2/15と入力…0.5を返す
datediff("m",xxx,xxx)を使用すると、整数でしか
返さず、4を満たさないために下記のようなコードを
書いてみました。(実際は呼び側で戻り値の小数点2位を四捨五入しています)。
Function GetMonthDiff(dtStart As Date, dtEnd As Date) As Single
Dim nDays(12) As Integer
Dim nYear As Integer
Dim nDay As Integer
Dim nDaySpan As Integer
nDays(1) = 31: nDays(2) = 28: nDays(3) = 31
nDays(4) = 30: nDays(5) = 31: nDays(6) = 30
nDays(7) = 31: nDays(8) = 31: nDays(9) = 30
nDays(10) = 31: nDays(11) = 30: nDays(12) = 31
nDay = nDays(Month(dtStart))
' 閏年考慮
If Month(dtStart) = 2 Then
nYear = Year(dtStart)
If nYear Mod 4 = 0 And nYear Mod 100 <> 0 Or nYear Mod 400 = 0 Then
nDay = nDay + 1
End If
End If
' 開始日、終了日の日数差を計算する
nDaySpan = DateDiff("d", dtStart, dtEnd)
GetMonthDiff = (nDaySpan + 1) / nDay
End Function
これで、仕様1,3,4は満たしているのですが、2.の場合だと、
2.1になってしまいます。
#これはnDayが28で分母が小さい為ですが。
このように現状は1ヶ月しか計算できないプログラムです。
こうしたら良い、とかもっと良い方法がある、とか
知識をお持ちの方いらっしゃいましたらご教授下さい。
以上、よろしくお願い致します。
試してないけど、これではだめですか?
' 月数を計算する
GetMonthDiff = DateDiff("m", dtStart, dtEnd)
If GetMonthDiff = 0 Then
' 開始日、終了日の日数差を計算する
nDaySpan = DateDiff("d", dtStart, dtEnd)
GetMonthDiff = (nDaySpan + 1) / nDay
End If
お返事ありがとうございます。
すみません、言葉足らずでした。
5.2/01〜3/15 … 1.5
ともしたいのです。
ジャスト1ヶ月、2ヶ月等の場合は、1、2と表示、
ジャストにならない場合は、1.5、2.4などの小数点表示と
したいのです。
ジャストかどうかの判断としては、
(1)開始月が1月からの場合…終了日が31日後
(2)開始月が2月からの場合…終了日が28日後(閏年も考慮)
と考えています。
よろしくお願い致します。
小数点表示は誤差が出るような・・・
ありがとうございます。
誤差は誤差の範囲内でいいのです。
と言うのも、入力例が期間だいたい、
半月(0.5ヶ月)もしくは1ヶ月単位でして。
仮に結果が0.6などになった場合は、それは、
入力した側にはある程度の目安として分かれば
いいと考えています。
以上、よろしくお願い致します
こんな感じでしょうか?
Function GetMonthDiff(dtStart As Date, dtEnd As Date) As Single
Dim nDay As Integer
Dim nMonthSpan As Integer
Dim nDaySpan As Integer
'終了日の月の日数
nDay = Day(DateSerial(Year(dtEnd), Month(dtEnd) + 1, 0))
' 開始日、終了日の月数差を計算する(整数部分)
nMonthSpan = DateDiff("m", dtStart, dtEnd)
' 開始日、終了日の日数差を計算する(小数部分)
nDaySpan = DateDiff("d", DateAdd("d", -1, DateAdd("m", nMonthSpan, dtStart)), dtEnd)
GetMonthDiff = nMonthSpan + nDaySpan / nDay
End Function
LESIAさんありがとうございます。おかげさまで理想の動きに
なりました。
>nDay = Day(DateSerial(Year(dtEnd), Month(dtEnd) + 1, 0))
"YYYY/MM/0"指定でDateSerialを取ると、"YYYY/MM-1"月の最終日が
取れる、というのは知りませんでした(後で調べたらHelpに載って
ましたが…)
ご提示頂いたソースコードはとても勉強になりました。
ありがとうございました。
ツイート | ![]() |