Excel根据3位准则计算假期

编辑开始第一,如果你是第一次阅读这个,这个编辑部分下面是我以前的post。

我认为获得我想要的结果的唯一方法是在vb中创build一个脚本,或者像Robin Mackenzie在下面的评论中提到的那样更改我的表格devise。

当我开始放弃希望的时候,为了这个目的,我做了一个自定义的函数,在和我的朋友交谈之后,他决定他更喜欢某种forms的input来增加数据的容易度,所以我打算把vb限制为forms和改变桌子的devise,以便我可以使用一个公式。

这是我的自定义函数包装任何人都需要这样的事情。

http://pastebin.com/PDCGLJs4

脚本不是那么大,但我不想在这篇文章中添加太多,这个脚本中有两个variables叫做newyears和christmas,那些variables代表“dd / mm”,年份是dynamic的,这两个date被排除在计数之外,我也增加了1,因为如果一个雇员需要24/02/2017closures,那么就会返回0。

一旦我做了我的更改,我会添加我的公式+任何东西到这个主题作为答案。

编辑结束

所以我一直在绞尽脑汁想弄清楚如何在没有VBA的情况下做到这一点。 我正在创build一张员工表,其中包含薪资信息和每个员工所做的假期,我已经完成了所有工作,并且在需要的地方完全dynamic,除非我无法弄清楚如何为每个员工提取假日数据适合两个date以及如何计算所有的date。

这是员工假期表的一个例子

这是薪资数据的一个例子

因此,我需要提取每周指定范围内的所有假期,然后计算它们以获取date之间的date。

例如:在第一周,同一个人在不同的date有四个假期(艾米阿尔法),也有一个员工从第四周开始到第五周结束(Elaine Echo)。

基本上,我只需要抓住每个星期内的假期,所以说到Elaine Echo,我只需要在第四周和第五周两个假期,但是当谈到艾米,我需要得到所有人她那个星期内的假期。

最重要的是,我需要确定假期是否在12月25日和1月1日closures的date。

我在提取信息方面没有任何问题,计算我需要计算的东西没有问题,但似乎无法创build一个公式来做这两个,所以这里是我现在基本上得到的。

下面的代码将检查1月1日或12月25日是否在本周之间,然后检查date是否也在我们的假期范围之内,如果是,则加1或2,然后从假期中扣除,因为工作场所是在那天closures

B18是假期开始date

C18是假期结束date

B4是一周StartDate

D4是星期结束date

A6是员工姓名的开始

我也有定义的假期表

Holiday_Table

Holiday_StartDate

Holiday_EndDate

SUM((IF(OR(AND((DATE(YEAR(B18),12,25)>=B4),(DATE(YEAR(B18),12,25)<=D4)),AND((DATE(YEAR(C18),12,25)>=B4),(DATE(YEAR(C18),12,25)<=D4))),"1","0"))+(IF(OR(AND((DATE(YEAR(B18),1,1)>=B4),(DATE(YEAR(B18),1,1)<=D4)),AND((DATE(YEAR(C18),1,1)>=B4),(DATE(YEAR(C18),1,1)<=D4))),"1","0"))) 

接下来是我的date的计算,这个例子与上面相同的单元格,它基本上做的是发现假日开始date是否在一周内,如果假期结束date是在一周之内,那么它只是得到date假日开始date和结束date之间的差异,或者工作开始date和假期结束date,假日开始date和工作结束date之间的差异,或者最终得到工作周的开始date和结束date之间的date差异。

 IF((B18>=B$4)*(B18<=D$4),IF((C18>=B$4)*(C18<=D$4),SUM(C18-B18),SUM(D$4-B18)),IF((C18>=B$4)*(C18<=D$4),SUM(C18-B$4),IF((B18<=$B$4)*(C18>=$D$4),SUM(D$4-B$4),IF(B18>D$4,0,"errend")))) 

所以在这个代码中,一旦得到总天数,如果节假日是在1月1日或12月25日,则其他代码将扣除1或2。

用一个公式可能会有一个更简单的方法来做到这一点,而我可能已经把它复杂化了,但是现在我想不出一个办法

  1. 根据两个date和员工姓名提取数据。
  2. 计算所有这些,并扣除店铺closures的date。

我试图用if语句,index,countifs和match来得到每个员工的价值,员工的名字就是这样的一个例子,但是我无法弄清楚假期的一部分公式。

只要有帮助,这是我的雇员名字的公式。

 =IFERROR(INDEX(Payroll_Table,MATCH( 0,IF(Payroll_StartDate>=$A$2,IF(Payroll_EndDate>=$A$4,COUNTIF($A$5:A5,INDEX(Payroll_Table,,1))),"")),1),"") 

在这个例子中,A2是开始date,A4是工资单的结束date,这就是我如何得到我的工作范围,以及这个星期哪个员工的工作。

希望有人能帮助我,提前谢谢你。

哇! 你承担了相当的任务。 当然,我的build议是使用VBA,但你已经注意到这不是一个选项。 这是一个好消息:你可以做到,但这将是非常复杂的。

因为您正在将复杂逻辑应用到基于单元格的数据中,所以通过创build工作表使其变得非常简单。 这与大多数政府机构在提交税务方面的情况类似。 您将一步一步地处理数据,并将其分解为块,并且一行中的值将基于上述行的值。

像这样的工作表应该有一个独立于主文档的Excel工作表,这样你就可以隐藏所有的数据和计算。

我会开始dynamic地build立一个查询表。

  1. 在工作簿中创build一个新工作表。
  2. 在最左边一列中,将表格的第一个值设置为week1的开始date。
  3. 在下面每行的列中,将date递增1天,直到您到达周末或总周期结束(从一周开始,然后展开。

现在你有一个星期的日子在考虑。 现在在表格的下一列中,你的问题变成了,员工X在这一天是否有假期?

由于您没有使用VBA,因此您需要为“假期历史logging”表的每一行硬编码这些检查,每个员工需要一张表。

艾米的假期工作表

在上面的工作表中,我试图通过将员工姓名放在B1单元格中让我的生活更轻松。 这样,我可以复制工作页面,只更改员工名称来更新表值。

在B3:G3范围内,我将B1中的员工姓名与我在假期表中检查的行的名称进行比较。 列B检查行Sheet1!A3:D3上的数据表,并且列D检查行Sheet1!A5:D5上的数据表。 这两行都是Amy Alpha的,所以它们的结果是TRUE。 其他行导致FALSE,因为名称不匹配。

在这些值的下面,我嵌套了IF语句:

  1. 如果上面的值是TRUE(这行匹配员工姓名,继续),否则输出一个空string“”并继续前进。
  2. …嵌套…列A中的date是否在相应的表格行的开始date和结束date之间? 如果是,则输出1天,否则输出0天。

结果是1和0值的表格。 我总结每一行,并将结果存储在我的工作表的H列。 请注意,这使我可以检查错误和重叠的假期,因为可以使用两行包含重叠节假日的表格格式。 举例来说,如果一个假期的开始date是错误的年份,那么它肯定会覆盖所有的假期,员工将有两个假期与一个date相关联。

在第一列中,我检查列A中的date是否与每周列的开始date相匹配。 这个检查是不必要的,但我用它来帮助清理J列中的数据,以便我只显示我真正感兴趣的数据。

J列输出当前行总和(H列)加上后面的6天的总和,得出一周的假期总和。

现在,在Sheet1上,我使用一个VLOOKUP()根据一周的开始date从列J中提取值。 对于每位员工,我的第一周的VLOOKUP如下(注意,我在他们build模的员工之后命名了我的工作表)

  • =VLOOKUP($B$13,Amy!$A$4:$J$38,10,FALSE)
  • =VLOOKUP($B$13,Brian!$A$4:$J$38,10,FALSE)
  • =VLOOKUP($B$13,Charlie!$A$4:$J$38,10,FALSE)
  • 等等

$ B $ 13包含第1周的开始date,VLOOKUP将search与该date匹配的行。 当find该行时,它将移动到与列J相匹配的列#10,并返回该值。

对于第2周我的公式是:

* =VLOOKUP($D$13,Amy!$A$4:$J$38,10,FALSE) * =VLOOKUP($D$13,Amy!$A$4:$J$38,10,FALSE) =VLOOKUP($D$13,Charlie!$A$4:$J$38,10,FALSE) *等

我的标签已被复制,每个员工都有自己的选项卡…结果是这张表(我没有格式化或小时数据):

假期计算员工 - 没有VBA

您可以下载我的示例电子表格的副本,以便在此链接中查看更详细的信息,我将在2017年3月31日前保持活动状态: 示例XLS文档 – 无macros

我一直不情愿地倾向于这个解决scheme,但罗宾·麦肯齐的评论摇摆了我的决定。

所以,在我继续之前,我只想说,我已经附加了Excel表格中的一些模拟数据,以防万一任何人想看一下,它包含的脚本主要是我已经embedded到概述中的用户表单片。 我还要感谢Robin和Jared Clemence在这个问题上的两分钱,不胜感激。

而不是假期表的开始和结束date,我仍然认为这是input信息的最佳方式,excel已经使我的意志,我现在有1行的假期,这意味着我的桌子看起来像这样。

 Name | Holiday Emp1 | 21-Feb-17 Emp1 | 22-Feb-17 Emp1 | 23-Feb-17 

我只是使用COUNTIFS函数来计算它

A5是员工姓名B3是周开始dateC3是周结束date

 =COUNTIFS(tbl_holiday_name,"="&$A5,tbl_holiday_dates,">="&B$3,tbl_holiday_dates,"<="&C$3) 

为了方便阅读,我省略了很多代码,还可以包括商店closures时的两个假期,看起来像这样

 tbl_holiday_dates,"<>"&DATE(YEAR(Overview!E2),12,25), tbl_holiday_dates,"<>"&DATE(YEAR(Overview!E2)+1,1,1) 

总览是表格名称,E2包含标记新的假期年份开始的date。 另一种select,而不是使用公式来忽略特定的date,我可以添加一个黑名单,表格将被忽略具体的date时,被input到表中。

最后,这里是一个模拟表,它不完整,但我想我已经摆脱了大部分,如果不是所有的错误,我的公式

ShopSheetTemp.xlsm