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

时间:2017-05-10 18:06:23

标签: excel google-sheets array-formulas

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

我嘲笑了toy example on Google Spreadsheet你应该能够看到和评论的内容。 (我不允许编辑访问以防止破坏。)

看起来像这样,所有内容都在行2中,而项目符号1,2,3,4引用了列ABC,{分别为{1}}:

  1. '更改' - 手动输入为空白
  2. '实施例。兴趣' - D
  3. '利率' - 手动输入的空白​​
  4. '余额' - =ARRAYFORMULA(IF(ROW(B2:B)>2, OFFSET(D2:D, -1, 0) + A2:A,))
  5. 这个想法是让兴趣化合物(可能具有可变利率)和每行的正/负资本变化选项,但是,单元格=ARRAYFORMULA(IF(ROW(D2:D)=2, 0, B2:B*(1+C2:C)))B2(第2点, 4)错误D2,并在悬停时报告'循环依赖'。

    我已经尝试了我能想到的所有内容:#REFOFFSETINDIRECT(而不是D1:D),甚至是帮助列,除了引用之外什么都不做2的前一行(它只是引起了三列循环依赖)。

    我怎么能拥有'前。 interest'列引用数组公式中前一行的'balance'列而不会导致此错误?

    类似的问题用行D来解决这个问题,条件是行数小于数组公式中的'当前'行。 我看不出这可能适用于我的情况,因为我需要将整个运行总和乘以每一步的兴趣。我尝试SUMIF来引用之前的单个行;这在辅助列中工作以打印偏移平衡,但尝试使用它(对于每个下面的迭代计算)只是表现得像零。

    在@ JackBrown的建议中,我启用了迭代计算,它解决了循环依赖性错误,但是它仍然不起作用 - 第二个填充的行从前一行获得值SUMIF(... "="&DATE(...) ...),尽管上一行有非零值。好像它在早期迭代中占用了值,并且没有更新更新。

1 个答案:

答案 0 :(得分:3)

的Excel

在excel中制作智能表并使用公式:

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

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

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也无法处理计算

<强> Workaroud 但这对于递归函数或脚本来说非常简单,因为它们可以记住最后找到的值。所以我建议编写脚本并将其用作自定义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