[英]Unexpected Date Results - Excel VBA - Day Month Year get mixed up
我有兩個日期范圍,我試圖將它們轉換為兩個字符串OldestDate
和NewestDate
。 但是,今天我遇到了問題,其中一個日期的格式為dd/mm/yyyy
,而另一個日期的格式為mm/dd/yyyy
這是我放在兩個單獨工作表上的示例數據: 注意,我復制了“日期”格式單元格旁邊的單元格內容以供視覺參考,但在我的實際數據中,只有“日期”列。
和
這是我用來轉換為字符串和調試輸出的代碼:
Public Sub Get_Date()
DateHeader = "A"
Set rng = Application.ActiveSheet.Range(DateHeader & "1:" & DateHeader & Cells(Rows.Count, 1).End(xlUp).Offset(1).Row)
OldestDate = Format(WorksheetFunction.min(rng), "dd/mm/yyyy")
Debug.Print OldestDate
NewestDate = Format(WorksheetFunction.Max(rng), "dd/mm/yyyy")
Debug.Print NewestDate
'20200908
'Sept 8, 2020
aDate = Split(OldestDate, "/")
If UBound(aDate) = 2 Then
sDay = aDate(0)
If Len(sDay) = 1 Then
sDay = "0" & sDay
End If
sMonth = aDate(1)
If Len(sMonth) = 1 Then
sMonth = "0" & sMonth
End If
sYear = aDate(2)
End If
OldestDateStr = sYear & sMonth & sDay
Debug.Print OldestDateStr
aDate = Split(NewestDate, "/")
If UBound(aDate) = 2 Then
sDay = aDate(0)
If Len(sDay) = 1 Then
sDay = "0" & sDay
End If
sMonth = aDate(1)
If Len(sMonth) = 1 Then
sMonth = "0" & sMonth
End If
sYear = aDate(2)
End If
NewestDateStr = sYear & sMonth & sDay
Debug.Print NewestDateStr
End Sub
控制台/調試:
7/10/2020 ' This is Correct
8/10/2020 ' This is Correct
20201007 ' This is Correct
20201008 ' This is Correct
8/17/2020 ' Incorrect
8/18/2020 ' Incorrect
20201708 ' Incorrect
20201808 ' Incorrect
我采取了一種解決方法與調試相比,只是刮掉了月/年,然后在第一天硬編碼 1 並使用函數EoMonth
來獲得最后一天。 這被用來創建一個 URL 以根據日期進行查詢,查詢將花費更長的時間並有額外的數據,但是對我來說沒關系,我寧願擁有 100% 的可靠性。
這是新代碼,閱讀起來也不那么復雜:)
Public Sub Get_Date()
DateHeader = "A"
Set rng = Application.ActiveSheet.Range(DateHeader & "1:" & DateHeader & Cells(Rows.Count, 1).End(xlUp).Offset(1).Row)
Dim OldestDate As Date, NewestDate As Date
OldestDate = Format(WorksheetFunction.min(rng), "mm/yyyy")
Debug.Print OldestDate
NewestDate = Format(WorksheetFunction.Max(rng), "mm/yyyy")
Debug.Print NewestDate
'20200908
'Sept 8, 2020
'OldestDate
aDate = Split(OldestDate, "/")
sYear = aDate(2)
sMonth = aDate(0)
If Len(sMonth) = 1 Then
sMonth = "0" & sMonth
End If
sDay = "01"
OldestDateStr = sYear & sMonth & sDay
Debug.Print OldestDateStr
'NewestDate
aDate = Split(NewestDate, "/")
sYear = aDate(2)
sMonth = aDate(0)
If Len(sMonth) = 1 Then
sMonth = "0" & sMonth
End If
sDay = Day(Application.WorksheetFunction.EoMonth(NewestDate , 0))
NewestDateStr = sYear & sMonth & sDay
Debug.Print NewestDateStr
End Sub
調試:(注意我將一個日期更改為 Nov 只是為了測試)
10/1/2020
11/1/2020
20201001
20201130
8/1/2020
8/1/2020
20200801
20200830
Format 將一次性完成此操作:
OldestDateStr = Format(WorksheetFunction.min(rng), "yyyymmdd")
Debug.Print OldestDateStr
NewestDateStr = Format(WorksheetFunction.Max(rng), "yyyymmdd")
Debug.Print NewestDateStr
如果您的單元格值是格式化為“反向”美國格式mm/dd/yyyy 的文本日期,並且您不在美國環境中,則可以使用此函數將這些值轉換為真實的日期值:
' Converts a US formatted date/time string to a date value.
'
' Examples:
' 7/6/2016 7:00 PM -> 2016-07-06 19:00:00
' 7/6 7:00 PM -> 2018-07-06 19:00:00 ' Current year is 2018.
' 7/6/46 7:00 PM -> 1946-07-06 19:00:00
' 8/9-1982 9:33 -> 1982-08-09 09:33:00
' 2/29 14:21:56 -> 2039-02-01 14:21:56 ' Month/year.
' 2/39 14:21:56 -> 1939-02-01 14:21:56 ' Month/year.
' 7/6/46 7 -> 1946-07-06 00:00:00 ' Cannot read time.
' 7:32 -> 1899-12-30 07:32:00 ' Time value only.
' 7:32 PM -> 1899-12-30 19:32:00 ' Time value only.
' 7.32 PM -> 1899-12-30 19:32:00 ' Time value only.
' 14:21:56 -> 1899-12-30 14:21:56 ' Time value only.
'
' 2018-03-31. Gustav Brock. Cactus Data ApS, CPH.
'
Public Function CDateUs( _
ByVal Expression As String) _
As Date
Const PartSeparator As String = " "
Const DateSeparator As String = "/"
Const DashSeparator As String = "-"
Const MaxPartCount As Integer = 2
Dim Parts As Variant
Dim DateParts As Variant
Dim DatePart As Date
Dim TimePart As Date
Dim Result As Date
' Split expression into maximum two parts.
Parts = Split(Expression, PartSeparator, MaxPartCount)
If IsDate(Parts(0)) Then
' A date or time part is found.
' Replace dashes with slashes.
Parts(0) = Replace(Parts(0), DashSeparator, DateSeparator)
If InStr(1, Parts(0), DateSeparator) > 1 Then
' A date part is found.
DateParts = Split(Parts(0), DateSeparator)
If UBound(DateParts) = 2 Then
' The date includes year.
DatePart = DateSerial(DateParts(2), DateParts(0), DateParts(1))
Else
If IsDate(CStr(Year(Date)) & DateSeparator & Join(DateParts, DateSeparator)) Then
' Use current year.
DatePart = DateSerial(Year(Date), DateParts(0), DateParts(1))
Else
' Expression contains month/year.
DatePart = CDate(Join(DateParts, DateSeparator))
End If
End If
If UBound(Parts) = 1 Then
If IsDate(Parts(1)) Then
' A time part is found.
TimePart = CDate(Parts(1))
End If
End If
Else
' A time part it must be.
' Concatenate an AM/PM part if present.
TimePart = CDate(Join(Parts, PartSeparator))
End If
End If
Result = DatePart + TimePart
CDateUs = Result
End Function
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.