【问题标题】:Excel date format and value inconsistencyExcel日期格式和数值不一致
【发布时间】:2018-11-21 17:08:30
【问题描述】:

我试图了解 Excel 如何处理日期格式和日期值。

问题的背景:

我的应用程序具有以下架构

  • Excel VBA 客户端:2016 French with windows 7 French
  • SQL 服务器数据库

在 Excel 工作簿中,工作表有一个 Change 事件处理程序,用于捕获数据(为了解释的简单,我们假设有所有日期)并将输入值保存到数据库中。值会被捕获并保存为字符串,并作为文本加载并在工作表中格式化为日期。

在工作表中,Change 事件处理程序处理使用以下代码跟踪的输入(从数据库加载数据时事件处理程序被禁用)。

With Target 
    Dim mydate As Date
    mydate = CDate(.Value)
    Debug.Print " day = " & Day(mydate) & ", month = " & Month(mydate)
End with

当手动设置格式时(右键单击单元格 > 格式化单元格 > 日期 > 选择或定义您希望的格式)月份和日期将按预期进行解释。

如果我尝试输入日期(例如 2018 年 10 月 23 日),则对输入设置验证会引发错误(我有法语操作系统和法语 Excel 版本)。在此示例中,日期中的第一项是日 (10),然后是月份(23,对于本示例无效),最后是年份 (2018)。

Sub SetValidation(ByVal dataRange as Range)

With dataRange
    With .Validation
    On Error GoTo ErrorHandler
        .Delete
        .Add Type:=xlValidateDate, AlertStyle:=xlValidAlertStop, _
            Operator:=xlGreater, Formula1:="1/1/1900"
        .InCellDropdown = True
        .IgnoreBlank = True
        .ErrorTitle = ""
        .ErrorMessage = ""
        .ShowInput = False
        .ShowError = True
    End With '.Validation
End With 'dataRange
ErrorExit:
Exit Sub
    ' process error
    GoTo ErrorExit
End Sub

当我输入 23/10/2018 时,输入被接受并保存为输入的内容(作为字符串)。

现在,例如,当输入为 04/05/2018 时,日期可能不明确,具体取决于阅读它的用户的环境是法语还是盎格鲁撒克逊语。

所以我想弄清楚使用明确格式键入的内容,并将月份显示为字符串。

如果我将格式设置为“dd mmm yyyy”,则值显示为 2018 年 5 月 4 日(天 = 04,月 = 可能),Change 事件处理程序中的跟踪输出以下内容

day = 4, month = 5 与显示一致。

现在,当使用 VBA 代码应用完全相同的格式时,它不会提供相同的输出 - 交换日期和月份。

With dataRange
    .NumberFormat = "dd mmm yyyy"
    .Value = .Value 'force format to update 
end With 

说清楚:

  • VBA 将日期字符串加载为“04/05/2018”
  • VBA 应用格式“dd mmm yyyy”,日期格式为“5 apr 2018”
  • 用户在相同格式的空白单元格中输入“04/05/2018”,日期格式为“2018 年 5 月 4 日”

问题不涉及如何为法语系统上不使用盎格鲁撒克逊约定的日期设置验证:当输入像 2018 年 3 月 23 日这样的日期时,无论值如何,验证都会引发错误被渲染。

问题是关于日期如何在内部表示以及在使用 VBA 应用格式时如何呈现给用户的不一致。我希望手动应用格式会产生与通过 VBA 应用相同的结果。

输入日期 04/05/2018 时,它会被验证,但在 VBA 中应用该格式,值变为 05/04/2018

在这两种情况下,格式指令完全相同。

我想了解为什么 VBA 代码和 Excel 用户界面有不同的行为,以及是否有可用的修复程序。

【问题讨论】:

    标签: excel vba


    【解决方案1】:

    VBA(总是)使用美国日期格式,DateValue 的帮助(见下文)对您有用吗?

    Sub SetValidation(ByVal dataRange as Range)
    
    With dataRange
        With .Validation
        On Error GoTo ErrorHandler
            .Delete
            .Add Type:=xlValidateDate, AlertStyle:=xlValidAlertStop, _
                Operator:=xlGreater, Formula1:=DateValue("04/05/2018")
            .InCellDropdown = True
            .IgnoreBlank = True
            .ErrorTitle = ""
            .ErrorMessage = ""
            .ShowInput = False
            .ShowError = True
        End With '.Validation
    End With 'dataRange
    ErrorExit:
    Exit Sub
        ' process error
        GoTo ErrorExit
    End Sub
    

    【讨论】:

    • 问题不涉及如何为法语系统上不使用盎格鲁撒克逊约定的日期设置验证:当输入像 2018 年 3 月 23 日这样的日期时,验证会引发错误无论价值如何呈现。 问题是关于如何在内部表示日期以及如何在使用 VBA 应用格式时将其呈现给用户的不一致。我希望手动应用格式会得到与通过 VBA 应用相同的结果
    • 不,如前所述,VBA 总是使用美国日期格式,你试过上面的代码吗?
    • 验证是不是的问题,而是格式化时值的变化。宏复制该值,然后格式化一系列日期,然后交换月份和日期(之后的值及其显示方式是一致的)。这不是发生问题的用户输入处理,只是之后的显示(格式化)。该应用程序是客户端服务器。假设输入发生在一天并正确播放,值从数据库加载并在上述过程之后的另一天显示。
    • .Value = DateValue("04/05/2018")
    猜你喜欢
    • 1970-01-01
    • 2016-08-17
    • 2020-08-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多