いくつかの日付を含むスプレッドシートがあります。これらは通常、_mm/dd/yyyy
_または_mm/dd/yyyy hh:mm
_のいずれかに表示されます。
問題は、日付が常に正しく入力されるとは限らず、コード内の日付であることを確認するためのチェックが必要なことです。
私の元々の考えは、IsDate
を使用してチェックまたはCDate
を使用することでしたが、これは機能していないようでした。日付の代わりに文字列を返していました。
それ以来、これらの機能が期待どおりに機能しないことを示す小さな実験を設定しました。方法論は次のとおりです。
=DATE(2013,10,28)
を入力します=A1*1
_これは数値と等しくなければなりません(41575)この小さなスクリプトを実行する
_Sub test()
MsgBox ("Start:" & TypeName(ActiveCell.Value) & " " & IsDate(ActiveCell.Value))
ActiveCell.Value = Format(ActiveCell.Value, "mm/dd/yyyy")
MsgBox ("After format: " & TypeName(ActiveCell.Value) & " " & IsDate(ActiveCell.Value))
ActiveCell.Value = CDate(ActiveCell.Value)
MsgBox ("After Cdate: " & TypeName(ActiveCell.Value) & " " & IsDate(ActiveCell.Value))
End Sub
_
スクリプトが開始すると、セルは日付型であり、IsDate
はtrueを返します。 Format
を実行した後は、文字列型ですが、IsDate
は依然としてtrueを返します。 CDate
もセルを文字列に変換します。セルB1も0を返します(文字列* 1であるため)。
だから私は質問を要約することを推測する:
Format
とCDate
がセルを文字列に変更するのですか?セルのcontent、セルの表示形式、 VBAによるセルからのデータ型読み取り、およびデータ型書き込み VBAからのセルとExcelがこれを自動的に解釈する方法。 (たとえば this previous answer を参照してください。)これらの関係は少し複雑になる可能性があります。Excelは、あるタイプ(文字列など)の値を特定の他のデータタイプ(たとえば日付)そして、これに基づいて表示形式を自動的に変更します。最も安全なのは、明示的にすべてを行い、この自動機能に依存しないことです。
私はあなたの実験を実行しましたが、あなたと同じ結果は得られません。私のセルA1はずっと日付のままで、B1は41575のままです。だからあなたの質問#1に答えることができません。結果はおそらく、Excelのバージョン/設定がその内容に基づいてセルの数値形式を自動的に検出/変更する方法に依存します。
質問#2、「セルが日付値を返すことを確認するにはどうすればよいですか」:まあ、日付値を「返す」ことの意味がわかりませんが、必要な場合はVBAからの書き込み内容に基づいて、日付として表示される数値どちらか:
Excelが日付や形式として自動的に解釈することを期待する文字列値をセルに書き込みます。指をクロスします。明らかにこれは非常に堅牢ではありません。または、
VBAからセルに数値を書き込み(明らかに日付型が目的の型ですが、整数、長整数、単数、または倍精度でも同様です)、.NumberFormat
を使用してセルの数値形式を目的の日付形式に明示的に設定しますプロパティ(またはExcelで手動)。これははるかに堅牢です。
既存のセルの内容を日付として表示できることを確認したい場合は、次の関数が役立ちます。
Function CellContentCanBeInterpretedAsADate(cell As Range) As Boolean
Dim d As Date
On Error Resume Next
d = CDate(cell.Value)
If Err.Number <> 0 Then
CellContentCanBeInterpretedAsADate = False
Else
CellContentCanBeInterpretedAsADate = True
End If
On Error GoTo 0
End Function
使用例:
Dim cell As Range
Set cell = Range("A1")
If CellContentCanBeInterpretedAsADate(cell) Then
cell.NumberFormat = "mm/dd/yyyy hh:mm"
Else
cell.NumberFormat = "General"
End If
Format
は値を文字列に変換します。 IsDate
は、文字列を解析して有効な日付を取得できるため、依然としてtrueを返します。
セルを文字列に変更したくない場合は、Format
を使用しないでください。 (IOW、最初から文字列に変換しないでください。)Cell.NumberFormat
を選択し、表示する日付形式に設定します。
ActiveCell.NumberFormat = "mm/dd/yy" ' Outputs 10/28/13
ActiveCell.NumberFormat = "dd/mm/yyyy" ' Outputs 28/10/2013
入力いただきありがとうございます。明らかに、他のマシンでは再現されない問題がいくつか見られます。ジャンの答えに基づいて、私はうまくいくように見えるエレガントではない解決策を思いつきました。
セルにcdateから直接値を渡すか、単に数値としてフォーマットする場合、セル値を文字列として残すため、その数値をセルに戻す前に日付値を数値変数に渡す必要がありました。
Function CellContentCanBeInterpretedAsADate(cell As Range) As Boolean
Dim d As Date
On Error Resume Next
d = CDate(cell.Value)
If Err.Number <> 0 Then
CellContentCanBeInterpretedAsADate = False
Else
CellContentCanBeInterpretedAsADate = True
End If
On Error GoTo 0
End Function
使用例:
Dim cell As Range
dim cvalue as double
Set cell = Range("A1")
If CellContentCanBeInterpretedAsADate(cell) Then
cvalue = cdate(cell.value)
cell.value = cvalue
cell.NumberFormat = "mm/dd/yyyy hh:mm"
Else
cell.NumberFormat = "General"
End If
サイドでvalue(cellref)
を使用して、セルを評価します。文字列は「#Value」エラーを生成しますが、日付は数値に解決されます(例:43173
)。