问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

计算除周末和节假日的两个日期之间的工作日

创作时间:
作者:
@小白创作中心

计算除周末和节假日的两个日期之间的工作日

引用
1
来源
1.
https://community.fabric.microsoft.com/t5/Power-BI-%E4%B8%AD%E6%96%87%E5%8D%9A%E5%AE%A2/%E8%AE%A1%E7%AE%97%E9%99%A4%E5%91%A8%E6%9C%AB%E5%92%8C%E8%8A%82%E5%81%87%E6%97%A5%E7%9A%84%E4%B8%A4%E4%B8%AA%E6%97%A5%E6%9C%9F%E4%B9%8B%E9%97%B4%E7%9A%84%E5%B7%A5%E4%BD%9C%E6%97%A5/ba-p/4108028

在许多情况下,您可能需要计算两个日期之间的工作日。本文将告诉您如何计算出确切的工作日天数(即不包括周末和节假日)。

示例数据

事实表:

节假日表:

解决方案一:使用DAX

在过去,当我们遇到此类问题时,通常需要创建一个日期连续的日历表,这有助于我们根据日期表过滤和计算预期数据。

不过,2022年7月Power BI的功能摘要里提到的一项新的DAX功能使我们不需要再创建这样一个连续的日历表,而是可以直接调用函数 “NETWORKDAYS”来计算工作日。

NETWORKDAYS 用于返回(含)两个日期之间的工作日整数。

语法:

NETWORKDAYS(<开始日期>, <结束日期>[, <周末>, <节假日>])

与 DATEDIFF 功能不同的是,你可以编辑参数来指定哪些天和多少天是周末。你还可以将列表中的日期指定为不被视为工作日的节假日。

必须使用函数 DATE 或其他表达式的结果来指定日期。如果开始日期和结束日期都是空的,那么输出值也是空的。

如果开始日期或结束日期为空,则空的开始日期或结束日期将被视为 Date (1899, 12, 30)。

样例:

除周末外的工作日 = NETWORKDAYS ('事实表(DAX)'[开始日期],'事实表(DAX)'[结束日期],1)
除周末和节假日外的工作日 = NETWORKDAYS ('事实表(DAX)'[开始日期],'事实表(DAX)'[结束日期],1,VALUES('节假日'[日期]))

解决方案二:使用Power Query

目前M 语法中没有类似于 “NETWORKDAYS ”的函数可以直接使用。不过,我们可以构建一个自定义函数来实现类似的目标。

详细步骤

  1. 复制“节假日”表并将其转换为日期列表。
  2. 新建空白查询,并在 “高级编辑器 ”中粘贴以下代码,创建函数 “除周末外的工作日 ”和函数 “除周末和节假日外的工作日”。

除周末外的工作日:

(开始日期 as date,结束日期 as date) as number=> 
let 
    日期列表=List.Dates(开始日期,Number.From(结束日期-开始日期)+1,#duration(1,0,0,0)), 
    //创建日期系列 
    移除周末=List.Select(日期列表,each Date.DayOfWeek(_,Day.Monday)<5), 
    //移除周末 
    统计天数=List.Count(移除周末) 
    //统计天数 
in 
  统计天数   

除周末和节假日外的工作日:

(开始日期 as date, 结束日期 as date, 节假日列表 as list) as number=> 
let 
    日期列表=List.Dates(开始日期,Number.From(结束日期-开始日期)+1,#duration(1,0,0,0)), 
    //创建日期系列 
    移除周末=List.Select(日期列表,each Date.DayOfWeek(_,Day.Monday)<5), 
    //移除周末 
    移除节假日=List.RemoveItems(移除周末, 节假日列表), 
    //移除节假日 
    统计天数=List.Count(移除节假日) 
    //统计天数 
in 
  统计天数   

List.Dates : 返回指定大小的日期值列表。
Number.From: 从给定值返回值。这里我们用它来获取开始日期和结束日期之间的时间间隔,这对于生成日期列表非常方便。
Date.DayOfWeek:返回一个数字(从 0 到 6): 返回一个数字(从 0 到 6),表示所提供日期时间的星期几。在这里,我们用它来确定是否是工作日(不包括周末)。
List.Select : 从符合选择条件的列表中返回一个值列表。这里我们使用它来提取给定日期列表中的所有工作日(不包括周末)。
List.RemoveItems :从 list1 中移除 list2 中所有给定值。在此,我们将从指定列表中删除 “节假日列表”中的所有值。
List.Count :列表计数,返回列表中的项目数。

  1. 创建两个自定义列,调用函数 “除周末外的工作日”和函数 “除周末和节假日外的工作日”。

完整的应用代码如下:

let 
    源 = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("Vc/BCcAwCAXQXTxHiFbbZpbg/mvUlJJ+wcvnKeqcpF2Vu2RR+4NRNDBF82oH2lnN0C4wY/FtvhagwVw23mAD7xys1TJ+Jr38sOLeJ++zEQ8=", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [开始日期 = _t, 结束日期 = _t]), 
    更改的类型 = Table.TransformColumnTypes(源,{{"开始日期", type date}, {"结束日期", type date}}), 
    已添加自定义 = Table.AddColumn(更改的类型, "总天数", each Duration.Days([结束日期]-[开始日期])+1), 
    已添加自定义1 = Table.AddColumn(已添加自定义, "除周末外的工作日", each 除周末外的工作日([开始日期],[结束日期])), 
    已添加自定义2 = Table.AddColumn(已添加自定义1, "除周末和节假日外的工作日", each 除周末和节假日外的工作日([开始日期],[结束日期],节假日列表)) 
in 
    已添加自定义2   

希望本文能帮助你解决类似问题。

本文原文来自微软官方社区

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号