Windows 10 Pro, Regionale Einstellungen in englisches Englisch. In Excel VBA habe ich die Zeichenfolge "02/05/2017 16:30" . In Großbritannien bedeutet dies "02. Mai 2017 16". 30 "
Aber VBA wandelt dies irgendwie in ein US-Format um und setzt in der Zelle "05/02/2017 16:30".
Der VBA-Code ist so
Dim sField As String
sField = "02/05/2017 16:30"
ws.Cells(1,1) = sField
Ich kann CDate verwenden, um dies zu umgehen, aber CDate, aber dies erfordert zusätzlichen Code, um zu bestimmen, welche Zellen Datumsangaben sind und welche nicht, während die implizite Konvertierung für alle Typen funktioniert.
Verwenden Sie stattdessen eine Date-Variable und geben Sie Ihr Datum immer in MDY in VBA an.
Dim sField As Date
sField = #05/02/2017 16:30#
ws.Cells(1,1) = sField
AFAIK in VBA müssen Sie immer auf den "amerikanischen Weg" arbeiten, mit Datumsangaben MDY. Es folgt NICHT den regionalen Einstellungen. Was gut ist, denn damit kann derselbe Code in heterogenen Umgebungen ausgeführt werden.
Dies ist eine Problemumgehung im VBA-Code:
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
Es nimmt das Datum als Zeichenfolge an und teilt es durch /
. Dann dauert es das Jahr, den Monat und den Tag und es wird mit Hilfe von DateSerial()
ein neues Datum erstellt. DateSerial MSDN .
Stellen Sie in solchen Fällen sicher, dass Sie das korrekte Datum an Excel übergeben. Dort können Sie das Format durch etwas ändern, das so einfach ist:
Range("A1").NumberFormat = "m/d/yyyy"
Um sicherzugehen, dass Sie das korrekte Datum übergeben, probieren Sie einfach Month(YourDate)
über dem Datum oder Day(YourDate)
.
Ich verwende lieber die eingebauten VBA-Funktionen DateSerial (Jahr, Monat, Tag) und TimeSerial (Stunde, Minute, Sekunde).
Dim myDateTime as date
mydateTime = DateSerial(2017, 5, 2) + TimeSerial(16, 30, 0)
ws.Cells(1,1) = myDateTime
Sie können dann die Zahlenformatierung in der Excel-Zelle nach Ihren Wünschen einstellen.
Ich gehe davon aus, dass dies schneller ist, da zuvor keine Zeichenfolge übersetzt werden muss. Noch wichtiger für mich als Programmierer sind die Parameter eindeutig. Ich muss mich nicht um unterschiedliche regionale Einstellungen kümmern.
Ich habe ein verwandtes Problem gelöst. Meine Arbeitsmappe ist nur zur Verwendung in Großbritannien bestimmt. Es verfügt über ein Formular, in dem Sie Details zu Bargeld eingeben können, das an verschiedenen Orten abgeholt wurde. Der Benutzer verfügt über zwei Einzelzellenfelder, um jeden Veranstaltungsort zu identifizieren. normalerweise ein Ort und ein Datum, aber manchmal enthält das Feld "Datum" stattdessen einen erweiterten Standortnamen. Datum sollte als TT/MM/JJ eingegeben werden, aber fast alles Erkennbare wird akzeptiert mit Ausnahme von mm/tt/jj. Die Details werden gespeichert und später zum Drucken in formatierte Arbeitsblätter kopiert. Ich habe den Speicher im Speicher überprüft. Nachdem die Arbeitsmappe jedoch einige Monate in Gebrauch war, stellte ich fest, dass der Benutzer ein gültiges Datum in einer Zelle im Format TT/MM/[JJ] JJ (z. B. 05/11/17) und seine Interpretation als eingegeben hat mm/tt/[jj] yy würde auch ein gültiges Datum angeben, dann würde das Datum unklar als 11-Mar statt 05-Nov gedruckt werden.
Einige Codeausschnitte:
'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).