【问题标题】:Which date system does VBA recognise/default to?VBA 识别/默认哪个日期系统?
【发布时间】:2019-06-24 23:41:55
【问题描述】:

我正在 excel 中编写一个 vba 子例程,将 2 个日期之间的所有日期值存储在一个维度数组中,然后检查另一个工作表上某个范围内的每个值。

我的问题是,当代码获取日期值(作为整数(或双精度 - 无论它实际使用哪个))时,它存储的值比工作表上的日期值大 1462。

我使用的是 1904 日期系统,所以我可以使用负时间值,而且我在澳大利亚,所以日期格式为 dd/mm/yyyy。

举个例子;

在工作表上: 2019 年 1 月 1 日 = 42004

在代码中:01/01/2019 = 43466

我知道差异与使用 1900 与 1904 日期系统时的日期值之间的差异相同,这使我相信 VBA 可能将工作表值默认为 1900 并在代码时再次将值转换为 1904运行了吗?

此工作簿设置如下:

Sheet1Range("A1:A25") 中包含从 01/01/2019 到 25/01/2019 的日期。

Sheet2 包含单元格 A1 中的 01/01/2019 和单元格 A2 中的 10/01/2019 和一个 activeX commandbutton

还有代码:

Private Sub CommandButton1_Click()
Dim myStart As Long
Dim myEnd As Long

myStart = Me.Range("A1").Value
myEnd = Me.Range("A2").Value

Dim v As Variant
Dim x As Long
Dim myArr As Variant
ReDim myArr(0 To 100)
x = 0

For v = myStart To myEnd
    If v = Empty Then Exit For
    myArr(x) = v
    Debug.Print ("v = " & v)
    Debug.Print ("myArr = " & myArr(x))
    x = x + 1
Next

Dim lastrow As Long
lastrow = Me.Cells(Rows.Count, 4).End(xlUp).Row
x = 0
For Each cell In Sheet1.Range("A1:A100")
Debug.Print (CDbl(cell))
    If cell = myArr(x) Then
        Me.Cells(lastrow, 3).Value = cell
        Me.Cells(lastrow, 4).Value = Format(cell, "dd/mm/yyyy")
        lastrow = lastrow + 1
    End If
    x = x + 1
Next
End Sub

第 3 列和第 4 列中cell 值的输出如下(前 5 行用于演示):

       C         D             Sheet1.Range("A1:A5")[when displayed as number format] 
1    43466    01/01/2019                42004
2    43467    02/01/2019                42005
3    43468    03/01/2019                42006
4    43469    04/01/2019                42007
5    43470    05/01/2019                42008

日期以短日期格式而非数值形式写入单元格。

使用我注意到?cdbl(DateValue(now)) = 43496 (31/01/2019) 的恐吓窗口,这让我想知道哪些值对于使用 1904 日期系统的日期是正确的?根据 Sheet1 中的值,它应该是 42034

问题是由我使用的数据类型或函数引起的,是否如前所述 - 当使用 VBA 将值分配给 Sheet2 时,工作表将它们转换为 1904,是 Excel 的错误还是其他问题?

我发现了一个与 here on mrexcel 相同的问题的问题,但是解决方法是更改​​ Excel 以使用 1900 日期系统或从代码中的值中减去 1462,我希望避免这两种情况。

【问题讨论】:

    标签: excel vba date


    【解决方案1】:

    通常,VBA 中的日期系统与 Excel 中的日期系统不同。您可以有以下 3 个日期系统选项:

    • Excel 日期
    • 带有 1904 属性的 Excel 日期
    • VBA 日期

    这就是区别:

    日期转换为数字。例如,每个日期都转换为数字,但起始数字有点不同。

    • 在 Excel 中,1 被转换为 01.January.1900
    • 在 VBA 中,1 被转换为 31.December.1899
    • 在 1904 的 Excel 中,1 转换为 02.January.1904

    1904 系统(或缺少系统)是按工作簿设置的。因此,如果您在 Excel 中有 2 个工作簿,一个带有 1904,一个没有它,它会相应地识别它们。系统设置在:

    文件 > 选项 > 高级 > 使用 1904 日期系统

    一般来说,如果有可能有人以错误的系统更改了您的工作簿,请考虑在打开工作簿时添加此检查:

    Private Sub Workbook_Open()    
        If ThisWorkbook.Date1904 Then
            MsgBox "System is 1904, consider some action!"
        End If        
    End Sub
    

    如果您想知道选择哪个系统 - 我可以建议从不使用 1904。

    【讨论】:

    • 啊。 VBA 开始日期是我所缺少的!我敢打赌,现在你已经解释过了,我可以在十亿个地方找到这些信息!
    • @SamuelEverson - VBA 日期和 excel 日期的差异是故意完成的,以确保它们在 28.Feb.1900 之后相互匹配。
    • 我只是通过链接的故事阅读,非常有趣。
    • 另外,我只使用 1904 来计算负时间值,但在使用 1900 系统的同时找到一种方法来实现这一点是另一回事。
    • @SamuelEverson - 链接的故事实际上以另一种方式向我展示了 BG,看到他如此快速地提出这个问题,我印象深刻。对于 1904 - 我从不使用它,因为当错误/错误发生时,工作表中的 4 年实际上是一个巨大的差异。但是,如果你能很好地控制它,那也是一种选择。
    【解决方案2】:

    为了为我的示例提供解决方案,一位同事提到,如果您将日期值调暗为 date 数据类型,那么值表 -> vba -> 表的问题就会消失。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-06-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多