達人養成塾 小川です。
とある受講生からこんな質問がありました。
何かというと。
たとえば、以下のコードを実行すると、セルA1には、「1900年1月0日 0:00」を意味する値が入る。
Dim d As Date
Range(“A1”).Value = d
ところが、以下のマクロを実行すれば分かるとおり、Visual Basic Editor上で比較すると、 初期値のままの日付型変数の値は、 1899年12月30日 0:00 と同値となっている。
Dim d As Date If d = #1899/12/30# Then '[1] Debug.Print "一致" Else Debug.Print "不一致" End If 'ただし、[1]の行の#シャープ#でくくられた部分は、 '編集を終えた瞬間、以下のように置き換わってしまう。 '#12:00:00 AM#
そこで、この点について整理して書いてみた。
ポイントは、以下。
○エクセルのうるう年の処理が間違っている(「1900年2月29日」という、ありえない日付がエクセルには存在する)
○そのため、1900年3月1日より後と1900年2月28日より前とでは、VBの中で日付型変数が持っている日付の値とそれを出力したときのエクセルでの日付が異なることがある。その逆もまた同様。
この件を明らかにするため、以下のマクロを書きました。
ただし、.text はセルに表示されている文字列をそのまま取得し、
.value はセルに入っている値を取得するという違いに留意しましょう。
Sub hoge1() Columns("B:C").ColumnWidth = 14 Columns("B:C").NumberFormatLocal = "yyyy/m/d h:mm;@" Dim d As Date Dim c As Long If d = #12:00:00 AM# Then Debug.Print "一致" Else Debug.Print "不一致" End If For c = 1 To 3 Range("A" & c).Value = c - 1 Range("B" & c).Formula = "=A" & c With Range("C" & c) .Value = DateAdd("d", c - 1, d) Debug.Print c & "行目" Debug.Print vbTab & "excel value: " & .Offset(, -1).Value Debug.Print vbTab & "excel text : " & .Offset(, -1).Text Debug.Print vbTab & "dateadd : " & DateAdd("d", c - 1, d) Debug.Print vbTab & "vba .value : " & .Value Debug.Print vbTab & "vba .text : " & .Text Debug.Print vbNewLine End With Next For c = 60 To 62 Range("A" & c).Value = c - 1 Range("B" & c).Formula = "=A" & c With Range("C" & c) .Value = DateAdd("d", c - 1, d) Debug.Print c & "行目" Debug.Print vbTab & "excel value: " & .Offset(, -1).Value Debug.Print vbTab & "excel text : " & .Offset(, -1).Text Debug.Print vbTab & "dateadd : " & DateAdd("d", c - 1, d) Debug.Print vbTab & "vba .value : " & .Value Debug.Print vbTab & "vba .text : " & .Text Debug.Print vbNewLine End With Next End Sub
このマクロの実行結果は、以下の通りです。
○出力結果
1行目 excel value: 0:00:00 excel text : 1900/1/0 0:00 dateadd : 0:00:00 vba .value : 0:00:00 vba .text : 1900/1/0 0:00 2行目 excel value: 1899/12/31 excel text : 1900/1/1 0:00 dateadd : 1899/12/31 vba .value : 1899/12/31 vba .text : 1900/1/1 0:00 3行目 excel value: 1900/01/01 excel text : 1900/1/2 0:00 dateadd : 1900/01/01 vba .value : 1900/01/01 vba .text : 1900/1/2 0:00 60行目 excel value: 1900/02/27 excel text : 1900/2/28 0:00 dateadd : 1900/02/27 vba .value : 1900/02/27 vba .text : 1900/2/28 0:00 61行目 excel value: 1900/02/28 excel text : 1900/2/29 0:00 dateadd : 1900/02/28 vba .value : 1900/02/28 vba .text : 1900/2/29 0:00 62行目 excel value: 1900/03/01 excel text : 1900/3/1 0:00 dateadd : 1900/03/01 vba .value : 1900/03/01 vba .text : 1900/3/1 0:00