我在网上搜索得非常广泛,但没有找到任何类似的经历。有什么想法吗?
我在VBA中有一个简单的子程序来更改控制单元。该控制单元由另一张表中的公式使用。随着代码更改控件值,Excel使用越来越多的内存达到了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 bug吗?
答案 0 :(得分:0)
我对你的问题进行了更多的研究。构建运行和函数的方式必须创建许多中间范围:
=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处理环境,除了美容用途之外,我无法理解为什么它在这里需要。