简体   繁体   English

如何滚动 WeekNum 如果年份不是在特定的工作日(如星期五)开始

[英]How to rollover WeekNum If year does not start on a specific weekday (Like Friday)

I am currently working on a excel macro which generates Weekly data.我目前正在研究一个生成每周数据的 excel 宏。 I have to prepare multiple reports where my Week starting day is different eg if for one report my week start day is "Friday" whereas for other report the week start day is "Monday"我必须准备多份报告,其中我的周开始日是不同的,例如,如果一份报告我的周开始日是“星期五”,而其他报告的一周开始日是“星期一”

Right now, I am doing this in multiple steps:现在,我分多个步骤执行此操作:

  1. First I am getting all data from source excel and adding a formula to get all records in a particular week.首先,我从源 excel 获取所有数据并添加一个公式来获取特定周内的所有记录。 I have considered "Friday" as my first day of week.我已将“星期五”视为我一周的第一天。

  2. I arranged the records in descending order and get the unique value for each AZ column.我按降序排列记录并获得每个 AZ 列的唯一值。 This way I got the last record from each week, which is what I was looking.通过这种方式,我获得了每周的最后一张唱片,这正是我想要的。

Code I am using for this is as follows:我为此使用的代码如下:

    Range("Data").AdvancedFilter _
    Action:=xlFilterCopy, _
    CriteriaRange:=Range("$A$1:$A$2"), _
    CopyToRange:=Range("$BB$4:$BD$4")

    FilterDataLastRow = Cells.Find(What:="*", _
    After:=Range("BA999999"), _
    LookAt:=xlPart, _
    LookIn:=xlFormulas, _
    SearchOrder:=xlByRows, _
    SearchDirection:=xlPrevious, _
    MatchCase:=False).Row

    ' Sort data in descending order of date
     ' Range("WeeklyFilteredData").Sort Key1:=Range("$BB$4:$BB$999999"), Order1:=xlDescending, Header:=xlYes
       Range("AW4:BE999999").Sort Key1:=Range("BC4:BC999999"), order1:=xlDescending, Header:=xlYes

    ' Assign Unique Key for each record row. We are using RowNum for same
        Range("BA5:BA" & FilterDataLastRow).Formula = "=ROW(RC[-2])"

    ' Assign SearchKey to filter Out all the data belonging to same week
        Range("AZ5:AZ" & FilterDataLastRow).Formula = "=(TEXT(RC[3],""yyyy""))&(TEXT(WEEKNUM(RC[3],15),""00""))"

    ' Get all data in User View
         Range("A5:A" & FilterDataLastRow).Formula = "=VLOOKUP(RC[51],C[51]:C[55],2,FALSE)"
         Range("B5:B" & FilterDataLastRow).Formula = "=VLOOKUP(RC[50],C[50]:C[54],3,FALSE)"
         Range("C5:C" & FilterDataLastRow).Formula = "=VLOOKUP(RC[49],C[49]:C[53],4,FALSE)"
         Range("E5:E" & FilterDataLastRow).Formula = "=VLOOKUP(RC[47],C[47]:C[51],5,FALSE)"

         Cells.RemoveDuplicates Columns:=Array(1)

在此处输入图片说明

This was working perfectly fine till WEEKNUM 53. January 2020 started on Wednesday and this was considered a WEEKNUM "1" which is not correct for my report.在 WEEKNUM 53 之前,这一直运行良好。2020 年 1 月从星期三开始,这被认为是 WEEKNUM “1”,这对我的报告不正确。

Currently I am getting my Output as shown below:目前我得到我的输出如下所示:

这是我当前数据的样子

I need to modify my Code to skip data for 12/31/2019 (Highlighted in red) as this data will be calculated as part of week which is ending on 01/02/2020.我需要修改我的代码以跳过 2019 年 12 月 31 日的数据(以红色突出显示),因为此数据将作为 2020 年 1 月 2 日结束的一周的一部分进行计算。

Please suggest a better way to update my code to enter code here请建议一种更好的方法来更新我的代码以enter code here

[Update: 07 January 2020] ANSWER [更新:2020 年 1 月 7 日]答案

I figured out a way to achieve my end result.我想出了一种方法来实现我的最终结果。 But I know there is still better way to do same thing and hence I am keeping this question open for better approach.但我知道还有更好的方法来做同样的事情,因此我保持这个问题开放以寻求更好的方法。

Here is what I did: 1. Retrieve MONTH, DAY and WEEKDAY from given date这是我所做的: 1. 从给定日期检索 MONTH、DAY 和 WEEKDAY

Range("AW5:AW" & FilterDataLastRow).Formula = "=MONTH(RC[6])"
Range("AX5:AX" & FilterDataLastRow).Formula = "=DAY(RC[5])"
Range("AY5:AY" & FilterDataLastRow).Formula = "=WEEKDAY(RC[4],16)"
  1. Now added a for loop.现在添加了一个 for 循环。 I tried to explain each of my step in comments inside code.我试图在代码中的注释中解释我的每一步。

     For i = 5 To FilterDataLastRow ' Check for records with Month = 1 And DAY is 1-6 and WEEKDAY < 6 If Range("AW" & i).Value = 1 And Range("AX" & i).Value < 7 Then CurrYear = Year(Range("BC" & i).Value) PrevYear = CurrYear - 1 PrevYearLastDay = "12/31/" & PrevYear Range("AV" & i).Value = PrevYearLastDay 'Get the Day of Weel on 31st December of Previous Year Range("AU" & i).Value = "=WEEKDAY(RC[1],16)" 'Calculate Number of Days remaining for new week to start DaysRemForNewWeek = 8 - Range("AU" & i).Value 'Calculate Date of First Friday of Current Year Range("AT" & i).Value = PrevYearLastDay + DaysRemForNewWeek 'Compare all the dates prior to first Friday and rollover WeekNum from last year for these dates If Range("BC" & i).Value < Range("AT" & i).Value Then Range("AZ" & i).Formula = "=(TEXT(RC[-4],""yyyy""))&(TEXT(WEEKNUM(RC[-4],16),""00""))" Else Range("AZ" & i).Formula = "=(TEXT(RC[3],""yyyy""))&(TEXT(WEEKNUM(RC[3],16),""00""))" End If Else Range("AZ" & i).Formula = "=(TEXT(RC[3],""yyyy""))&(TEXT(WEEKNUM(RC[3],16),""00""))" End If Next i

What is your definition of a Week given a particular start day?给定特定的开始日,您对一周的定义是什么?

If it is the first full week of the year starting with that date, then you can derive it more easily from the VBA DatePart function, eg如果它是从该日期开始的一年中的第一个完整周,那么您可以更轻松地从 VBA DatePart函数中导出它,例如

DatePart("ww", myDate, vbFriday, vbFirstFullWeek)

If you need to have this as a function or part of a formula on your worksheet, use it as a UDF instead of the worksheet WEEEKNUM function which is not as flexible.如果您需要将此作为工作表上的一个函数或公式的一部分,请将其用作 UDF 而不是工作表WEEEKNUM函数,后者不够灵活。 Or, better yet, construct the year/wknum string in VBA using the vba Format function and write that string to the worksheet.或者,更好的是,使用 vba Format函数在 VBA 中构造year/wknum字符串并将该字符串写入工作表。

For example:例如:

Function yrWkNum(dt As Date) As String
    yrWkNum = Year(dt) & Format(DatePart("ww", dt, vbFriday, vbFirstFullWeek), "00")
End Function

在此处输入图片说明

I figured out a way to achieve my end result.我想出了一种方法来实现我的最终结果。 But I know there is still better way to do same thing and hence I am keeping this question open for better approach.但我知道还有更好的方法来做同样的事情,因此我保持这个问题开放以寻求更好的方法。

Here is what I did: 1. Retrieve MONTH, DAY and WEEKDAY from given date这是我所做的: 1. 从给定日期检索 MONTH、DAY 和 WEEKDAY

Range("AW5:AW" & FilterDataLastRow).Formula = "=MONTH(RC[6])"
Range("AX5:AX" & FilterDataLastRow).Formula = "=DAY(RC[5])"
Range("AY5:AY" & FilterDataLastRow).Formula = "=WEEKDAY(RC[4],16)"
  1. Now added a for loop.现在添加了一个 for 循环。 I tried to explain each of my step in comments inside code.我试图在代码中的注释中解释我的每一步。

     For i = 5 To FilterDataLastRow ' Check for records with Month = 1 And DAY is 1-6 and WEEKDAY < 6 If Range("AW" & i).Value = 1 And Range("AX" & i).Value < 7 Then CurrYear = Year(Range("BC" & i).Value) PrevYear = CurrYear - 1 PrevYearLastDay = "12/31/" & PrevYear Range("AV" & i).Value = PrevYearLastDay 'Get the Day of Weel on 31st December of Previous Year Range("AU" & i).Value = "=WEEKDAY(RC[1],16)" 'Calculate Number of Days remaining for new week to start DaysRemForNewWeek = 8 - Range("AU" & i).Value 'Calculate Date of First Friday of Current Year Range("AT" & i).Value = PrevYearLastDay + DaysRemForNewWeek 'Compare all the dates prior to first Friday and rollover WeekNum from last year for these dates If Range("BC" & i).Value < Range("AT" & i).Value Then Range("AZ" & i).Formula = "=(TEXT(RC[-4],""yyyy""))&(TEXT(WEEKNUM(RC[-4],16),""00""))" Else Range("AZ" & i).Formula = "=(TEXT(RC[3],""yyyy""))&(TEXT(WEEKNUM(RC[3],16),""00""))" End If Else Range("AZ" & i).Formula = "=(TEXT(RC[3],""yyyy""))&(TEXT(WEEKNUM(RC[3],16),""00""))" End If Next i

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM