Excel VBAdate格式

我有一个包含许多date的电子表格。 这些通常以mm/dd/yyyymm/dd/yyyy hh:mm

问题是date不总是正确的,我想检查,以确保它们是代码中的date。

我原来的想法是使用IsDate检查或CDate但这似乎并没有工作:它仍然返回string,而不是date。

我已经做了一个小实验,表明这些function并不像我期望的那样工作。 方法是:

  1. 在单元格A1中input公式=DATE(2013,10,28)
  2. 单元格B1公式=A1*1应该等于一个数字(41575)
  3. 运行这个小脚本

     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 

当脚本启动的单元格是一个types的date和IsDate返回true。 通过Format运行后,它是stringtypes,但IsDate仍然返回true。 CDate也会将单元格转换为string。 单元格B1现在也将返回0(因为它是一个string* 1)。

所以我想总结一下问题:

  1. 为什么FormatCDate更改我的单元格string?
  2. 我怎样才能确保一个单元格会返回一个date值,而不仅仅是一个看起来像date的string?

区分单元格的内容显示格式 ,从VBA 读取数据types以及从VBA 写入单元格的数据types以及Excel如何自动解释这些数据是非常重要的。 (请参阅前面的回答 。)这些关系可能有点复杂,因为Excel会将某种types(例如string)的值解释为某种其他数据types(例如date),然后自动更改显示格式基于此。 你最安全的赌注,它明确地做一切事情,而不是依靠这种自动的东西。

我跑了你的实验,我没有得到和你一样的结果。 我的单元格A1始终保持一个date,B1保持41575.所以我不能回答你的问题#1。 结果可能取决于您的Excel版本/设置如何根据其内容自动检测/更改单元格的数字格式。

问题#2,“我怎样才能确保一个单元格会返回一个date值”:好吧,不知道你的意思是“返回”一个date值,但是如果你想要它包含一个显示为date的数值,根据你从VBA写到的内容,你可以:

  • 向单元格写入一个string值,希望Excel自动将其解释为date和格式。 交叉手指。 显然这不是很健壮。 要么,

  • 从VBA中写入一个数值到单元格(显然Datetypes是预期的types,但是一个Integer,Long,Single或Double也可以),并且用单元格明确地设置单元格的数字格式为你想要的date格式.NumberFormat属性(或在Excel中手动)。 这是更强大的。

如果你想检查现有的单元格内容可以显示为一个date,那么这里有一个函数可以帮助你:

 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将值转换为string。 IsDate仍然返回true,因为它可以parsing该string并获取有效的date。

如果您不想将单元格更改为string,请不要使用“ Format 。 (IOW,首先不要将它们转换为string。)使用Cell.NumberFormat ,并将其设置为要显示的date格式。

 ActiveCell.NumberFormat = "mm/dd/yy" ' Outputs 10/28/13 ActiveCell.NumberFormat = "dd/mm/yyyy" ' Outputs 28/10/2013 

感谢您的input。 我很明显看到一些问题没有在其他机器上复制。 根据Jean的回答,我提出了一些看似不太好的解决scheme。

因为如果我直接从cdate传递单元格的值,或者只是将其格式化为数字,那么它将单元格值保留为string,所以在将该数字传递回单元格之前,必须将date值传递给数字variables。

 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)来评估单元格。 string将产生“#Value”错误,但dateparsing为一个数字(例如43173 )。