引用前一行的 ArrayFormula? (循环依赖错误)

ArrayFormula that refers to the previous row? (Circular dependency error)

我遇到了一个看起来很常见的要求:包含先前行的数组公式计算。问题似乎是数组公式中的所有单元格都被一次求值,因此它认为存在循环依赖,并给出该错误。

我模拟了一个 toy example on Google Spreadsheet,您应该可以看到并发表评论。 (我不允许编辑权限以防止破坏。)

看起来像这样,所有内容都在行 2 中,项目符号 1、2、3、4 指的是列 ABC ,D分别为:

  1. 'Change' - 手动输入为空白
  2. 'Ex. interest' - =ARRAYFORMULA(IF(ROW(B2:B)>2, OFFSET(D2:D, -1, 0) + A2:A,))
  3. 'Interest rate' - 手动输入为空白
  4. 'Balance' - =ARRAYFORMULA(IF(ROW(D2:D)=2, 0, B2:B*(1+C2:C)))

想法是让复利(利率可能可变)和每行 plus/minus 资本变化的选项,但是,单元格 B2D2 (第 2、4 点)错误 #REF,悬停时报告 'circular dependency'.

我已经尝试了所有我能想到的方法:OFFSETINDIRECTD1:D(而不是 2),甚至是辅助列,除了请参考 D 的前一行(这只是导致了三列循环依赖)。

如何让 'ex. interest' 列引用数组公式中前一行的 'balance' 列而不导致此错误?

类似的问题通过行上的 SUMIF 来解决这个问题,条件是该行小于数组公式中的 'current' 行。 我看不出这对我的情况有用,因为我需要将整个 运行 总和乘以每一步的利息。 我试过 SUMIF(... "="&DATE(...) ...) 引用前一行;这在帮助列中工作以打印抵消余额,但尝试使用它(根据下面的迭代计算)就像它是零一样。

在@JackBrown 的建议下,我启用了消除循环依赖错误的迭代计算,但它仍然不起作用 - 第二个填充的行从前一行获得 0 的值,尽管前一个具有非零值的行。就好像它在早期迭代中获取了值,并且没有在更改时更新。

Excel

在excel中使智能table并使用公式:

=If(row()=2,A2*(1+B2),(A1+C1)*(1+B2))

请在此处下载示例文件: https://drive.google.com/file/d/0B79ClRnKS87QTTR5VDBld0plajg/view?usp=sharing


Google 张

为了解决您的问题,我进行了研究。 简短回答:我不能这样做,我相信那是不可能的。

背景

我将案例简化为通过不断变化的利率寻找未来利率值的任务:

Rate+   Recursive formula for rate
1.00%   101.0000%    =(1+A2)
1.50%   102.5150%    =B2*(1+A3)
1.10%   103.6427%    =B3*(1+A4)
1.10%   104.7827%    =B4*(1+A5)

然后我手工制作了一个数组以获得相同的结果并得到了这个:

={1+A2;
  1+A2+(1+A2)*A3;
  1+A2+(1+A2)*A3+(1+A2+(1+A2)*A3)*A4;
  1+A2+(1+A2)*A3+(1+A2+(1+A2)*A3)*A4+(1+A2+(1+A2)*A3+(1+A2+(1+A2)*A3)*A4)*A5}

如你所见,参数的数量增长非常快:

1  = 2 ^1 - 1   1+B2         
3  = 2 ^2 - 1   1+B2+(1+B2)*B3 
7  = 2 ^3 - 1   1+B2+(1+B2)*B3+(1+B2+(1+B2)*B3)*B4   
15 = 2 ^4 - 1   1+B2+(1+B2)*B3+(1+B2+(1+B2)*B3)*B4 + ... 

要计算最后一行的结果,我们需要 2^n - 1 个变量:

  • 第 32 行的数字是 4 294 967 295!

这就是为什么即使启用 Iterative calculation= On

arrayformula 也无法处理计算的原因

解决方法 但这对于递归函数或脚本来说是非常简单的任务,因为它们可以记住最后找到的值。所以我建议编写脚本并将其用作自定义数组公式:

function futureValue(values, rates) {

  var result = [];
  var resultCurrent = 0;

  for (var i = 0, len = values.length; i < len; i++)
  {
    resultCurrent = (+values[i] + resultCurrent) * (1 + +rates[i]);
    result.push(resultCurrent);
  }

  return result;

}

链接:

  1. Sample file 脚本正常工作
  2. Guide on custom functions