题1:
如图,将左表的日期范围,展开为连续的日期。
在此之前,我们已经介绍过不少数字类型的展开问题,比如"1-99"展开,我们只需要先将首尾拆分,然后构建list展开即可。
{Number.From(Text.BeforeDelimiter([范围],"-"))..Number.From(Text.AfterDelimiter([范围],"-"))}
逻辑很简单,但是涉及到一些数据类型的转换,一定要细心。
再回来看这个问题,把日期展开,但是日期格式并不能直接构建list,比如{#date(2017,7,1)..#date(2017,7,15)},这个是错误的。
我们知道在excel中,日期即为数字,在Power Query中两者虽然不能直接运算,但也是可以通过函数转换数据类型的。
于是就先要拆分文本,然后把文本转成日期,再把日期转为数字,用数字构建list,最后再把数字还原为日期。
let 源 = Excel.CurrentWorkbook(){[Name="表2"]}[Content], 日期 = Table.AddColumn(源, "日期", each List.Transform({Number.From(Date.From(Text.BeforeDelimiter([日期范围],"-")))..Number.From(Date.From(Text.AfterDelimiter([日期范围],"-")))},Date.From)), 展开 = Table.ExpandListColumn(日期, "日期") in 展开
题2:
上面是热身,来加大难度。
这回不仅包含日期,还包含时间,而我们知道带时间的日期转为数字后是小数,但是小数又不能构建list,比如{1.5..99},这也是不行的。
但是看下我们要的结果,[开始时间]除了每一个[人员]的第一行是小数,其余的都是整数。[结束时间]除了最后一行是小数,其余的虽然不是整数但是可以通过整数转换为时间后减1秒得到。
所以我们就通过向上向下舍入取整,先去掉首尾,构建整数的list,然后用&连接单独的首尾,得到最终的list。
let 源 = Excel.CurrentWorkbook(){[Name="表1"]}[Content], 类型 = Table.TransformColumnTypes(源,{{"人员", type text}, {"开始时间", type datetime}, {"结束时间", type datetime}}), 构建 = Table.AddColumn(类型, "a", each [a={Number.RoundUp(Number.From([开始时间]))..Number.RoundDown(Number.From([结束时间]))},b=List.Transform(List.Zip({{[开始时间=[开始时间]]}&List.Transform(a,each [开始时间=DateTime.From(_)]),List.Transform(a,each [结束时间=DateTime.From(_)-#duration(0,0,0,1)])&{[结束时间=[结束时间]]}}),Record.Combine)][b]), 删除列 = Table.RemoveColumns(构建,{"开始时间", "结束时间"}), 展开list = Table.ExpandListColumn(删除列, "a"), 展开record = Table.ExpandRecordColumn(展开list, "a", {"开始时间", "结束时间"}) in 展开record
此方法重点在于第三步构建嵌套record的list,其余步骤都是鼠标点点就出来的。当然你也可以分两步走,分别添加两列来构建list。方法不唯一,看你能不能写出更加优化的解法?
题2现在再看一遍 还是看晕了
那就再来一遍~
日期时间的展开,取得数据后转为数值,乘24×60,取整,构建数列,再除24×60 再转为日期时间,是否可行
题目2看的我脑壳晕乎乎的,似懂非懂的。
题2直接将日期格式改成短日期不行吗
看错了,是时间连续
有用,感谢
let
源 = Excel.CurrentWorkbook(){[Name="表1"]}[Content],
已添加自定义 = Table.AddColumn(源, "aa", each Table.FromColumns({ List.Transform({Number.IntegerDivide(Number.From([开始时间]),1)..Number.IntegerDivide(Number.From([结束时间]),1)},
(x)=>List.Max({[开始时间],DateTime.From(x)})),
List.Transform({Number.IntegerDivide(Number.From([开始时间]),1)+1..Number.IntegerDivide(Number.From([结束时间]),1)+1},
(x)=> List.Min({[结束时间],DateTime.From(x-0.00001)}))}
,{"开始时间","结束时间"})),
删除的列 = Table.RemoveColumns(已添加自定义,{"开始时间", "结束时间"}),
#"展开的“aa”" = Table.ExpandTableColumn(删除的列, "aa", {"开始时间", "结束时间"}),
更改的类型 = Table.TransformColumnTypes(#"展开的“aa”",{{"开始时间", type datetime}, {"结束时间", type datetime}})
in
更改的类型
哈,第二题我也可以做出来了