0

注意:我已经通过 StackOverflow 上列出的几种不同方法多次验证这些单元格包含值而不是文本!

我正在尝试编写一个调度工作簿,它可以告诉我我目前的人员配备是否足够。有一张日程表,其中包含每个工作人员的打卡时间、第一次休息时间、第一次休息时间、午餐时间、午餐时间、第二次休息时间、第二次休息时间和打卡时间,以及那八 (8) 列重复七次 (x7) 以计算一周中的每一天。还有另一个“分析”电子表格,从周一上午 6:30 - 上午 6:45 到周日下午 5:45 - 下午 6:00,每行增加 15 分钟。

在分析表上,我尝试使用不同的公式将块开始和块结束时间增加 15 分钟,然后填写这 7 天内的每个块。假设我在单元格 B2 中手动输入上午 6:30,我记得尝试过的公式如下:

  • =B2+(15/60/24)
  • =TRUNC(B2+TIME(0,15,0),12)

当我尝试比较员工的预定开始时间是否大于或等于区块的开始时间,以及当我尝试比较员工的预定结束时间是否大于或等于区块的结束时,问题变得特别痛苦时间。我相信这是由于计算时间的序列值与手动输入的计划时间的序列值之间存在微小的毫秒差异。但是,我们的目标是通过 =COUNTIFS() 公式运行计划,以确定在该块的时间内出现的员工总数。到目前为止,我提出的公式看起来像这样(请忽略列引用,因为我将它复制到几列以便能够在第一列中尝试其他一些方法):

=COUNTIFS(OFFSET('Front Desk'!$B$5:$B$24,0,(MATCH(A2,'Front Desk'!$B$3:$BE$3,0)-1)),"<>",OFFSET('Front Desk'!$B$5:$B$24,0,(MATCH(A2,'Front Desk'!$B$3:$BE$3,0)-1)),"<="&'Front Desk Analysis'!H2,OFFSET('Front Desk'!$C$5:$C$24,0,(MATCH(A2,'Front Desk'!$B$3:$BE$3,0)-1)),"<>",OFFSET('Front Desk'!$C$5:$C$24,0,(MATCH(A2,'Front Desk'!$B$3:$BE$3,0)-1)),">="&'Front Desk Analysis'!L2)+COUNTIFS(OFFSET('Front Desk'!$D$5:$D$24,0,(MATCH(A2,'Front Desk'!$B$3:$BE$3,0)-1)),"<>",OFFSET('Front Desk'!$D$5:$D$24,0,(MATCH(A2,'Front Desk'!$B$3:$BE$3,0)-1)),"<="&'Front Desk Analysis'!H2,OFFSET('Front Desk'!$E$5:$E$24,0,(MATCH(A2,'Front Desk'!$B$3:$BE$3,0)-1)),"<>",OFFSET('Front Desk'!$E$5:$E$24,0,(MATCH(A2,'Front Desk'!$B$3:$BE$3,0)-1)),">="&'Front Desk Analysis'!L2)+COUNTIFS(OFFSET('Front Desk'!$F$5:$F$24,0,(MATCH(A2,'Front Desk'!$B$3:$BE$3,0)-1)),"<>",OFFSET('Front Desk'!$F$5:$F$24,0,(MATCH(A2,'Front Desk'!$B$3:$BE$3,0)-1)),"<="&'Front Desk Analysis'!H2,OFFSET('Front Desk'!$G$5:$G$24,0,(MATCH(A2,'Front Desk'!$B$3:$BE$3,0)-1)),"<>",OFFSET('Front Desk'!$G$5:$G$24,0,(MATCH(A2,'Front Desk'!$B$3:$BE$3,0)-1)),">="&'Front Desk Analysis'!L2)

请容忍我的长度和一些重复性,因为我试图解释四个时间间隔中的任何一个(打卡 - 第一次休息,第一次休息 - 午餐休息,午餐 - 第二次休息,和第二次休息 - 时钟出去)。我认为有必要披露函数的长度,并且它会变得更长,因为我需要考虑到一些员工可能会或可能不会在他们的一整天中休息和/或午餐(想象一下有一个短 2 到 4 小时轮班的人只会打卡一次)。如果我开始在那里添加一大堆复杂的嵌套 ROUND() 函数,我担心会达到函数限制。

如果我必须总结这个问题,我想我有四个问题:

  1. 为什么上午 9:30 和上午 10:30 的序列表示中的第 15 位十进制数字与手动输入时间的序列值相差一 (1),但两者之间差异的十进制扩展却没有?(0.395833333333334000000 - 0.395833333333333000000 = 0.000000000000000000000)
  2. 既然两个值之间的差值显然为零,​​那么为什么比较结果为假呢?
  3. 如果您要提出这是一个浮点计算问题的论点,那么为什么不会有更少的 TRUE 比较(因为每个计算值都是根据前一个值计算的,并与所有后续值的差异复合)这导致异常而不是规范?
  4. 与最后三个主题稍有不同,但这种方法是否类似于您用来解决整体调度问题的方法,或者您会建议什么来解决问题?

我对每个问题的答案同样感兴趣,因此请随时回复其中一个或全部(请在您的回复中注明相关问题#)。谢谢大家!

编辑:我是新来的关于堆栈溢出的问题,但我相信如果您遵循以下步骤,可以创建一个最小的可重现示例:

  1. 在单元格 B2 中键入“6:30 AM”+ Enter 键。
  2. 在单元格 B3 中键入“=B2+(15/60/24)”+ Enter 键。
  3. 单击格式刷按钮,然后单击单元格 B2,然后单击单元格 B3(如果正确执行步骤 1,则将公式单元格格式化为时间,否则从格式下拉菜单中单击常规,然后单击时间)。
  4. 选择单元格 B3,然后向下拖动,直到公式等于上午 9:30 或更大。
  5. 在与 B 列单元格相邻的 C 列单元格中键入“9:30 AM”+ Enter 键,该单元格也包含值“9:30 AM”+ Enter 键(我相信应该是第 14 行)。
  6. 在与这些单元格右侧相邻的 D 列单元格中,键入以下公式:=B14=C14+ Enter 键,您应该得到一个FALSE评估。

块分析表 员工日程表

4

1 回答 1

1

您正面临 Excel 数据/时间系统的古老问题,如您所知,它依赖于不准确的浮点数学。

解决方案一直是四舍五入到避免错误的幅度:

=ROUND(B5,7)

以上将时间值四舍五入到秒,允许接近的值相等,并且一秒的精度对于员工调度和工资单应该足够准确。

现在在公式中一遍又一遍地使用大量 ROUND() 函数远非理想。

有几种解决方法,都不是理想的。

1.) 拥有一个复制源数据的工作表,但对每个相应的数据点使用 ROUND() 函数。在这种情况下,您会将 COUNTIFS() 公式对准此中间表。这使您不必在每个 COUNTIFS() 中使用 ROUND() 无数次。确实 ROUND() 仍然在每个数据点上使用......但它只对每个数据点使用一次。

2.) 利用 VBA 进行计算并将结果返回到分析表。这甚至可以配置为用户定义函数 (UDF),您可以直接从分析表中调用它作为公式。

于 2020-03-25T16:09:51.600 回答