Excel 用于创建列的 运行 产品的动态数组公式

Excel Dynamic Array formula to create a running product of a column

我需要从一列数字创建一个 运行 产品(我可以使用一行,但在这里使用一列更容易演示。)输入可以是任意数组。事实上,在我要部署它的应用程序中,它不是一个范围,而是 LAMBDA 公式中的另一个动态数组。这是数字输入列和公式所需输出的示例:

输入 预期的动态数组输出
10 10
8 80
3 240
4 960
5 4800

公式会溢出结果。

总计 运行 有很多解决方案,但我没有找到 运行 产品的解决方案。我尝试了几种不同的方法,包括 SUBTOTAL 和 AGGREGATE,但都没有成功。我还构建了多种方法来获得结果,但都被硬编码为固定数量的行。我需要公式来适应任意大小的行数。以下公式是我迄今为止得到的最接近的公式。

这个 LET 公式提供了结果,但是,如您所见,它固定为 5 行:

=LET( a, {10;8;3;4;5},
       v, SEQUENCE( ROWS(a) ), h, TRANSPOSE( v ),
       stagr, (v - h + 1) * (v >= h),
       m, IFERROR(INDEX( a, IF(stagr>0,stagr,-1), ), 1),
       almost, INDEX(m,v,h) * INDEX(m,v,h+1) * INDEX(m,v,h+2) * INDEX(m,v,h+3) * INDEX(m,v,h+4),
       result, INDEX( almost, , 1 ),
       result )

输入的任意数字数组放在变量a.

下一步是创建一些用于处理这些数字的索引:va[ 中每个数字的垂直行序列=122=] 和 h 是相同的序列,但转置为列。 stagr 是从 vh 创建的索引矩阵,稍后将用于处理每个a 中的项目,将其组成 乘法矩阵 。如果把最后的result换成stagr,就可以看到stagr的形状了。它只是将一列向下移动一行,直到它们一直向下移动。

现在我们通过简单地使用 INDEX 使用 stagr 创建乘法矩阵 m,如下所示:INDEX(a,stagr)。但这并不是真正需要的,因为它采用第一行值 (10) 并复制它,因为 0 的 INDEX 被视为与 1 相同。为了得到我们想要的,我通过使用和内部 IF 语句强制出错this: INDEX( a, IF(stagr>0,stagr,-1) ) 将 0 结果替换为 -1。即它会产生这个:

现在,使用 IFERROR 将错误替换为 1,这样就解释了 m 的创建方式和原因。结果是这样的矩阵:

通过按行乘以 m,我们得到了我们想要的输出,但是 这是我失败的地方.

为了说明,我创建了一个变量 almost,它显示了我如何尝试进行逐行乘法。

almost, INDEX(m,v,h) * INDEX(m,v,h+1) * INDEX(m,v,h+2) * INDEX(m,v,h+3) * INDEX(m,v,h+4)

你可以看到我粗略地将一列乘以下一列和下一列...并使用 h + offset 得到那里。这会生成 almost 矩阵,而 result 仅提供该矩阵的第一列,其中包含答案。

虽然答案可能是动态调整大小的 almost 的一个很好的替代品,但这不是我真正的问题。我想要一个 运行 产品,我怀疑有一种完全不同的方法,而不是简单地替换我的 almost.

明确一点,结果必须是一个动态数组,没有辅助单元格或 CSE 拖拽。

oh... and no VBA. (@Whosebug - please add a no-VBA tag)

我能找到的唯一方法是将 DPRODUCT 与 OFFSET 一起使用,但这需要标题行。标题行中的内容无关紧要(甚至可以为空),只要包含即可。

=DPRODUCT(OFFSET(A1,0,0,SEQUENCE(COUNT(A:A),,2)),1,$ZZ1:$ZZ2)

$ZZ1:$ZZ2 可以是任何空单元格引用。

如果 A 中的值是动态的,那么我们可以这样做:

=DPRODUCT(OFFSET(A1,0,0,SEQUENCE(ROWS(A2#),,2)),1,$ZZ:$ZZ)

虽然还不是所有人都可以使用,但我们可以使用 SCAN()

A1中的公式:

=SCAN(1,{10,8,3,4,5},LAMBDA(a,b,a*b))
  • 第一个参数是我们的起始值,意味着嵌套LAMBDA()中的第一个计算是'1*10'。
  • 第二个参数都可以采用一维和二维数组(书面或范围参考)。
  • 第三个参数是嵌套的LAMBDA(),我们的递归函数的结果将用于第二次计算; '10*8'。第三……等等。等等
  • 在上面的示例中,垂直数组被溢出,但是当使用水平输入时,这显然会导致水平溢出输出。当使用二维数组时,结果会溢出二维数组。

这里有很多有趣的答案。但是,如果求和很容易,为什么不对要相乘的数字取对数,将这些对数相加,然后计算总和的指数 return 与原始数字的乘积。

即利用 ln(a * b) = ln(a) + ln(b)