【问题标题】:How to get correct week number in Access如何在 Access 中获取正确的周数
【发布时间】:2016-10-01 00:01:14
【问题描述】:

我每周都会收到一个大型数据集,其中包含开始日期和结束日期,开始日期始终为星期一,结束日期始终为星期日。我希望能够按周对不同产品的销售额进行滚动 YTD。我试图给每周的数据一个周数。但是我的第一周是 12/28/2015-1/3/2016,它一直给我第 53 周而不是第 1 周。我看到另一个人在同一问题上的帖子,dbDesigner 的回答确实有效:

Get the week number from a given date

但这在一个专栏中给了我 2016-01。我想要两列,一列用于正确的周数,另一列用于正确的年份,以便能够对我的滚动 YTD 销售进行子查询。例如,对于我的第一周 12/28/2015-1/3/2016,它将是周:1 和年:2016

谢谢。

【问题讨论】:

  • 你理解你所指的解决方案吗?因为如果你这样做,你应该注意到年份和星期是连接的。所以你应该撤消连接。
  • 好吧,谢谢你的叫醒。我把它们分开了,它们都起作用了。

标签: ms-access


【解决方案1】:

首先,VBA 中没有周编号方法遵循 ISO 8601 标准。

第二,2015-12-28 到 2016-01-03 的周数不是 2106 的第一个,而是 2015W53。

您可以使用以下函数检索任何日期的正确 ISO 8601 周数:

Public Function ISO_WeekYearNumber( _
  ByVal datDate As Date, _
  Optional ByRef intYear As Integer, _
  Optional ByRef bytWeek As Byte) _
  As String

' Calculates and returns year and week number for date datDate according to the ISO 8601:1988 standard.
' Optionally returns numeric year and week.
' 1998-2007, Gustav Brock, Cactus Data ApS, CPH.    Public Function ISO_WeekNumber( _
  ByVal datDate As Date) _
  As Byte

' Calculates and returns week number for date datDate according to the ISO 8601:1988 standard.
' 1998-2000, Gustav Brock, Cactus Data ApS, CPH.
' May be freely used and distributed.

  Const cbytFirstWeekOfAnyYear  As Byte = 1
  Const cbytLastWeekOfLeapYear  As Byte = 53

  Dim bytWeek                   As Byte
  Dim bytISOThursday            As Byte
  Dim datLastDayOfYear          As Date

  bytWeek = DatePart("ww", datDate, vbMonday, vbFirstFourDays)

  If bytWeek = cbytLastWeekOfLeapYear Then
    bytISOThursday = Weekday(vbThursday, vbMonday)
    datLastDayOfYear = DateSerial(Year(datDate), 12, 31)
    If Weekday(datLastDayOfYear, vbMonday) >= bytISOThursday Then
      ' OK, week count of 53 is caused by leap year.
    Else
      ' Correct for Access97/2000 bug.
      bytWeek = cbytFirstWeekOfAnyYear
    End If
  End If

  ISO_WeekNumber = bytWeek

End Function
' May be freely used and distributed.

  Const cbytFirstWeekOfAnyYear  As Byte = 1
  Const cbytLastWeekOfLeapYear  As Byte = 53
  Const cbytMonthJanuary        As Byte = 1
  Const cbytMonthDecember       As Byte = 12
  Const cstrSeparatorYearWeek   As String = "W"

  Dim bytMonth                  As Byte
  Dim bytISOThursday            As Byte
  Dim datLastDayOfYear          As Date

  intYear = Year(datDate)
  bytMonth = Month(datDate)
  bytWeek = DatePart("ww", datDate, vbMonday, vbFirstFourDays)

  If bytWeek = cbytLastWeekOfLeapYear Then
    bytISOThursday = Weekday(vbThursday, vbMonday)
    datLastDayOfYear = DateSerial(intYear, cbytMonthDecember, 31)
    If Weekday(datLastDayOfYear, vbMonday) >= bytISOThursday Then
      ' OK, week count of 53 is caused by leap year.
    Else
      ' Correct for Access97/2000+ bug.
      bytWeek = cbytFirstWeekOfAnyYear
    End If
  End If

  ' Adjust year where week number belongs to next or previous year.
  If bytMonth = cbytMonthJanuary Then
    If bytWeek >= cbytLastWeekOfLeapYear - 1 Then
      ' This is an early date of January belonging to the last week of the previous year.
      intYear = intYear - 1
    End If
  ElseIf bytMonth = cbytMonthDecember Then
    If bytWeek = cbytFirstWeekOfAnyYear Then
      ' This is a late date of December belonging to the first week of the next year.
      intYear = intYear + 1
    End If
  End If

  ISO_WeekYearNumber = CStr(intYear) & cstrSeparatorYearWeek & Format(bytWeek, "00")

End Function

如果你只需要周数本身,可以使用这样的函数:

【讨论】:

  • 谢谢,但我使用了旧帖子,现在可以正常工作了。我可以得到正确的周数和年数。
【解决方案2】:

您了解您所指的解决方案吗? 因为如果你这样做,你应该注意到年份和星期是连接的。 所以你应该撤消连接。

【讨论】:

    猜你喜欢
    • 2021-04-11
    • 1970-01-01
    • 2012-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-03
    • 1970-01-01
    相关资源
    最近更新 更多