達人養成塾 小川です。
とある受講生からこんな質問がありました。
何かというと。
たとえば、以下のコードを実行すると、セル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