vso*_*ler 1 excel excel-formula
我正在尝试计算某个范围内每列的运行(累积)总计(请参见下图)。
如果我每列使用一个 SCAN 函数,它就可以工作。但我必须编写与我有的列一样多的 SCAN 函数。
问题是我想使用一个包含所有列的动态数组公式,无论是当前列还是将来列。
当我尝试将 BYCOL 与 LAMBDA 和 SCAN 一起使用时,它不起作用。我想知道 BYCOL 是否能够与 SPILL 的函数一起使用。
如果 BYCOL 与 SCAN 不兼容,是否有解决方法可以对我的所有运行总计使用单个公式?
在单元格上D2输入以下公式:
=LET(set, A2:B5, m, COLUMNS(set), seq, SEQUENCE(m,1),
CUMULATE, LAMBDA(x, SCAN(0, x, LAMBDA(acc,item, acc+item))),
DROP(REDUCE(0,seq, LAMBDA(acc,idx, HSTACK(acc, CUMULATE(INDEX(set,,idx))))),,1)
)
Run Code Online (Sandbox Code Playgroud)
这是输出:
如果累加器正确初始化,并且第一列的累积和,它也可以在不删除DROP第一列的情况下工作,如下所示:
=LET(set, A2:B5, m, COLUMNS(set), seq, SEQUENCE(m,1),
CUMULATE, LAMBDA(x, SCAN(0, x, LAMBDA(acc,item, acc+item))),
REDUCE(0,seq, LAMBDA(acc,idx, IF(idx = 1, CUMULATE(INDEX(set,,idx)),
HSTACK(acc, CUMULATE(INDEX(set,,idx))))))
)
Run Code Online (Sandbox Code Playgroud)
另一种选择是使用MAP与输入范围相同的形状的以下解决方案,因此无需通过DROP/REDUCE/HSTACK模式添加列:
=LET(n, ROWS(A2:B5), m, COLUMNS(A2:B5),
rows, MAKEARRAY(n, m, LAMBDA(r, c, r)),cols, MAKEARRAY(n, m, LAMBDA(r, c, c)),
MAP(rows, cols, LAMBDA(r, c, SUM(INDEX(A2:B5, 1, c):INDEX(A2:B5, r, c)) ))
)
Run Code Online (Sandbox Code Playgroud)
注意:您不能传递名称来表示函数内的LET范围,以使用需要范围的函数/操作,例如构建范围如下:。检查@JosWoolley对此问题的答案:使用来自 LET 的名称变量会产生#VALUE!在 MAP 内部使用 SUM 并将范围定义为 INDEX : INDEXA2:B5LAMBDAINDEX() : INDEX()
BYCOL每列返回一个单元格,这就是为什么您会收到与Nested Array Error#CALC!相关的错误。可以使用模式来规避,例如此处解释:如何将 Excel 中的表格从垂直转换为水平,但具有@DavidLeal 提供的不同长度答案。DROP/REDUCE/HSTACK
对于您的特定情况,我们需要计算每列的累积和。我们LAMBDA为此创建了一个用户函数CUMULATE:
LAMBDA(x, SCAN(0, x, LAMBDA(acc, item, acc+item)))
Run Code Online (Sandbox Code Playgroud)
现在我们使用该模式来迭代所有列。REDUCE函数需要一个输入数组,因此我们创建一个seq包含列位置的名称。我们可以通过 访问输入范围 ( set)的每一列INDEX(set,,idx),其中idx表示列号。
DROP/REDUCE/HSTACK现在我们使用上面链接中解释的模式来生成每一列:
DROP(REDUCE(0, arr, LAMBDA(acc, x, HSTACK(acc, func(x)))),,1)
Run Code Online (Sandbox Code Playgroud)
在我们的例子func(x)中将是LAMBDA我们刚刚创建的用户函数:CUMULATE,所以在我们的例子中它将是:
DROP(REDUCE(0,seq, LAMBDA(acc,idx, HSTACK(acc, CUMULATE(INDEX(set,,idx))))),,1)
Run Code Online (Sandbox Code Playgroud)
它的作用是调用函数的每一列set,CUMULATE LAMBDA并通过HSTACK附加在每次迭代中创建的列。该变量acc代表累加器,因此我们从累加器的初始值开始0,然后通过以下列递归添加HSTACK。最后,我们需要删除DROP(result,,1)代表第一次迭代的第一列 via ,该迭代不计算累积和并仅生成如下所示的列:
0
#N/A
#N/A
#N/A
Run Code Online (Sandbox Code Playgroud)
注意:如果数组的行数少于所选数组的最大宽度,则在附加行中HSTACK返回错误。#N/A这就是为什么你会得到这样的价值观。最重要的是,需要删除第一列,因为我们在第一次迭代时没有使用有效值进行初始化。我提供了第二种替代方案,不需要删除此列,但最后是一个更详细的公式。这是个人喜好的问题。
| 归档时间: |
|
| 查看次数: |
510 次 |
| 最近记录: |