【问题标题】:Excel Cell Formula: Intermittent Error Comparing Calculated vs. Manually Entered Time ValuesExcel 单元格公式:比较计算的时间值与手动输入的时间值的间歇性错误
【发布时间】:2020-07-04 09:08:31
【问题描述】:

注意:我已经通过 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 评估。

【问题讨论】:

  • 请创建一个minimal reproducible example。这里有太多内容需要我们排除以找出您的问题。
  • 嗨。这听起来像是一个有趣的问题,但如果没有工作簿,就很难理解。你能给我发一份证明问题的吗?我很乐意看看解决方案。
  • @ExcelHero 抱歉,但我如何向您发送我的演示工作簿?

标签: excel time excel-formula comparison datetime-comparison


【解决方案1】:

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

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

=ROUND(B5,7)

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

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

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

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

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

【讨论】:

  • 仅供参考,我刚刚发现对于方法 #1,您实际上需要四舍五入到小数点后 7 位,所以公式应该是 =ROUND(B2+TIME(0,15,0), 7)。这将防止秒值中的错误在一天中填写时复合(因为每个值都是根据前一个值计算的)。
  • 我在四舍五入到小数点后 7 位时仍然存在比较问题,因此我将在开始时间后的 # 分钟内插入一个新列,它将包含一个将 15 添加到每个后续行的公式(从单元格 B2 中的 0 开始)。然后我将在TIME(Hours, Minutes, Seconds) 公式中使用该值来防止复合错误。
  • VBA 可能是适合您情况的最佳方法。
猜你喜欢
  • 2014-10-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多