简体   繁体   English

VBA 将日期转换为周数

[英]VBA Convert date to week number

In VBA I want to convert a date as 03/11/2017(DD/MM/YYYY) into the week number for that date.在 VBA 中,我想将日期 03/11/2017(DD/MM/YYYY) 转换为该日期的周数。

Until now I have the following code:到目前为止,我有以下代码:

   '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)

Now, I need a function to convert that date into the week number of the year.现在,我需要一个 function 来将该日期转换为一年中的周数。 First week day is Monday.第一个工作日是星期一。

要将星期一作为第一天的周数,请使用以下内容:

WorksheetFunction.WeekNum(now, vbMonday)

Using VBA, to convert a date into an isoWeeknumber, you merely need the DatePart function (where DT is the date of interest):使用 VBA,要将日期转换为 isoWeeknumber,您只需要DatePart函数(其中 DT 是感兴趣的日期):

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

If you want to use other definitions than that specified in ISO 8601, investigate some of the other options for FirstDayOfWeek and FirstWeekOfYear如果您想使用 ISO 8601 中指定的定义以外的其他定义,请研究FirstDayOfWeekFirstWeekOfYear的其他一些选项

NOTE笔记

As pointed out by @Mike85, there is a bug in DatePart (and also in the Format ) function wherein Monday may be erroneously given a weeknumber of 53 when it should be 1.正如@Mike85 所指出的那样, DatePart (以及Format )函数中存在一个错误,其中 Monday 可能被错误地赋予周数 53,而它应该是 1。

There are a variety of workarounds.有多种解决方法。

In Excel 2013+ (Excel for Mac 2011+) you can use for the ISO Weeknumber:在 Excel 2013+(Excel for Mac 2011+)中,您可以使用 ISO Weeknumber:

isoWeekNumber = WorksheetFunction.isoWeekNum(dt)

For earlier versions, you can test the Monday and adjust it if necessary, or you can write a separate routine.对于较早的版本,您可以测试星期一并在必要时进行调整,或者您可以编写单独的例程。

Be carefull when it comes to week numbers as there are different definitions around.当涉及到周数时要小心,因为周围有不同的定义。 The Excel definition differs from the ISO definition. Excel 定义不同于 ISO 定义。 To get the ISO weeknumber use (copied From http://www.rondebruin.nl/win/s8/win001.htm )获取 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) Result: 'Monday' WeekdayName( number, [abbreviate], [firstdayofweek] ) WeekdayName(2)结果:'星期一'

WeekdayName(2, TRUE) Result: 'Mon' WeekdayName(2, TRUE)结果:'星期一'

WeekdayName(2, TRUE, vbMonday) Result: 'Mon' WeekdayName(2, TRUE, vbMonday)结果:'星期一'

So, this is my final and working perfectly version所以,这是我的最终版本并且完美运行

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)

Calculate ISO year using datepart with bugs workaround:使用 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) Cw = DatePart("ww", d, vbWednesday, vbFirstFullWeek)

ww -> for Calendar Week ww -> 用于日历周

d -> date variable d -> 日期变量

vbWednesday -> Starting day of week vbWednesday -> 一周的开始日期

vbFirstFullWeek -> year will be started from first 7 vbFirstFullWeek -> 年份将从前 7 开始

This alternate solution assumes the week number increases by 1 each Monday, and resets to 1 on the first Monday in January.此替代解决方案假设周数每个星期一增加 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