1

我有一个谷歌电子表格维护事件历史及其发生日期,如下所示(B 列是开始日期,C 列是结束日期):

Sheet A
| | A      | B         | C         |
|1| Event1 | 1/15/2013 | 2/20/2013 |
|2| Event2 | 3/1/2013  | 3/10/2013 |
|3| Event3 | 5/7/2013  | 5/9/2013  |

我想要做的是能够找出,给定另一个日期范围,与这些事件中的任何一个重叠的总天数。例如,如果我的日期范围是 2013 年 2 月 1 日到 2013 年 3 月 15 日,那么计算应该能够确定与 Event1 有 20 天的重叠,与 Event2 有 10 天的重叠,以及 0 天与 Event3 重叠。把它们放在一起,我想显示的值是 30。

这是一个示例第二张表,显示了我要为几个示例日期范围计算为列 C 的值:

Sheet B
| | A         | B         | C  |
|1| 2/1/2013  | 3/15/2013 | 30 |
|2| 3/20/2013 | 3/25/2013 | 0  |
|3| 5/1/2013  | 5/7/2013  | 1  |

我遇到的问题是,虽然我可以编写单元格表达式来显示 SUM 和 FILTER 几乎可以让我到达那里,但我尝试的最后一步(我已经尝试了多种方法来让它工作)似乎总是将我对所有事件的计算减少到一个标量,然后我才能对每个事件求和。

例如,如果我为工作表 B 的 C1 单元格编写如下所示的内容,作为弄清楚如何计算的一个步骤:

=SUM(MIN(B1,'Sheet A'!C:C) - MAX(A1,'Sheet A'!B:B))

然后 SUM 清楚地包括负值,其中事件不与所讨论的时间段重叠。(您可以调整公式并将其扩展为工作表 A 的每一行以查看未汇总的值。)

但是,如果我尝试使用类似下面的内容过滤掉那些不相交的行,我只会得到一个“#N/A”的结果。我猜这是因为 FILTER 函数不喜欢在求和的值和标准中使用相同的范围,但这只是一个猜测:

=SUM(FILTER( MIN(B1,'Sheet A'!C:C)-MAX(A1,'Sheet A'!B:B) ; MIN(B1,'Sheet A'!C:C)>MAX(A1,'Sheet A'!B:B) ))

如果我尝试使用 MAX() 函数或 IF() 来清除非相交行产生的负值,则 SUM 返回 0。我认为这是因为 MAX 和 IF 正在减少数据在求和完成之前,我想将范围求和到单个标量变量。即 SUM() 在单个标量上运行。

=SUM( MAX(0, MIN(B1,'Sheet A'!C:C) - MAX(A1,'Sheet A'!B:B)) )

或者

=SUM(IF( MIN(B1,'Sheet A'!C:C)>MAX(A1,'Sheet A'!B:B), MIN(B1,'Sheet A'!C:C) - MAX(A1,'Sheet A'!B:B), 0))

任何想法如何计算我想要的?我唯一的另一个想法是将工作表 A 展开,以便每一行仅涵盖一天。然后找到相交天数的总和应该会更容易一些,但是向工作表 A 添加新事件的努力会大大增加。

4

2 回答 2

0

在尝试了许多不同的方法来让 Google 电子表格允许 IF、MAX、MIN、SUM、FILTER、SUMIF、ARRAYFORUMLA 等在列范围内按行进行评估(计算中涉及多个单列范围,但它们大小都一样,如果我能让 Google 将每一行视为 DB 条目类型的东西,一切都应该工作,)我放弃并重构了我的事件表,以便单个事件跨越多行,每行代表一个日历日。也就是说,上面的工作表 A 现在看起来像:

Sheet A
|  | A      | B         |
|1 | Event1 | 1/15/2013 |
...
|17|        | 1/31/2013 |
[18|        | 2/1/2013  |
...
|38|        | 2/20/2013 |
|39| Event2 | 3/1/2013  |
...
|49|        | 3/10/2013 |
|50| Event3 | 5/7/2013  |
|51|        | 5/8/2013  |
|52|        | 5/9/2013  |

这样就没有复杂的范围与范围交叉计算,因此基于事件日是否在查询范围内的简单 FILTER() 有效。

于 2013-09-27T23:30:17.463 回答
0

要获得给定日期范围(SheetB!A2 中的开始日期、SheetB!B2 中的结束日期、结束日期是 INCLUSIVE)与 SheetA!B2:B 和 SheetA! C2:C 分别在 C2 中使用以下公式:

=SUM(ArrayFormula(IF((SheetA!$B$2:$B="")+(SheetA!$C$2:$C=""),"",IF((TRANSPOSE(INDEX(ArrayFormula(QUERY(TRANSPOSE({SheetA!$C$2:$C,$B2+0*SheetA!$C$2:$C}),"Select "&"MIN(Col"&JOIN(", MIN(Col",SEQUENCE(ROWS(SheetA!$C$2:$C))&")"),0)),2))-TRANSPOSE(INDEX(ArrayFormula(QUERY(TRANSPOSE({SheetA!$B$2:$B,$A2+0*SheetA!$B$2:$B}),"Select "&"MAX(Col"&JOIN(", MAX(Col",SEQUENCE(ROWS(SheetA!$B$2:$B))&")"),0)),2)))>=0,(TRANSPOSE(INDEX(ArrayFormula(QUERY(TRANSPOSE({SheetA!$C$2:$C,$B2+0*SheetA!$C$2:$C}),"Select "&"MIN(Col"&JOIN(", MIN(Col",SEQUENCE(ROWS(SheetA!$C$2:$C))&")"),0)),2))-TRANSPOSE(INDEX(ArrayFormula(QUERY(TRANSPOSE({SheetA!$B$2:$B,$A2+0*SheetA!$B$2:$B}),"Select "&"MAX(Col"&JOIN(", MAX(Col",SEQUENCE(ROWS(SheetA!$B$2:$B))&")"),0)),2)))+1,0))))

如果您的结束日期是独家使用:

=SUM(ArrayFormula(IF((SheetA!$B$2:$B="")+(SheetA!$C$2:$C=""),"",IF((TRANSPOSE(INDEX(ArrayFormula(QUERY(TRANSPOSE({SheetA!$C$2:$C,$B2+0*SheetA!$C$2:$C}),"Select "&"MIN(Col"&JOIN(", MIN(Col",SEQUENCE(ROWS(SheetA!$C$2:$C))&")"),0)),2))-TRANSPOSE(INDEX(ArrayFormula(QUERY(TRANSPOSE({SheetA!$B$2:$B,$A2+0*SheetA!$B$2:$B}),"Select "&"MAX(Col"&JOIN(", MAX(Col",SEQUENCE(ROWS(SheetA!$B$2:$B))&")"),0)),2)))>0,(TRANSPOSE(INDEX(ArrayFormula(QUERY(TRANSPOSE({SheetA!$C$2:$C,$B2+0*SheetA!$C$2:$C}),"Select "&"MIN(Col"&JOIN(", MIN(Col",SEQUENCE(ROWS(SheetA!$C$2:$C))&")"),0)),2))-TRANSPOSE(INDEX(ArrayFormula(QUERY(TRANSPOSE({SheetA!$B$2:$B,$A2+0*SheetA!$B$2:$B}),"Select "&"MAX(Col"&JOIN(", MAX(Col",SEQUENCE(ROWS(SheetA!$B$2:$B))&")"),0)),2))),0))))

您可以将其向下拖动以获取 SheetB 中其他行的编号。

按行计算数组的 MAX/MIN 的问题在这里解决:https ://stackoverflow.com/a/64314420/3525368

于 2020-10-12T10:00:32.213 回答