找出日期差距

时间:2018-07-20 21:04:36

标签: excel vba excel-formula powerpivot powerquery

我有一张桌子,上面有50000条工人记录。我正在尝试确定每个工人的“首次”开始日期。如果该工人已下班至少30天,则应重设第一日期。

如果有能力帮助解决此问题,我对功率查询和功率枢轴都很满意。我对VBA不太满意,但也不反对这种方式的解决方案。

数据

Unique ID   Order ID    Worker Start Date   Worker End Date
1   1   02/01/2016  03/23/2018
1   2   04/23/2018  04/25/2018
2   3   02/10/2014  05/15/2015
3   4   01/01/2013  05/02/2014
4   5   01/01/2013  05/01/2015
4   6   06/01/2015  10/28/2016
4   7   10/31/2016  07/31/2017
4   8   08/31/2017  04/22/2018
5   9   01/02/2017  05/05/2017
6   10  01/01/2013  12/31/2014
6   11  02/02/2015  01/31/2017
6   12  03/03/2017  04/22/2018
7   13  09/29/2014  09/29/2016
7   14  10/31/2016  03/02/2018
8   15  01/01/2013  05/04/2014
9   16  02/18/2013  05/20/2014
10  17  01/01/2015  03/31/2016
10  18  03/28/2016  03/03/2017
10  19  09/18/2017  09/18/2017
11  20  11/30/2015  02/12/2016
11  21  05/18/2016  07/29/2016
12  22  01/01/2013  11/14/2014
13  23  06/01/2015  08/27/2017
14  24  06/17/2013  02/08/2015
15  25  06/02/2014  11/30/2014
16  26  02/09/2015  06/12/2015
17  27  01/01/2013  12/23/2014
17  28  02/02/2015  12/22/2016
17  29  12/23/2016  12/21/2017

预期结果

Unique ID   Expected Date
1   04/23/2018
2   02/10/2014
3   01/01/2013
4   08/31/2017
5   01/02/2017
6   03/03/2017
7   10/31/2016
8   01/01/2013
9   02/18/2013
10  09/18/2017
11  05/18/2016
12  01/01/2013
13  06/01/2015
14  06/17/2013
15  06/02/2014
16  02/09/2015
17  02/02/2015

2 个答案:

答案 0 :(得分:3)

首先,创建一个自定义列Plus30,以便更轻松地了解正在发生的事情。

= Date.AddDays([Worker End Date], 30)

现在,我们需要一个自定义列,用于检查当前行的Plus30是否出现在下一行的Worker Start Date之前。

= Table.AddColumn(PrevisousStepName, "Custom",
      (C) => if List.Min(
                    Table.SelectRows(#"Changed Type",
                        each _[Unique ID] = C[Unique ID] and
                             _[Order ID]  > C[Order ID])
                    [Worker Start Date])
             > C[Plus30] then 1 else 0, Int64.Type)

如果该Error没有后续行,则返回Unique ID,如果下一行1小于该行{{1},则返回Worker Start Date },否则返回Plus30

这时,我将错误替换为整数(我任意选择了0),然后过滤掉了-1列中的所有1值。

一旦对它们进行了过滤,请按Custom对表进行分组,并为Unique ID列获取Worker Start Date的最小值。

这是我将您的数据加载到表Expected Date中的整个M代码:

Table1

请注意,您可以跳过添加let Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content], #"Changed Type" = Table.TransformColumnTypes(Source,{{"Unique ID", Int64.Type}, {"Order ID", Int64.Type}, {"Worker Start Date", type date}, {"Worker End Date", type date}}), #"Added Custom" = Table.AddColumn(#"Changed Type", "Plus30", each Date.AddDays([Worker End Date], 30), type date), #"Added Custom1" = Table.AddColumn(#"Added Custom", "Custom", (C) => if List.Min(Table.SelectRows(#"Changed Type", each _[Unique ID] = C[Unique ID] and _[Order ID] > C[Order ID])[Worker Start Date]) > C[Plus30] then 1 else 0, Int64.Type), #"Replaced Errors" = Table.ReplaceErrorValues(#"Added Custom1", {{"Custom", -1}}), #"Filtered Rows" = Table.SelectRows(#"Replaced Errors", each ([Custom] <> 1)), #"Grouped Rows" = Table.Group(#"Filtered Rows", {"Unique ID"}, {{"Expected Date", each List.Min([Worker Start Date]), type date}}) in #"Grouped Rows" 列,而只需在Plus30列中包含该位。为此,在公式中将Custom替换为C[Plus30]

答案 1 :(得分:1)

您的解释对我来说还不太清楚,但我想您的意思是您想要 最后 开始日期,但不包括缺少30天或更长时间的时间? Unique ID是员工吗?

如果是这样,我将使用简单的工作表公式和AutoFilter,首先添加带有公式的列以计算“此结束”与“下一次开始”之间的天数,如下所示:

img

...在此示例中,E2中的公式为:

=IF(A3<>A2,"",C3-D2)

然后自动过滤或删除E列中的数字大于30的任何行。

这将给出如下结果:

img

请注意,您数据中的ID #10上有一个重叠部分。