引用前一行的 ArrayFormula? (循环依赖错误)
ArrayFormula that refers to the previous row? (Circular dependency error)
我遇到了一个看起来很常见的要求:包含先前行的数组公式计算。问题似乎是数组公式中的所有单元格都被一次求值,因此它认为存在循环依赖,并给出该错误。
我模拟了一个 toy example on Google Spreadsheet,您应该可以看到并发表评论。 (我不允许编辑权限以防止破坏。)
看起来像这样,所有内容都在行 2
中,项目符号 1、2、3、4 指的是列 A
、B
、C
,D
分别为:
- 'Change' - 手动输入为空白
- 'Ex. interest' -
=ARRAYFORMULA(IF(ROW(B2:B)>2, OFFSET(D2:D, -1, 0) + A2:A,))
- 'Interest rate' - 手动输入为空白
- 'Balance' -
=ARRAYFORMULA(IF(ROW(D2:D)=2, 0, B2:B*(1+C2:C)))
想法是让复利(利率可能可变)和每行 plus/minus 资本变化的选项,但是,单元格 B2
和 D2
(第 2、4 点)错误 #REF
,悬停时报告 'circular dependency'.
我已经尝试了所有我能想到的方法:OFFSET
、INDIRECT
、D1: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;
}
链接:
我遇到了一个看起来很常见的要求:包含先前行的数组公式计算。问题似乎是数组公式中的所有单元格都被一次求值,因此它认为存在循环依赖,并给出该错误。
我模拟了一个 toy example on Google Spreadsheet,您应该可以看到并发表评论。 (我不允许编辑权限以防止破坏。)
看起来像这样,所有内容都在行 2
中,项目符号 1、2、3、4 指的是列 A
、B
、C
,D
分别为:
- 'Change' - 手动输入为空白
- 'Ex. interest' -
=ARRAYFORMULA(IF(ROW(B2:B)>2, OFFSET(D2:D, -1, 0) + A2:A,))
- 'Interest rate' - 手动输入为空白
- 'Balance' -
=ARRAYFORMULA(IF(ROW(D2:D)=2, 0, B2:B*(1+C2:C)))
想法是让复利(利率可能可变)和每行 plus/minus 资本变化的选项,但是,单元格 B2
和 D2
(第 2、4 点)错误 #REF
,悬停时报告 'circular dependency'.
我已经尝试了所有我能想到的方法:OFFSET
、INDIRECT
、D1: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
解决方法 但这对于递归函数或脚本来说是非常简单的任务,因为它们可以记住最后找到的值。所以我建议编写脚本并将其用作自定义数组公式:
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;
}
链接: