我有下表:
A1 - 25
A2 - 26
A3-27
A4 - 空白
A5-30
A6-23
A7 - 空白
A8-24
在 B1 中,我想要以下内容 - 从 A1 开始,对条目求和,直到遇到第一个空白单元格。在这种情况下,它将是 25+26+27 = 78。
我已经看了几个小时的多个答案并尝试调整它们,但没有任何效果。感谢任何帮助(而且很多事情没有意义,函数 isblank(a1:a10) 将返回 true 或 false,那么 arrayformula(isblank(a1:a10)) 如何突然将其转换为数组,因为 isblank只是返回一个布尔值?)
这里有几种方法以及显示这两种方法的电子表格。
https://docs.google.com/spreadsheets/d/1rkLarQC6NQ4HdGa38X3-rPoAW0A2-USvImFimlelhZM/edit#gid=0
方法1:使用MATCH查找第一个空白行的行,然后用INDIRECT构造引用传递给SUM:
=sum(indirect("a1:a" & match("~~", arrayformula("~" & A1:A10 & "~"), 0) - 1))
重新格式化:
=sum(
indirect(
"a1:a" &
match(
"~~",
arrayformula("~" & A1:A10 & "~"),
0
) - 1
)
)
这里唯一棘手的事情是,如果您只是传递“”来查找,则 MATCH 会返回错误,因此我使用 ARRAYFORMULA 将 A1:A10 范围包装在分隔符中(〜在本例中,但这是任意的),然后在数组中查找 ~~。这将返回第 4 行,因此我使用间接构造对 A1:A3 的引用并将其传递给 sum。
与ztiaa的方法类似,但较差。他直接过滤 ROW() 结果,并使用 A:A 作为过滤参数。两者都优于我使用 ISBLANK 等传递给 FILTER
第二,同样的想法(找到第一个空行的编号并构造一个引用传递给INDIRECT):
=sum(indirect("a1:a" & filter(ARRAYFORMULA(isblank(A2:A11)*row(A2:A11)), ARRAYFORMULA(isblank(A2:A11)*row(A2:A11))<>0)-1))
重新格式化以便于阅读:
=sum(
indirect(
"a1:a" &
filter(
ARRAYFORMULA(isblank(A1:A10)*row(A1:A10)),
ARRAYFORMULA(isblank(A1:A10)*row(A1:A10))<>0
) - 1,
)
)
因此,我使用
ISBLANK(A1:A10)
获取一个布尔数组,指示哪些行为空,然后将其乘以 ROW(A1:A10)
,这将返回一个包含该范围内所有行号的数组,所有行号都在 ARRAYFORMULA
内。
ARRAYFORMULA(isblank(A1:A10)*row(A1:A10))
在乘法中使用布尔值会将它们转换为零,因此这将生成一个 0(对于非空白行)或行号(对于任何空白行)的数组。然后我采用相同的公式并使用 FILTER 删除所有零
filter(
ARRAYFORMULA(isblank(A1:A10)*row(A1:A10)),
ARRAYFORMULA(isblank(A1:A10)*row(A1:A10))<>0
)
留下一个包含每个空白行的行号的数组。由于它们是按顺序排列的,并且 Sheets 缺乏动态数组处理,因此返回值只是第一个值而不是数组,因此我们可以将其传递给 INDIRECT 以使用该行号 - 1 生成对范围的引用(因为我想要范围从 A1 到紧邻第一个空白行之前的行):
indirect(
"a1:a" &
filter(
ARRAYFORMULA(isblank(A1:A10)*row(A1:A10)),
ARRAYFORMULA(isblank(A1:A10)*row(A1:A10))<>0
)-1
)
然后作为最后一步,将整个内容包装在 SUM 中,对刚刚使用 INDIRECT 创建引用的范围内的值求和。
=sum(
indirect(
"a1:a" &
filter(
ARRAYFORMULA(isblank(A1:A10)*row(A1:A10)),
ARRAYFORMULA(isblank(A1:A10)*row(A1:A10))<>0
)-1
)
)
[![在此处输入图像描述][1]][1]
让我知道这是否适合您。我想有更好的方法来做到这一点。我会继续思考。
player0 的回答非常有趣 - 但缺乏解释。 我在互联网上找不到任何地方(无论是 Google 文档,还是任何其他页面),也找不到 ChatGPT 可以解释它,所以我决定创建一个更详细的解释。
这里是原始公式:
=FLATTEN(INDEX(QUERY(; "select "&SUBSTITUTE(JOIN("+";
IF(INDIRECT("A1:A"&MAX(ROW(A1:A)*(A1:A<>"")))="";
","; A1:A)); "+,+"; ",")); 2))
工作原理:
(1) 神奇之处在于 index() 公式 - 索引与范围一起运行循环。
(2) 剩下的就是简单的解析,在查询 select 语句中生成一个静态字符串 - 最后,该字符串归结为“select 25+26+27,30+23,40,5+-6” .
理解索引与范围和 if 的结合:
最相关的部分是:
=index(if(A1:A11="",",",A1:A))
Index 导致条件语句逐行执行(就像
arrayformula()
那样)。因此循环会迭代条件中的每个值,如果为空则返回逗号,否则返回值。
查询的内部部分可以重写为:
"select "&
SUBSTITUTE(
JOIN(
"+",
ARRAYFORMULA(
IF(
INDIRECT(
"A1:A"&MAX(ROW(A1:A)*(A1:A<>""))
)="", // INDIRECT: create range up to last not-empty cell
",",
A1:A
) // IF: replace empty values in range with comma
), // ARRAYFORMULA: runs the loop
) // JOIN: create string out of range
"+,+", ",") // SUBSTITUTE: clean up string from empty lines
对于每个高级 Google Sheet 用户来说,这可能都很容易理解。
现在请注意: (1)
arrayformula()
可以用 index()
代替,并且会产生相同的结果
(2) arrayformula()
可以被提升到 query() 之外,并且仍然会产生相同的结果。