乐于分享
好东西不私藏

EXCEL|List函数的案例分享-求重复出差天数

EXCEL|List函数的案例分享-求重复出差天数
这个案例中涉及的List类函数如下:
M函数
语法
用途
List.Combine()
List.Combine(列表)
将多个列表合并成新的列表
List.Distinct()
List.Distinct(列表)
删除列表的重复项,返回新的列表
List.Difference()
List.Difference(列表1,列表2)
获取列表1中独有的项,返回新的列表
List.Count()
List.Count(列表)
获取并返回列表中成员计数
案例描述如下:根据下表内容,我们需要找出存在重复出差天数的员工并统计重复出差天数。
员工
出差开始时间
出差结束时间
小力
2016/10/13
2016/10/15
天天
2016/5/27
2016/5/27
天天
2016/5/31
2016/5/31
天天
2016/9/16
2016/9/17
天天
2016/10/13
2016/10/15
天天
2016/10/19
2016/10/25
天天
2016/10/20
2016/10/31
天天
2016/10/22
2016/10/23
苏苏
2016/5/31
2016/5/31
小白
2016/10/11
2016/10/15
小白
2016/10/12
2016/10/12
小白
2016/10/19
2016/10/19
小白
2016/11/14
2016/11/17
果果
2016/10/13
2016/10/15
果果
2016/10/19
2016/10/19
整体的解题思路是将每个人的所有出差日期值都列举出来,然后按照员工为分组依据从员工的维度将所有出差日期值都包含在一列里,然后去重,然后再用原出差日期值跟去重后的出差日期值进行匹配,差值就是重复出差日。以下为操作步骤:
1. 将上述表格导入到查询编辑器,然后插入自定义列,使用公式={Number.From([出差开始时间])..Number.From([出差结束时间])},将每段出差日期之间的日期值都列出来。如下图所示。
Number.From()是常用的类型转换函数,用于将文本或者日期时间类数据转换成可以参与运算的数值。比如文本类型的"123"不能参与运算,因此需要使用M函数将其转换成数值才能参与运算。M代码为:Number.From("123").Excel内部是用数字来存储日期的1900年1月1日对应的数字是1,其他日期一次递增,使用Number.From()函数可以返回日期对应的数字。常用的类型转换函数如下图所示。
2. 结果如下图所示。生成的自定义列是包含表的列,列表中包含的是出差日期对应的数值。在第一个列表中,42656~42658代表从2016年10月13日到2016年10月15日这3天。
3. 按员工分组对出差记录进行合并,将同一个员工所有的出差日期值记录合并到一个列表中。这一步需要特别注意下。正常,这步会用到分组依据。如果用分组依据,出现的函数和结果是下面这个。
4. 我们需要在这里手动改下公式,用List.Combine()函数。在公式栏里将公式改成如下M代码:

= Table.Group(已添加自定义, {"员工"}, {{"全部出差日期", each List.Combine(_[出差日期记录])}})

5. 此时每个员工的所有出差日期值都合并到同一个列表中,也就是说如果有重复的日期值,那么该日期值就会在列表中出现多次。如下图所示。

6. 接下来,我们将这个列表里面的重复值去掉再与原列表相减,那么可得到重复的出差日期值。我们自定义新列,用List.Distinct()函数对列表去重,如下图所示。

=List.Distinct([全部出差日期])

7. 全部出差日期列包含所有的出差日期值,而出差日期_去重列中的日期值仅保留了不重复的出差日期值。只要将两个列表相减就能得到重复的出差日期值。我们添加自定义列,然后用List.Difference()函数返回两个列表的差。如下图所示。

=List.Difference([全部出差日期],[出差日期_去重])

8. 最后用List.Count()函数计算重复出差天数。如下图所示。

9. 结果如下图所示。最后得到的结果是天天重复出差8天,小白重复出差1天。

今天的案例是通过4个List类函数一步步计算出来的,如果对M函数足够熟悉,也可以通过嵌套函数来实现。

好了,今天内容就这样。