簡體   English   中英

VBA 將日期轉換為周數

[英]VBA Convert date to week number

在 VBA 中,我想將日期 03/11/2017(DD/MM/YYYY) 轉換為該日期的周數。

到目前為止,我有以下代碼:

   'geting the date out of the string
    HeadlineTemp = Mid(VRHeadline, InStr(VRHeadline, "[") + 1, 10)
   'switch "." to "/"
    HeadlineTemp = Replace(HeadlineTemp, ".", "/")
   'convert to a date
    FristVRFirstKW = CDate(HeadlineTemp)

現在,我需要一個 function 來將該日期轉換為一年中的周數。 第一個工作日是星期一。

要將星期一作為第一天的周數,請使用以下內容:

WorksheetFunction.WeekNum(now, vbMonday)

使用 VBA,要將日期轉換為 isoWeeknumber,您只需要DatePart函數(其中 DT 是感興趣的日期):

isoWeekNumber = DatePart("ww", DT, vbMonday, vbFirstFourDays)

如果您想使用 ISO 8601 中指定的定義以外的其他定義,請研究FirstDayOfWeekFirstWeekOfYear的其他一些選項

筆記

正如@Mike85 所指出的那樣, DatePart (以及Format )函數中存在一個錯誤,其中 Monday 可能被錯誤地賦予周數 53,而它應該是 1。

有多種解決方法。

在 Excel 2013+(Excel for Mac 2011+)中,您可以使用 ISO Weeknumber:

isoWeekNumber = WorksheetFunction.isoWeekNum(dt)

對於較早的版本,您可以測試星期一並在必要時進行調整,或者您可以編寫單獨的例程。

當涉及到周數時要小心,因為周圍有不同的定義。 Excel 定義不同於 ISO 定義。 獲取 ISO 周數使用(從http://www.rondebruin.nl/win/s8/win001.htm復制)

Public Function IsoWeekNumber(d As Date) As Integer
    Dim d2 As Long
    d2 = DateSerial(Year(d - Weekday(d - 1) + 4), 1, 3)
    IsoWeekNumber = Int((d - d2 + Weekday(d2) + 5) / 7)
End Function

WeekdayName( number, [abbreviate], [firstdayofweek] ) WeekdayName(2)結果:'星期一'

WeekdayName(2, TRUE)結果:'星期一'

WeekdayName(2, TRUE, vbMonday)結果:'星期一'

所以,這是我的最終版本並且完美運行

Public Function IsoWeekNumber(d As Date) As String

    Dim kwtemp As String

    kwtemp = DatePart("ww", d, vbMonday, vbFirstFourDays)

    If Len(kwtemp) = 1 Then kwtemp = "0" & kwtemp

    IsoWeekNumber = kwtemp

End Function

If Application.International(xlMDY) = True Then

HeadlineTemp = Mid(VRHeadline, InStr(VRHeadline, "[") + 1, 10)
HeadlineTemp = Replace(HeadlineTemp, ".", "/")
HeadlineTemp = Mid(HeadlineTemp, 4, 3) & Left(HeadlineTemp, 2) & Right(HeadlineTemp, 5)
VRFirstKW = CDate(HeadlineTemp)
HeadlineTempEndKW = Mid(VRHeadline, InStr(VRHeadline, "]") - 10, 10)
HeadlineTempEndKW = Replace(HeadlineTempEndKW, ".", "/")
HeadlineTempEndKW = Mid(HeadlineTempEndKW, 4, 3) & Left(HeadlineTempEndKW, 2) & Right(HeadlineTempEndKW, 5)
VREndKW = CDate(HeadlineTempEndKW)
VRKW = "KW" & IsoWeekNumber(VRFirstKW) & "-" & IsoWeekNumber(VREndKW) & "/" & Year(VREndKW)

    Else 'don't switch position of the month with days

    HeadlineTemp = Mid(VRHeadline, InStr(VRHeadline, "[") + 1, 10)
    HeadlineTemp = Replace(HeadlineTemp, ".", "/")
    VRFirstKW = CDate(HeadlineTemp)
    HeadlineTempEndKW = Mid(VRHeadline, InStr(VRHeadline, "]") - 10, 10)
    HeadlineTempEndKW = Replace(HeadlineTempEndKW, ".", "/")
    VREndKW = CDate(HeadlineTempEndKW)
    VRKW = "KW" & IsoWeekNumber(VRFirstKW) & "-" & IsoWeekNumber(VREndKW) & "/" & Year(VREndKW)

使用 datepart 和錯誤解決方法計算 ISO 年份:

'Test 2007-12-31 should return W01Y2008

myDate = "2007-12-31"

ISOWeek = DatePart("ww", myDate, vbMonday, vbFirstFourDays)
Week1 = DatePart("ww", myDate, vbMonday, vbFirstFourDays)
Week2 = DatePart("ww", DateAdd("d", 7, myDate), vbMonday, vbFirstFourDays)
ISOYear = DatePart("yyyy", myDate, vbMonday, vbFirstFourDays)
Year1 = DatePart("yyyy", myDate, vbMonday, vbFirstFourDays)
Year2 = DatePart("yyyy", DateAdd("d", 7, myDate), vbMonday, vbFirstFourDays)

If ISOWeek = 53 And DatePart("ww", DateAdd("d", 7, myDate), vbMonday, vbFirstFourDays) = 2 Then
   ISOWeek = 1
End If

if ISOWeek = 1 And DatePart("yyyy", DateAdd("d", 7, myDate), vbMonday, vbFirstFourDays) > ISOYear Then
 ISOYear = ISOYear + 1
End If

MsgBox("W" & ISOWeek & "Y" & ISOYear)

' Result in W01Y2008

Cw = DatePart("ww", d, vbWednesday, vbFirstFullWeek)

ww -> 用於日歷周

d -> 日期變量

vbWednesday -> 一周的開始日期

vbFirstFullWeek -> 年份將從前 7 開始

此替代解決方案假設周數每個星期一增加 1,並在 1 月的第一個星期一重置為 1。

Dim WeekNumber as long
WeekNumber = Int(DateDiff("d", CDate("1/1/" & Year(DateAdd("d", 1 - Weekday(Date, 2), Date))), DateAdd("d", 1 - Weekday(Date, 2), Date)) / 7) + 1

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM