标记该月的前 6 天

Tag the 6 first wording days of the month

我正在尝试找到一种方法来标记该月的前 6 个措辞日(周一至周五)。

例如,对于 11 月,我想要:

Date FlagDate
11/01/2021 True
11/02/2021 True
11/03/2021 True
11/04/2021 True
11/05/2021 True
11/06/2021 False
11/07/2021 False
11/08/2021 True
11/09/2021 False
11/10/2021 False
11/11/2021 False
11/12/2021 False
11/13/2021 False
11/14/2021 False
11/15/2021 False
11/16/2021 False
11/17/2021 False
11/18/2021 False
11/19/2021 False
11/20/2021 False
11/21/2021 False

等等。

您可以使用以下公式使用 DAX 创建自定义列

= CONTAINS(TOPN(6,FILTER('Table',WEEKDAY('Table'[Date],2)<6)),'Table'[Date],'Table'[Date]) 

您可以更新TopN(6以相应地更新第一个工作日的天数

这里是 M 代码,它向您现有的 table 添加一列。

假设您的 table 中的列名称是 Date 它还假定您有一个至少跨越相关时间范围的相关假期日期的 List我从 https://publicholidays.fr 获取了列表并对其进行了缓冲以防止其不断下载

算法见M-Code注释

  • 请注意,不要求日期列包含完整的月份。但是如果它开始于,例如 15 日,那个月将没有任何标记为 TRUE 的东西,因为 first6 不存在。

假设:日期列跨度小于 1 年
如果不是这种情况,将需要不同的算法来创建 first6 列表。

M代码

//Before adding the "Flag" column enter this code to create a buffered list of working days in the months in the Date column
    workingDays = 
        let 
    
    //generate list of all dates from beginning of first month to the last date listed
        dts = List.Transform(
                {Number.From(Date.StartOfMonth(#"Previous Step"[Date]{0}))..
                 Number.From(List.Max(#"Previous Step"[Date]))},each Date.From(_)),

    //Using List.Generate, create a list of working days from the preceding list
    //working days will be days that are Monday-Friday and NOT found in the list of Holiday dates
        wdys = List.Generate(
            ()=>[wd=if Date.DayOfWeek(dts{0})>= Day.Monday 
                        and Date.DayOfWeek(dts{0})<=Day.Friday 
                        and not List.Contains(#"FR Holidays",dts{0}) then dts{0} else null,
                        idx = 0],
            each [idx] < List.Count(dts),
            each [wd=if Date.DayOfWeek(dts{[idx]+1})>= Day.Monday 
                        and Date.DayOfWeek(dts{[idx]+1})<=Day.Friday 
                        and not List.Contains(#"FR Holidays",dts{[idx]+1}) then dts{[idx]+1} else null,
                        idx = [idx]+1],
            each [wd]),

    //clean the wdys List by removing the Nulls
        cleanList = List.RemoveNulls(wdys),

    //create a list of the Months within the workday list
        monthsInList= List.Distinct(List.Transform(cleanList, each Date.Month(_))),

    //Use List.Accumulate to create lists of the first 6 working days in each month
        first6 = List.Accumulate(monthsInList,{}, 
            (state, current)=> state & 
                List.FirstN(List.Select(cleanList,each Date.Month(_)=current),6))
        in List.Buffer(first6),

//Now add a column and set the flag if a Date in the date column is found in the first6 list
    flagged = Table.AddColumn(#"Previous Step","FlagDate", each List.Contains(workingDays,[Date]), type logical)
in
    flagged

过滤后仅显示标记为 True

的日期

M 代码已编辑以处理超过一年的跨度
更改 MonthsInList 以包含年份,并在 List.Accumulate 步骤中测试该年份

//Before adding the "Flag" column enter this code to create a buffered list of working days in the months in the Date column
    workingDays = 
        let 
    
    //generate list of all dates from beginning of first month to the last date listed
        dts = List.Transform(
                {Number.From(Date.StartOfMonth(#"Previous Step"[Date]{0}))..
                 Number.From(List.Max(#"Previous Step"[Date]))},each Date.From(_)),

    //Using List.Generate, create a list of working days from the preceding list
    //working days will be days that are Monday-Friday and NOT found in the list of Holiday dates
        wdys = List.Generate(
            ()=>[wd=if Date.DayOfWeek(dts{0})>= Day.Monday 
                        and Date.DayOfWeek(dts{0})<=Day.Friday 
                        and not List.Contains(#"FR Holidays",dts{0}) then dts{0} else null,
                        idx = 0],
            each [idx] < List.Count(dts),
            each [wd=if Date.DayOfWeek(dts{[idx]+1})>= Day.Monday 
                        and Date.DayOfWeek(dts{[idx]+1})<=Day.Friday 
                        and not List.Contains(#"FR Holidays",dts{[idx]+1}) then dts{[idx]+1} else null,
                        idx = [idx]+1],
            each [wd]),

    //clean the wdys List by removing the Nulls
        cleanList = List.RemoveNulls(wdys),

    //create a list of the Months within the workday list
        monthsInList= List.Distinct(List.Transform(cleanList, each Date.ToText(_,"yyyy-MM"))),

    //Use List.Accumulate to create lists of the first 6 working days in each month
        first6 = List.Accumulate(monthsInList,{}, 
            (state, current)=> state & 
                List.FirstN(List.Select(cleanList,each Date.ToText(_,"yyyy-MM")=current),6))
        in List.Buffer(first6),

//Now add a column and set the flag if a Date in the date column is found in the first6 list
    flagged = Table.AddColumn(#"Previous Step","FlagDate", each List.Contains(workingDays,[Date]), type logical)
in
    flagged