excel vba字符串到日期

Posted

技术标签:

【中文标题】excel vba字符串到日期【英文标题】:excel vba string to date 【发布时间】:2018-05-31 16:03:14 【问题描述】:

Windows 10 专业版,区域设置为英国英语。 在 Excel VBA 中,我有一个字符串“02/05/2017 16:30” 这在英国的意思是“2017 年 5 月 2 日 16:30”

但 VBA 以某种方式将此转换为美国格式,并在单元格中输入“05/02/2017 16:30”

VBA代码是这样的

Dim sField As String
sField = "02/05/2017 16:30"
ws.Cells(1,1) = sField

我可以使用 CDate 来解决这个问题,但 CDate 需要额外的代码来确定哪些单元格是日期,哪些不是,而隐式转换适用于所有类型。

【问题讨论】:

您没有太多选择。如果你想控制输出,你需要更多的代码——真的没那么费劲! Excel VBA - Convert Text to Date?的可能重复 【参考方案1】:

请改用 Date 变量,并始终在 VBA 中的 MDY 中提供您的日期。

Dim sField As Date
sField = #05/02/2017 16:30#
ws.Cells(1,1) = sField

在 VBA 中的 AFAIK,您必须始终以“美国方式”工作,日期为 MDY。它不遵循区域设置。这很好,因为这样可以在异构环境中运行相同的代码。

【讨论】:

application.international(xlMDY) 可用于确定它是否以“美国方式”运作 - msdn.microsoft.com/en-us/vba/excel-vba/articles/… val = Application.International(xlMDY) 这是 FALSE val = Application.International(xlDateOrder) 这是 1 暗示 DMY 格式。然而,隐式字符串到日期的转换采用美国日期格式,除非月份已经过了 12 月,在这种情况下它采用英国格式。糟糕的设计。【参考方案2】:

这是 VBA 代码中的一些解决方法:

Sub Main()        
    Dim myInput     As String
    Dim splitMe     As Variant
    Dim outputDate  As Date

    myInput = "02/05/2017 16:30"
    splitMe = Split(myInput, "/")        
    outputDate = DateSerial(Left(splitMe(2), 4), splitMe(1), splitMe(0))        
    Debug.Print Format(outputDate, "DD-MMM-YY")
    Debug.Print Format(outputDate, "DD-MM-YYYY")           
End Sub

它将日期作为一个字符串,并用/ 分割它。然后它需要年、月和日,并在DateSerial() 的帮助下建立一个新的日期。 DateSerial MSDN.

在这种情况下,请确保您将正确的日期传递给 excel,然后您可以通过以下简单的方式更改格式:

Range("A1").NumberFormat = "m/d/yyyy"

为确保您传递的日期正确,只需在日期上尝试Month(YourDate)Day(YourDate)

【讨论】:

【参考方案3】:

我解决了一个相关问题。我的工作簿仅供在英国使用。它有一张表格,用于输入在各个场所收集的现金的详细信息。用户有两个单格字段来识别每个场地;通常是位置和日期,但有时“日期”字段将包含扩展的位置名称。 日期应该输入为 dd/mm/yy,但几乎可以接受任何可识别的内容除了 mm/dd/yy。 详细信息存储在内存中,然后复制到格式化的工作表中进行打印。我验证了内存中的存储。但在工作簿使用几个月后,我发现如果用户在单元格中输入有效日期,格式为 dd/mm/[yy]yy(例如 05/11/17),其解释为mm/dd/[yy]yy 也会给出一个有效的日期,然后日期会模糊地打印为 11-Mar 而不是 05-Nov。

一些代码sn-ps:

'Data structure:
Public Type BkItem             'An item of income, for banking.
    ItemName As String         'The first field, just a text name.
    ItemDate As Date           'The second field, interpreted as a date.
    ItemDateNumber As Long     'The date as internally stored as an integer.
    ItemDateString As String   'Re-formatted string, e.g. "05-Nov-17".
'   ...
End Type    'BkItem.

'Input validation:
BankData = Range(.Cells(BankFirstRow, BankFirstCol), _
                 .Cells(BankLastItemLastRow, BankLastCol))

With BankItem(BankTotalItems)
    .ItemName = IName
    .ItemDateString = BankData(<row>, <col>)
    .ItemDateNumber = DateToLong(.ItemDateString)
End With

'Utility routine. "Paper" is a 2-dimensional array of all the data to be printed
'on one or more pages; "Dest" is a global range.:

Sub OutputDataToSheet(ByVal Size As Long, ByRef CurrentSheet As String, _
                      ByRef Paper() As Variant)
    Worksheets(CurrentSheet).Activate
    Set Dest = Worksheets(CurrentSheet).Range((Cells(1, 1)), _
                                              (Cells(Size, LastCol)))
    Dest.Value = Paper 'Copy data to final sheet for printing.                                         
End Sub    'OutputDataToSheet.

'As we build the array "Paper", it helps to format those cells on the final
'printout worksheet which are going to contain dates.

.Range(Cells(CurRow, L15c01), Cells(CurRow, L15c01)).NumberFormat = "dd-Mmm-yyyy"
'For the item date.
.Range(Cells(CurRow, L15c01), Cells(CurRow, L15c01)).HorizontalAlignment = xlCenter

If IsDate(BankItem(item).ItemDateString) Then
    Paper(<row>, <col>) = BankItem(item).ItemDateNumber
    'Date as a number, so OutputDataToSheet preserves UK date format.
Else
    Paper(<row>, <col>) = BankItem(item).ItemDateString
    'Extension of name.
End If  'IsDate(.ItemDateString).

【讨论】:

可能有更优雅的方法来做到这一点;但就 Excel 而言,我是一个自学成才的七十多岁的人。并且“如果它有效,请不要修改它!”。 和你一样,我最终使用 IsDate 来判断传入的字符串是否为“日期”,如果是,则使用 CDate(string)【参考方案4】:

我宁愿使用内置的 VBA 函数 DateSerial(year, month, day) 和 TimeSerial(hour, min, sec)。

Dim myDateTime as date
mydateTime = DateSerial(2017, 5, 2) + TimeSerial(16, 30, 0)
ws.Cells(1,1) = myDateTime

然后,您可以根据自己的喜好设置 Excel 单元格上的数字格式。

我认为这会更快,因为不需要事先翻译任何字符串。对我作为程序员来说更重要的是,参数是明确的。我不必担心不同的区域设置。

【讨论】:

是的,但是数据以字符串形式到达,有些字符串是日期,有些是数字,有些是纯文本等 将字符串简单分配给单元格,例如 worksheet.cells(1,1)= string,适用于所有类型,除了 Date,其中 Excel 假定日期为美国格式,除非月份已过 12 月,在这种情况下,它假定为英国格式! 非常好!我找了好几个小时,然后决定自己重新发明***。我自己的DateSerial() 函数有很多问题。谢天谢地,我又用谷歌搜索了!

以上是关于excel vba字符串到日期的主要内容,如果未能解决你的问题,请参考以下文章

Excel VBA 日期格式

为啥 Excel vba 复制到剪贴板不一致?

Excel vba 将数字转换成字符串的函数是哪个

Excel:VBA 到 TRIM 长度不同的初始字符串

如何用EXCEL VBA批量提取JPG文件日期时间信息到表格中?

Excel VBA中的时间计算