2017-12-18 186 views
5

Windows 10 Pro,区域设置为英国英语。 在Excel VBA我有一个字符串“2017年2月5日16:30” 的是,在英国,是指“2017年05月02日16:30”excel vba string date date

但VBA变成这个美国格式莫名其妙,并在细胞提出“2017年5月2日16:30”

的VBA代码是这样的

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

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

+0

您没有太多的选择。如果你想控制输出,你需要更多的代码 - 这真的不是那么辛苦! – Rory

+1

[Excel VBA - 将文本转换为日期?](https://stackoverflow.com/questions/20375233/excel-vba-convert-text-to-date)可能重复 – eirikdaude

回答

4

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

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

AFAIK在VBA中,您必须始终使用'美国的方式',与日期MDY。它不符合地区设置。这很好,因为它可以在异构环境中运行相同的代码。

+1

application.international(xlMDY)可用于确定它是否以'美国方式'工作 - https://msdn.microsoft.com/en-us/vba/excel-vba/articles/application-international-property-excel – Phil

+0

val = Application.International(xlMDY)这是FALSE val = Application.International(xlDateOrder)这是暗示DMY格式的1。然而,隐含的字符串到日期转换采用美国日期格式,除非该月份已过去十二月,在这种情况下,它会采用英国格式。可怕的设计。 – user40966

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

在这样的情况下,请确保您传递正确的日期脱颖而出,并有可能通过一些,因为这容易更改格式:

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

要确保,要传递的正确的日期,只需在日期上尝试Month(YourDate)Day(YourDate)即可。

0

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

一些代码片段:

'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). 
+0

可能有更多更优雅的方法来做到这一点;但就Excel而言,我是一个自学成才的七十年代语言学家。而且“如果有效,不要修补它!”。 – OldColdDreamer

+0

像你一样,我最终使用IsDate来判断传入的字符串是否为“日期”,如果是,则使用CDate(字符串) – user40966

0

我宁愿使用内置的VBA函数DateSerial(年,月,日)和TimeSerial的(小时,分,秒)。

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

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

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

+0

是的,但数据到达字符串,一些字符串是日期,一些是数字,有些是纯文本等。String到单元格的简单赋值,例如worksheet.cells(1,1)= string,适用于所有类型,除了Date假定日期为美国格式的日期,除非月份是去年十二月,在这种情况下,它采用英国格式! – user40966