goo blog サービス終了のお知らせ 

パソコンカレッジ スタッフのひとりごと

パソコンスクールのスタッフが、
初心者から上級者まで役立つ情報をお伝えします。

ひと月を30日間として経過日数を計算する方法(ExcelVBA)

2011-11-16 09:02:16 | ExcelVBA
今日は、オリジナル関数を作成します。

というのも、変則的な計算をする必要が出てきたからです。

下の表を見てください。




開始日から終了日までの日数を計算したいのです。
ただし、
1.開始日も含める。
2.ひと月を30日として計算する。
という制約があるのです。


普通に求めるには、DATEDIF関数を使います。
=DATEDIF(B3,C3,"D")
と入力すれば、答えが出てきます。
これが正しい答えなのですが、今回の制約を満たしてはいません。

そこで、ExcelVBAを使って、ユーザー定義関数を作ります。

その名も!DateDiffSpecial関数です!(・・・|)

結果として、下のようになります。








ポイントは、「ひと月を30日として計算する」です。
たとえば12月は31日あります。また、2月は28日であったり29日であったりします。(閏年ですよ)

考え方は、いろいろあるでしょうが、今回は、以下のように攻めます。





つまり、開始日と終了日が同じ月なのか、1月だけ違うのか、それとももっと離れているのか、
この3つに分けて考えれば答えが出そうです。
その際、ひと月が30日になるように工夫をします。


さっそく、コーディングに入りましょう。

エクセルを起動したら、Altキーを押しながらF11キーを押して、VisualBasicEditorを表示します。

「挿入」→「標準モジュール」とクリックします。

表示されたモジュールにコードを記述しましょう。

オリジナル関数は、Public Function [関数名](引数1,引数2,・・・)As データ型
と書き始めます。

最後のデータ型は、この関数の戻り値(答え)のデータ型を指定するものです。

コードの中に 「 関数名 = 値 」を書くことによって、関数の答えとなります。

以下のように書いてみましょう。


Public Function DateDiffSpecial(ByVal startDay As Date, _
ByVal endDay As Date) As Integer
' 2つの日付の差を取得する。ただし、1か月を30日として計算

  If startDay > endDay Then
    '引数設定ミスは、0を返す
    DateDiffSpecial = 0
    Exit Function
  End If

  '終了日が末日かどうかをフラグに代入
  Dim IsMatsujitsu As Boolean
  If Day(endDay) = Day(DateSerial(Year(endDay), Month(endDay) + 1, 1) - 1) Then
    IsMatsujitsu = True
  Else
    IsMatsujitsu = False
  End If

  Dim Ans As Integer
  Ans = 0
  Dim a As Integer
  '開始日と終了日の月数の差を取得
  a = DateDiff("M", startDay, endDay)
  Select Case a
    Case 0
      If IsMatsujitsu Then
        Ans = 30 - Day(startDay) + 1
      Else
        Ans = Day(endDay) - Day(startDay) + 1
      End If
    Case 1
      Ans = 30 - Day(startDay) + 1
      If IsMatsujitsu Then
        Ans = Ans + 30
    Else
        Ans = Ans + Day(endDay)
      End If
    Case Is >= 2
      Ans = 30 - Day(startDay) + 1
      Ans = Ans + (a - 1) * 30
      If IsMatsujitsu Then
        Ans = Ans + 30
      Else
        Ans = Ans + Day(endDay)
      End If
  End Select

  DateDiffSpecial = Ans
End Function


画像も載せておきます。




条件分岐の方法として Select Case 構文と使う方法と、IF構文を使う方法がありますが、
今回は、その両方を使っています。

つまり、Select Case 構文で、大きく3つの条件分岐を設定し、
その中で、さらに30日になるようにIF構文で条件分岐をしています。

ゆっくりと読んでいくと、ロジックを理解できるでしょう。

なお、If IsMatsujitsu Then というのは、
If IsMatsujitsu = True Then
と同様の意味となります。= True は、省略可能なのです。

また、DateDiff関数は、エクセルのワークシート関数ではなく、VBAが持っている関数です。
引数の順番が異なりますので注意が必要です。

もうひとつ、末日の日を抜き出したい場合は、
Day関数の引数に、翌月1日-1 という値を指定すればいいのです。
翌月1日の前日は、その月の末日になるからです。



この関数を用いるには、答えを出したいセルに「=DateDiffSpecial(B3,C3)」と入力するだけです。




10月30日と11月1日の2日間ということで、答えは2となります。


セルの値を下のように変更してみます。




9月30日と10月1日の2日間ということで、やはり、答えは2となりますね。




えっ?なぜこんなややこしいことをしているのかって?
確かに無意味に見えるかもしれませんが、実は、あるソフトを制作するためにどうしても必要な機能なのです。

次回は、その一部をご紹介できるかもしれません。


それでは、また。


だい

コメント (2)    この記事についてブログを書く
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする
« 今週のおすすめ記事 | トップ | スマートフォンで撮った写真... »
最新の画像もっと見る

2 コメント

コメント日が  古い順  |   新しい順
VBA (成功のルーカス)
2011-11-17 17:47:07
こんにちは、ルーカスです。

いつもお世話になっております。

記事を参考にさせていただきました。

応援ポチッ
返信する
成功のルーカスさんへ (だい)
2011-11-18 10:02:58
コメントありがとうございます。
今後もよろしくお願いします。
応援ありがとうございます。
返信する

コメントを投稿

ExcelVBA」カテゴリの最新記事