質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

Q&A

解決済

4回答

7209閲覧

経過日数の計算について

pazzu

総合スコア16

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

0グッド

0クリップ

投稿2017/08/31 03:00

下記の問題をIf文とFor文を利用してどのようにプログラミングしていけば良いのか分かりません。大変お手数ですが、教えて頂けると幸いです。

入力年月日1から2までの経過年、日を計算しなさい。
各月の日数は下記の月表から算出すること

月表
1 2 3 4 5 6 7 8 9 10 11 12
31 28 31 30 31 30 31 31 30 31 30 31

閏年は29とする

入力年月日1

経過日数
入力年月日2 年 日

※入力年月日は西暦で8桁数字で以下の要領で入力される
例 1978年1月7日 19780107
注:西暦1000年以下の入力はないものとする(常に8桁数字)

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

VBAで2つの日時の差分を取るにはDateDiff関数を使うのが一番簡単です。
詳しくは下記URLを見てください。もちろんうるう年にも対応しています。

DateDiff関数

実際には8桁数字に区切り文字を入れて「XXXX/XX/XX」という文字列に変換しCDate関数でDate型になおして、DateDiff関数に与えることになります。

第1引数に与える文字で、「日数」「月数」「年数」を得ることができます。

投稿2017/09/04 08:30

PineMatsu

総合スコア3579

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

解決担っていないのでとりあえず、1900年1月1日からの日数を算出する部分のみとなります。1900年2100年までは、約40万日ありますので、Long変数にする必要があります。この例では、この変数をtDayとして計算しています。また、入力年月日の年をiYear, 月をiMonth, 日をiDayにしているものとします。

Dim monthOfDay As Variant
Dim dayOfYear(11) As Integer
Dim i As Integer
Dim d As Integer

' 月表を配列に設定する
monthOfDay = Split("31,28,31,30,31,30,31,31,30,31,30,31", ",")

' 各月ごとにその最初の日付前日までの日数をdayOfYear配列に設定
' ただし、閏年の場合には、3月以降に+1する。これは①で行なっている。
d = 0
For i = LBound(monthOfDay) To UBound(monthOfDay)
dayOfYear(i) = d
d = d + monthOfDay(i)
Next i

' ((iYear-1)-1000)*365を一度に計算しようとするとオーバーフローになるので式を分解する。
tDay = (iYear - 1) - 1000
tDay = tDay * 365

' 2行目のiMonth1-1は、dayOfYear配列の下限が0から始まっているため、
' 2行目のIIf式が、うるう年でiMonthが3月以降だったら+1にする。
tDay = (tDay + Int((iYear - 1) / 4) - Int(1000 / 4)) + _
(dayOfYear(iMonth - 1) + IIf(iYear Mod 4 = 0 And 3 <= iMonth, 1, 0)) + _
(iDay)

うるう年の決定には、4で割り切れるかどうかで判断していますが、本来的には、

・西暦が400で割り切れる年はうるう年である
・400で割り切れない場合、西暦が100で割り切れる年はうるう年ではない
・100で割り切れない場合、西暦が4で割り切れる年はうるう年である
・4で割り切れない場合、うるう年ではない

の判断が必要となります。

投稿2017/09/02 05:02

編集2017/09/02 13:07
diracpaul

総合スコア157

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

同じ質問をするより、解説が必要な部分をしぼって質問したほうがよいです。
https://teratail.com/questions/90445

元ネタの参考リンクについて少しづつ作成してみてください。
言語は違いますが、考え方(ロジック)は、変わりません

わかりやすいのは、経過日の計算かなぁ。

経過日の計算
①誕生日の年における1月1日から誕生日までの経過日数
②誕生日の年の1月1日から当該日(今日)の前年12月31日までの経過日数
③当該日(今日)の年における1月1日からの経過日数

経過日 = ② + ③ - ①

今回の場合、「誕生日の年」の部分が、「入力年月日1」に相当します。
同様に、「当該日(今日)」を「入力年月日2」と考えればよいです。

①と③の作成について

  • 入力年月日1が「10000101」入力年月日2が「10000102」
  • 入力年月日1が「10000101」入力年月日2が「10000301」

という単純なもので、実際にロジックを作成してみてください。

実際には、入力年月日1と2は違う年となるので、入力年月日1に対して、①の計算、
入力年月日2に対して、③の計算をします。
10001010 ~ 20001231 の経過日数を求める場合、10000101からの計算が①、20000101からの計算が③です。

②については、基本的には365日か、うるう年の場合、366日を年数分、合計すれだけです。
うるう年の判定についても記載されています。

(1)西暦年数が4で割り切れる年は原則として「うるう年」にする。
(2)上記の例外として、西暦年数が100で割り切れる年は「平年」とする。
(3)さらに例外として、西暦年数が400で割り切れる年は「うるう年」にする。

最後に、元の計算の経過日 = ② + ③ - ①で経過日数が求められます。

if文は、うるう年の判定
for文は、②の年の計算および、①のときの月の日数の計算で使うことになるかと思います。
参照元のロジック見たとおりですが・・・

日付関数使ってよいなら、rururu3さんのもので、ほぼOKだと思います。
Excelの基準年が1900年なので、それより前の年月で対応が必要かも。

投稿2017/08/31 05:57

momon-ga

総合スコア4820

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

pazzu

2017/08/31 07:14

ご回答ありがとうございます。教えて頂いたことを元にプログラミングしてみます。
guest

0

ExcelVBAで試したので他の環境で動くかは不明ですが

VBA

1Option Explicit 2 3Sub test() 4 Call MsgBox(diffDay("20170101", "20170102")) 5End Sub 6 7Function diffDay(dateStr1 As String, dateStr2 As String) As Integer 8 dateStr1 = Format(dateStr1, "0000/00/00") 9 dateStr2 = Format(dateStr2, "0000/00/00") 10 diffDay = DateDiff("d", dateStr1, dateStr2) 11End Function

※値入力に関しては考慮はしてませんので注意

投稿2017/08/31 03:17

rururu3

総合スコア5545

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

pazzu

2017/08/31 04:07

ご回答ありがとうございます!参考にさせて頂きます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問