将 x 个工作日添加到自定义列中的日期

Add x number of working days to a date in a custom column

我正在尝试在 Power Query 中添加一个自定义列,如果满足条件则添加 3 个 个工作日 ,否则添加 2 个工作日。

我可以让它有条件地添加天数而不会出现问题,但我在添加工作日时遇到了问题。我知道这很容易在 excel 中使用 =IF X = 1,WORKDAY([REFERENCE],3),WORKDAY([REFERENCE],2) 完成,但我如何才能在查询编辑器中执行与自定义列相同的操作?

以下是我所拥有的,包括周末在内的几天:

=if [REF]="1" then Date.AddDays([ETA],3) else Date.AddDays([ETA],2)

一个解决方案是将其分解为两个部分:

  1. 根据您的初始情况,增加 2 或 3 天
  2. 如果这在周六或周日结束,则增加 2 天以跳过周末

您已经执行了第 1 步。

您现在只需执行第 2 步,即根据需要添加额外的 2 天。您可以使用 DayOfWeek 函数来确定您从哪里开始,以确定您是否需要额外的 2 天:

如果您要添加 3 个工作日,那么如果初始日期是周三、周四或周五,您将需要再添加 2 天:

if Date.DayOfWeek([ETA], Day.Wednesday) <= 2 then {Add 2 more days}

如果您要添加 2 个工作日,那么如果初始日期是周四或周五,您将需要再添加 2 天:

if Date.DayOfWeek([ETA], Day.Thursday) <= 1 then {Add 2 more days}

您可以将这些合并到您的初始声明中。

我写了一个自定义函数来解决这个问题,除非你也需要考虑假期。它有点通用,它适用于 2 或 200 或 2000 天。等于 Excel.

中的 =WORKDAY(date;days) 函数

更新:Bibake Uppal 建议应该支持减法。添加了负数 days.

的减法

这里是:

(startDate, days) =>
    let
        Sign = if days < 0 then -1 else 1, //add a multiplier to enable negative 'days' to be subtracted rather than added
        Step1 = List.Dates(Date.AddDays(startDate, Sign), Sign*days + Number.RoundUp(Sign*days/7*3+4,0), #duration(Sign,0,0,0)), //provision list of added days with 3 more days per each added week, starting from startDate + 1 day; This is a bit over-provisioning, but ensures the list is long enough.
        Step2 = List.Select(Step1, (item) => Date.DayOfWeek(item, Day.Monday) < 5), // select only workdays
        Step3 = List.FirstN(Step2, Sign*days), //select required number of workdays
        Output = if days = 0 then startDate else List.Last(Step3)
    in
        Output

您可以将其保存为查询,将其命名为 AddWorkdays,然后按如下方式使用:

YourStepName = Table.AddColumn(yourTable, "CustomColumnName", 
                    each AddWorkdays([ETA], if [REF]="1" then 3 else 2) 
                   //note that [REF]="1" filters a text value, not number!

否则,您可以将此函数插入​​您的代码中,如

fnAddWorkdays = (startDate, days) =>
let
    Sign = if days < 0 then -1 else 1, //add a multiplier to enable negative 'days' to be subtracted rather than added
    Step1 = List.Dates(Date.AddDays(startDate, Sign), Sign*days +  Number.RoundUp(Sign*days/7*3+4,0), #duration(Sign,0,0,0)), //provision list of added days with 3 more days per each added week, starting from startDate + 1 day; This is a bit over-provisioning, but ensures the list is long enough.
    Step2 = List.Select(Step1, (item) => Date.DayOfWeek(item, Day.Monday) < 5), // select only workdays
    Step3 = List.FirstN(Step2, Sign*days), //select required number of workdays
    Output = if days = 0 then startDate else List.Last(Step3)
in
    Output

Eugene 的响应略有改进,也允许减少工作日。

= (startDate, days) =>
let
    Step1 = if days >= 0 then List.Dates(Date.AddDays(startDate, 1), days + Number.RoundUp(days/7*3+4,0), #duration(1,0,0,0)) 
            else List.Dates(Date.AddDays(startDate, -1), -days + Number.RoundUp(-days/7*3+4,0), #duration(-1,0,0,0)), //provision list of added days with 3 more days per each added week, starting from startDate + 1 day
    Step2 = List.Select(Step1, (item) => Date.DayOfWeek(item, Day.Monday) < 5), // select only workdays
    Step3 = List.FirstN(Step2, Number.Abs(days)), //select required number of workdays
    Output = List.Last(Step3)
in
    Output

只需为 days 输入负值。