我有以下数组公式,用于计算特定年份特定股票的回报:
=IF(AND(NOT(E2=E3),H2=H3),PRODUCT(IF($E$2:E2=E1,$O$2:O2,""))-1,"")
但是因为我在第50,000行遇到500,000行条目后,我从Excel收到错误,指出我的机器没有足够的资源来计算值。
如何优化功能以使其真正起作用?
E列是指用于检查股票的年份和股票价值的计数器。如果year与前一个值不同,则函数将输出1
。当股票名称发生变化时,它也会输出1
。例如,你可能有1993年的值,下一个值也是1993,但是库存的名称是不同的,所以很明显应该重新计算回报,我使用1
作为指示。
然后我有另一列运行那些1
的累积和。当遇到前一列中的新1
时,我将1
添加到正在运行的总计中,并保持打印相同的数字,直到我观察到新的数字。这样可以使用数组函数,如果包含运行总值(E列)的列具有与之前不同的下一个值,则使用我在SUMIF上的扭曲但使用PRODUCT IF。这将返回所有相应的运行总E列值的乘积。
答案 0 :(得分:1)
我认为,低效率的来源是稳定增长,必须检查的细胞数量的行数才能评估每个连续的数组公式。例如,在行50,000中,您的公式必须检查其上方所有行中的单元格。
我是阵列公式的忠实粉丝,所以我很难说这个,但我不会这样做。而是使用其他列在每行中计算返回所需结果所需的公式部分。通过采用这种方法,您可以利用Excel非常有效的重新计算引擎来计算所需的内容。
对于最终产品,从辅助列中的累积运行产品计算,并且当上面一行中的列P包含数字时,该值将重置为现在在列O中的值。这种方法更多地是本地的"并避免依赖大量细胞的公式。
我意识到文字并不是描述这一点的最佳语言,而我糟糕的写作技巧可能会增加挑战,所以如果需要更多细节,请告诉我。
有趣的问题,谢谢。
答案 1 :(得分:0)
我可以建议一个非常快速且非常脏的vba吗?像下面这样的东西。显然,在运行此文件之前,请备份您的文件。这假设您要从第13行开始计算。
Sub calculateP()
'start on row 13, column P:
Cells(13, 16).Select
'loop through every row as long as column A is populated:
Do
If ActiveCell(1, -14).Value = "" Then Exit Do 'column A not populated so exit loop
'enter formula:
Selection.FormulaR1C1 = _
"=IF(AND(NOT(RC[-11]=R[1]C[-11]),RC[-8]=R[1]C[-8]),PRODUCT(IF(R[-11]C5:RC[-11]=R[-1]C[-11],R2C15:RC[-1],""""))-1,"""")"
'convert cell value to value only (remove formula):
ActiveCell.Value = ActiveCell.Value
'select next row:
ActiveCell(2, 1).Select
Loop
End Sub
对不起,肯定是对你来说不是一个很好的答案......事实上,使用范围可以更优雅地实现这种方法......但是,快速而肮脏的方法可能对你有所帮助在临时??