为什么Day()在无效输入时返回30?

Kaz*_*Kaz 5 vba

这是我发现的一个问题,然后我自己解决了,因为我找不到关于这个主题的SO问题,我想我会创建一个供将来参考.

我不小心写了

debug.Print day(ow)
Run Code Online (Sandbox Code Playgroud)

代替

debug.Print day(now)
Run Code Online (Sandbox Code Playgroud)

令我惊讶的是,我没有抛出错误,而是得到了以下结果:

debug.Print day(ow)
 30 
Run Code Online (Sandbox Code Playgroud)

当给定未初始化的变量作为输入时,为什么不抛出错误?

Bat*_*eba 7

除非您Option Explicit在模块的顶部写入,否则VBA允许您Variant在第一个使用点自发地创建变量(作为类型).

这些变量实际上是零初始化的.

因此day(ow)相当于day(0)评估为30.(对应于1899年12月30日).


Kaz*_*Kaz 6

简单的答案是默认值.

以下结果说明如下:

debug.Print day(0)
 30 
Run Code Online (Sandbox Code Playgroud)

为什么?因为Day(0)在VBA日历中是日期30/12/1899.通过以下方式展示:

debug.Print format(Cdate(0), "dd/mm/yyyy")
30/12/1899
Run Code Online (Sandbox Code Playgroud)

除非您Option Explicit在模块的顶部写入,否则VBA允许您Variant在第一个使用点自发地创建变量(作为类型).

创建变量(但未设置)时,它将设置为其默认值.示例默认值:

Long --- 0(同其它数字,包括Date,Integer, Byte,Double等等)
Boolean--- False(在VBA的许可类型的系统,可被强制转换为0)
Variant--- Empty (其也可以被强制转换为0)
String--- Zero-Length-String ("")(其实际上,不能被强制0,如果你试图打印会抛出错误Day(""))
Any Object---Nothing

因此,如果您编写Debug.Print Day(Var)并且Var是任何数字数据类型,布尔值或Variant(或者从未在第一个地方声明),那么将强制执行此操作,Day(0)从而得到30如上所示的输出.


在问题的具体情况:

VBA识别ow为未声明的变量,因此它创建它(并将其初始化为Variant数据类型)并将其传递给Day().由于它是Variant,因此它具有初始值Empty,然后被强制转换0,从而产生Day(0)返回值30.

  • 这有可能成为一个全面的答案(不像我可以在一组红绿灯上的iPhone上挖掘出来),特别是如果你提到"Option Explicit".请随意从我的回答中取出. (4认同)