Excel根据3位标准

时间:2017-02-19 17:56:00

标签: excel excel-vba excel-formula vba

编辑开始 首先,如果您是第一次阅读此内容,则此编辑部分下方是我以前的帖子。

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

当我开始放弃希望时,我已经为此目的制作了一个自定义函数,在与我的朋友交谈后,他已经决定他更喜欢某种输入形式,以便更容易添加数据,所以我将限制vb到表单并更改表设计,以便我可以使用公式。

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

http://pastebin.com/PDCGLJs4

脚本不是那么大但我不想在这篇文章中添加太多内容,该脚本中有两个变量叫做newyears和christmas,这些变量代表“dd / mm”年份是动态的,这两个日期被排除在计数之外,我也将日期加1,因为如果员工休息24/02/2017,则日期会回来0。

一旦我做了更改,我就会将我的公式+任何内容添加到此主题作为答案。

编辑结束

因此,如果没有VBA,我一直在试图弄清楚如何做到这一点。我正在创建一份员工表,其中包含每位员工的工资单信息和假期,我已经完成了所有其他工作并且在我需要的地方完全动态,除了我无法弄清楚如何为每位员工提取假期数据适合两个日期以及如何计算所有日期。

Here is an example of the employee holiday table

Here is an example of the payroll data

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

示例:在第1周,同一个人在不同的日期(Amy Alpha)有4个假期,还有一个员工从第4周开始并在第5周结束(Elaine Echo)。 / p>

基本上,我只需要抓住每周内的假期,所以当谈到Elaine Echo时,我需要在第5周的第4周和第3个假期只获得2个假期,但是当谈到Amy我需要在那一周内完成所有假期。

除此之外,我还需要了解假期是否超过商店于12月25日和1月1日关闭的日期。

我在提取信息方面没有任何问题,我在计算我需要计算的内容方面没有任何问题,但我似乎无法创建两者的公式,所以这是我目前基本上得到的。

以下代码将检查1月1日或12月25日是否介于我们的一周之间,然后检查日期是否也在我们的假期范围内,如果是这样,它会增加1或2,然后从那个假期中扣除工作场所在该日期关闭

B18是Holiday StartDate

C18是Holiday EndDate

B4是Week StartDate

D4是Week EndDate

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")))

接下来是我的日期的计算,这个例子的上述相同的单元格,它基本上做的是找出Holiday StartDate是否在一周内,如果Holiday EndDate在一周内,那么它只是获取Holiday StartDate和EndDate,或Start StartDate和Holiday Enddate,Holiday StartDate和Work EndDate之间的日期差异,或者最终得到工作周的开始和结束日期之间的日期差异。

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. 根据两个日期和员工姓名提取数据。
  2. 计算所有这些并扣除日期 商店关门了。
  3. 我曾尝试使用if语句,索引,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是开始日期,A4是工资单的结束日期,这就是我获得周数范围的方式以及当周工作人员的工作范围。

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

2 个答案:

答案 0 :(得分:1)

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

因为您正在将复杂逻辑实现为基于单元格的数据,所以通过创建工作表可以使其变得最简单。这与大多数政府机构提交税务的做法类似。您将逐步处理数据并将其分解为块,并且一行中的值将基于上面行的值。

这样的工作表应该有一个与主文档分开的Excel工作表,以便您可以隐藏所有数据和计算。

我首先要动态构建一个查找表。

  1. 在工作簿中创建新工作表。
  2. 在最左侧的列中,将表的第一个值设置为等于week1的开始日期。
  3. 在下面每行的列中,将日期递增1天,直到您到达本周末或整个期间结束时(从一周开始,然后展开。
  4. 现在您有一个正在考虑的一周中的天数列表。现在在表的下一栏中,您的问题变成了,员工X在这一天有假期吗?

    因为您没有使用VBA,所以您需要为Holiday History表的每一行硬编码这些检查,并且每个员工需要一张表。

    Worksheet for Amy's Holiday

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

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

    在这些值之下,我有嵌套的IF语句:

    1. 如果上面的值为TRUE(此行与员工姓名匹配,则继续),否则输出空字符串“”并继续。
    2. ...嵌套... A列中的日期是否落在相应表格行的开始日期和结束日期之间?如果是,则输出1天,否则输出0天。
    3. 结果是一个值为1和0的表。我对每一行求和并将结果存储在我的工作表的H列中。请注意,这允许我检查错误和重叠假期,因为可以使用两行包含重叠假日的表格式。例如,如果假期的开始日期是在错误的年份输入的,那么肯定会在它之前的所有假期重叠,并且员工将有2个假期与单个日期相关联。

      在第一列中,我检查A列中的日期是否与每周列的开始日期之一匹配。这个检查不是必需的,但我用它来帮助清理J列中的数据,这样我才能显示我真正感兴趣的数据。

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

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

      • =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周的开始日期,VLOOKUP搜索与该日期匹配的行。找到该行后,它将移动到与列J匹配的列#10,并返回该值。

      对于第2周,我的公式是:

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

      我的标签已被复制,每位员工都有自己的标签...结果就是这张桌子(我没有打扰格式或小时数据):

      Holiday calculations by employee - no VBA

      您可以在此链接下载我的示例电子表格的副本,以便进一步审核,我将在2017年3月31日之前保持有效状态:Example XLS Document - No macros

答案 1 :(得分:0)

我一直不情愿地倾向于这个解决方案,但Robin Mackenzie的评论影响了我这样做的决定。

所以在我继续之前,我只是想说我已经附上了excel表格中的一些模拟数据,以防万一有人想看一看,它确实包含主要针对我嵌入的用户形式的脚本在概述表中。我还要感谢Robin和Jared Clemence在这件事上的两分钱,非常感谢。

而不是假期表的开始和结束日期,我老实说仍然认为这是输入信息的最佳方式,excel已经弯曲了我的意志,我现在有一排假期日期,这意味着我的表看起来像这样。

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

我只是使用COUNTIFS函数计算它

A5是员工姓名 B3是周开始日期 C3是周结束日期

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

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

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

概述是工作表名称,E2包含标记新假期开始的日期。另一个选项,而不是使用公式来忽略特定日期,我可以改为向表单中添加一个黑名单,它会在输入表格时忽略特定日期。

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

ShopSheetTemp.xlsm