具有多个条件的复杂 excel 方程

Complicated excel equation with multiple conditions

我有一个 sheet,用于根据时间sheet 计算我的税收、扣除额和 401k。它还计算我的 PTO、病假和补偿天数(我没有加班,当我加班时,我会在年底作为额外的带薪休假得到那个时间)。我的问题是时间 sheet 很难计算我的病假天数,所有其他时间都是按小时计算或按发薪期计算。但是如果有病假,我每年都会得到一定的数额。

基本上,我每年有 10 天(80 小时)。所以我把这 80 个小时除以 26,这就是我在每个支付期间得到的病假时间。问题是,因为我得到双周工资,所以这实际上是不正确的。例如,这个月我有 2 份薪水,我有 0.92 天的病假时间,但实际上我应该有 1 天。在我有 3 份薪水的一年中的 2 个月里,我有 1.38 天的病假时间, 这当然也不正确。

所以问题是我想弄清楚如何编写一个公式来给我正确的天数。参考截图:

所以基本上在 G6 上,该公式采用上一年 (G39) 的累计病假并添加当前病假时间。它决定通过检查该支付期的总工资是否存在,然后将该金额乘以病假累计率 (G40),然后除以 8 得到天数。

但我想做的是检查已经填写了多少个月,return那个。所以在这个例子中五月已经完成,所以它会 return 1 天。由于 9 月有 3 个发薪期,您需要填写所有 9 月的薪水支票才能从 4 增加到 5(5 月、6 月、7 月、8 月为 4)。

有什么想法吗?我尝试做的一切都失败了。请记住,这些日期是动态的,明年当我更改纳税年度的开始日期时,有 3 个月的月份将更改以匹配该年的实际支付期。所以这个公式实际上需要能够计算出任何一个月有 3 个工资期来推进病假天数,否则如果只有 2 个已填写。

尝试 #2 回答! >8(

在一个单元格中完成这一切的最终方程式会变得丑陋,但它会起作用。为了解释这一点以及基本上我是如何开发它的,我将把它分解成几个部分。最后,这些部分将被重新代入大方程。

我做的第一件事是确定最后填充了哪一行,或者根据评论,P 列的最后一行值大于 0 的是什么。为了确定这一点,我使用了聚合函数一个 T15 的临时单元格(是的,在电子表格的中间,但最终无关紧要):

=AGGREGATE(14,6,(P5:P30>0)*(ROW(P5:P30)-ROW(P5)+1),1)

分解这个函数:

  • 14 告诉它我们要进行数组类型计算,将数组从大到小排序。
  • 6 告诉它忽略错误
  • (P5:P30>0) 告诉它构建一个真(或 1)和假(或 0)大于 0
  • 的单元格数组
  • (ROW(P5:P30)-ROW(P5)+1) 生成一个列出行号的数组
  • 1 告诉它 return 数组中的最大值,如果它是 2 第二大值。

现在重要的是当您将大于 0 的数组与行号数组相乘时会发生什么。您最终只会得到 P 中的值大于 0 的行号。当我们对其进行排序并要求最大的数字时,我们会得到您完成的最后一行。可以使用的东西。

所以现在我们可以查看最后完成的日期,做一些检查看看它是否是月底,并计算出有多少病假。丑陋的公式开始为:

=IF(MONTH(INDEX(I5:I30,T15))=MONTH(INDEX(I5:I30,T15)+14),MONTH(INDEX(I5:I30,T15))-1,MONTH(INDEX(I5:I30,T15)))

这里的逻辑测试是判断我们最后填写的日期和14天后的日期是否还是同月。如果它们是同一个月,则您还没有到月底,并且在病假期间只能赚取上个月的收入。因此,这部分将告诉我们上个月的病假天数 os:

MONTH(INDEX(I5:I30,T15))-1

现在,如果未来 14 天的日期不是同一个月,那么我们就知道该月的最后一个条目已经完成,因此我们在病假中累积了该月的数字,并使用基本相同的公式:

MONTH(INDEX(I5:I30,T15))-1

好吧,我可以看到我们调用了单元格 T15 4 次,只是为了确定我们是减去 1 还是减去 0。虽然 IF 公式可能感觉更符合您的思维过程,但我们可以重新排列并仍然得到相同的结果结果,但缩短了公式,将对单元格 t15 的调用减少 1,并将 IF 一起删除。这只有效,因为我们正在处理 1 和 0,这也是 true 和 false。

=MONTH(INDEX(I5:I30,T15))-(MONTH(INDEX(I5:I30,T15))=MONTH(INDEX(I5:I30,T15)+14))

现在让我们绕过 T15 计算并将其代入上面的月份公式以获得:

=MONTH(INDEX(I5:I30,AGGREGATE(14,6,(P5:P30>0)*(ROW(P5:P30)-ROW(P5)+1),1)))-(MONTH(INDEX(I5:I30,AGGREGATE(14,6,(P5:P30>0)*(ROW(P5:P30)-ROW(P5)+1),1)))=MONTH(INDEX(I5:I30,AGGREGATE(14,6,(P5:P30>0)*(ROW(P5:P30)-ROW(P5)+1),1))+14))

还没有完成。这只会告诉您今年累积的天数。不是你真正想知道的。您需要将其转换为小时。它还需要减少使用的病假天数。上面的大丑还需要补充以下内容:

  • *8 病假 8 小时到病假一天
  • -sum($L$5:$L$30) 计算病假时间

这导致:

=(MONTH(INDEX(I5:I30,AGGREGATE(14,6,(P5:P30>0)*(ROW(P5:P30)-ROW(P5)+1),1)))-(MONTH(INDEX(I5:I30,AGGREGATE(14,6,(P5:P30>0)*(ROW(P5:P30)-ROW(P5)+1),1)))=MONTH(INDEX(I5:I30,AGGREGATE(14,6,(P5:P30>0)*(ROW(P5:P30)-ROW(P5)+1),1))+14)))*8-sum($L:$L)

现在我确实在测试期间注意到,如果电子表格中没有任何条目,那么最后一个条目的行将变为 0,这根本不可接受,因为它会导致一些奇怪的结果。因此,我们将把整个公式包装在一个小的错误捕获器中,以确保在没有完成支付周期时结果为 0。

=if(sum(P5:P30)=0,0,(MONTH(INDEX(I5:I30,AGGREGATE(14,6,(P5:P30>0)*(ROW(P5:P30)-ROW(P5)+1),1)))-(MONTH(INDEX(I5:I30,AGGREGATE(14,6,(P5:P30>0)*(ROW(P5:P30)-ROW(P5)+1),1)))=MONTH(INDEX(I5:I30,AGGREGATE(14,6,(P5:P30>0)*(ROW(P5:P30)-ROW(P5)+1),1))+14)))*8-sum($L:$L))

锦上添花的是上一年的应计病假。因为我不确定患病率和患病率是如何一起计算的,所以我会把这个计算留给你,只是让你知道无论从前一年结转的数字,只需在最后一年之后将它添加到上面的公式中) .

这是我的测试平台,展示了概念验证:

警告:此方法##WILL## 产生的支付期错误结果在支付期 >0 的最后日期之前 =0 参见下面的示例: