2017-12-18 355 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