Excel索引与偏移/间接 – 我不明白为什么偏移/间接在这种情况下更快

我有一个工作簿设置第一个选项卡包含参数列表。 每一列是不同实例的一组参数。

然后我有一个实例的模板工作表,用户使这个模板的许多副本。 模板所做的一件事就是dynamic地从第一张表中拉出参数。 用户input一个列号(1到n),该列中的参数从第一个工作表拉出,用于该实例。 然后该实例使用这些参数运行数十万行计算。

参数表

在这里输入图像说明

示例实例

在这里输入图像说明

我的问题似乎与波动有关。 对于大量实例,如果使用偏移或间接来获取参数,则工作簿中任何单元格中的任何更改都会导致在每个实例工作表上重新检索参数,因此每次都会重新计算每个工作表的整体,每当进行更改时,将工作簿冻结约3秒钟。

我以为我可以通过使用索引来减轻这一点。 每个工作表参数引用包含该参数的第一个工作表上的行,并将列号作为索引参数提取。 这解决了导致重新计算的任何变化的问题。 现在只有参数范围的变化会导致重新计算,但由于某些原因,情况会更糟糕。

现在,更改工作簿中的随机单元格不再导致整个事情在重新计算时冻结3秒钟,但更改参数范围中的相关单元格将导致每个表单重新计算,并需要大约10秒钟。 为什么这个方法慢得多。 在技​​术上应该像以前一样做相同的事情,只是在相关参数改变的时候。

有什么办法可以设置它,以便当前面板上的参数发生变化时,只有受该参数影响的纸张才会重新计算?

解决scheme

我考虑过涉及VBA的复杂解决scheme,于是复制模板实例监视其“实例号”单元。 当它被更改时,VBA代码可以将相应的参数复制到工作表并在这里硬拷贝这些值。 我还需要VBA监视主参数表上的更改事件。 当任何东西被改变时,它将不得不检查列号,迭代所有的模板,并重新复制值,如果该实例编号被引用。 我想避免这个解决scheme的原因是使VBA保持不变,但如果没有办法让excel的重新计算变得更加智能化,那么可能有必要这样做。

此问题是由使用索引function将参数#值填充到实例工作表上引起的。

当您在任何实例行的Main更改Param 1的值时,范围将被标记为已更改。 由于每个实例工作表参考此范围的参数1值查找,所有param 1值都标记为已更改。 然后,在所有工作表上引用Param 1所有Iteration #公式都被标记为已更改。

不知道这会对工作簿devise产生什么影响,但考虑更改索引查找以指导单元格引用。 例如在实例1的单元格D3: =Main!B2

在准备这个答案时,我设置了一个带有工作簿事件的文本来报告表单重新计算

 Private Sub Workbook_SheetCalculate(ByVal Sh As Object) MsgBox "Calc Sheet " & Sh.Name End Sub 

我使用Index,Offset和其他方法做了各种查找的实验,但找不到一个不会导致所有表单重新计算(不是详尽的search,所以其他人可能会提供一个解决scheme)。 我发现的唯一一个不会导致所有表单计算的是直接单元格引用

帮助build立维护实例工作表参数引用的VBA例程可能是为了…

这是一个旧的Excelmacros技巧仍然有效:

  • closures自动重新计算
  • select您要重新计算的所有单元格
  • 使用replace函数replace = with =
  • 这只是强迫这些特定的细胞重新计算。

把这个logging成一个macros是非常容易的,并且定期进行。