[英]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 中指定的定义以外的其他定义,请研究FirstDayOfWeek
和FirstWeekOfYear
的其他一些选项
笔记
正如@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.