我在网上搜索了很多,但没有找到任何类似的经历。有任何想法吗?
我在 VBA 中有一个简单的子程序,可以更改控制单元。此控制单元格由另一个工作表中的公式使用。随着代码更改控制值,Excel 使用越来越多的 ram 到 excel 停止的地步。
基本上我有一个有 3000 行和 330 列的工作表设置。在工作表的每个单元格中,填充了以下相同的公式:
=sum(sheet1!F8:INDEX(sheet1!F8:F$3000,Control!$D$1))
所以在单元格
A1
你会得到上面的公式,在单元格中说 B1
你将会拥有:=sum(sheet1!F**9**:INDEX(sheet1!F9:F$3000,Control!$D$1))
代码改变的控制值是
Control!$D$1
因此将控制从 2 更改为 4 将导致计算 sheet1 中从 2 到 4 个连续行的运行总和。请注意,代码首先在控制单元 (200) 中设置了一个高值,然后一直下降到 2。因此,内存使用量的增加确实让我感到困惑。
我的代码是:
For i = 200 To 1 Step -1
Application.Calculation = xlCalculationManual
ClearClipboard 'sets cutcopymode to false
Range("Control!d1").Value = i
Application.Calculation = xlCalculationAutomatic
Next i
最后,我尝试了以下替代方案,但没有一个适合我:
这是一个excel错误吗?
最佳答案
我对你的问题做了更多的研究。您的运行总和函数的构建方式必须创建许多中间范围:=sum(sheet1!F8:INDEX(sheet1!F8:F$3000,Control!$D$1))
一、sheet1!F8:F$3000
,第二个是 INDEX() 函数的结果,第三个是 SUM() 的参数。
相反,我建议使用 OFFSET() 函数只构建一个范围(最低限度)。它适用于该任务,因为控制参数是一个标量,并且 OFFSET() 从一个范围和标量创建一个新范围。
然后运行总和是=SUM(OFFSET(sheet1!$A$1;ROW()-1;COLUMN()-1;Control!$D$1;1))
其中控制值仅设置要求和的范围的大小。在我使用 2000 x 14 单元和 200 个循环的测试中,没有观察到内存消耗的增加。由于这两种方法(INDEX() 和 OFFSET())对于这样大小的工作表都非常快,因此我无法对计算时间做出任何假设(但请参阅下面的提示)。
我添加了 ROW() 和 COLUMN() 函数以使公式自我调整 - 总和的起始地址将与公式所在的单元格的地址相同。这样,工作表上的所有公式都完全相同并且不必根据它们的位置进行更改。
至于运行时,我建议您不要更改计算模式(即自动)。我注意到每次更改模式都会产生几秒钟的巨大开销。更改控制单元后,所有相关单元都必须计算一次,并且将模式设置为手动不会改变这一点。
最后,如果您使用原始数据尝试此公式,请测试是否遗漏了 ClearClipboard
命令将产生任何影响。最终它将不得不调用一个 Windows 函数,从而离开 Excel 处理环境,我不明白为什么这里需要它,除非是为了美观。
关于vba - Excel VBA重复更改控制单元占用内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25104552/