VBA内存问题,同时指定数组的范围

我的目的是分配一个Excel范围的单元格与二维variables数组的值。

分配工作正常,但是我面对一个内存问题(泄漏):当我启动Excel时,这个过程需要或多或less的22个内存。 运行下面的代码(创build一个新的工作簿,分配范围,closures工作簿而不保存)后,该过程需要33 Mo的RAM。

有没有人有一个想法,我在做什么错了?

问候,亚历山大

这里的代码

Option Explicit Sub test() Dim nLines As Long Dim xSize As Long Dim j As Long Dim i As Long 'Creating New Empty Workbook Application.Workbooks.Add Range("A1").Select Application.ScreenUpdating = False nLines = 10000 xSize = 200 Dim myRange As Range Dim myArray() As Variant ReDim myArray(1 To nLines, 1 To xSize) 'Assigning some values For j = 1 To nLines: For i = 1 To xSize: myArray(j, i) = i * 4 / 3# Next i Next j Set myRange = Range(ActiveCell, ActiveCell.Offset(nLines - 1, xSize - 1)) myRange .Value = myArray 'Cleaning up Erase myArray Set myRange = Nothing 'Closing workbook without saving Application.ActiveWorkbook.Close (False) Application.ScreenUpdating = True End Sub 

VBA不是C,不要指望能够以任何方式控制Excel的内存占用。 Excel对内存pipe理本身并不擅长,而且通常情况下,您正在运行macros,或者您在这些macros中所做的事情几乎无法控制Excel决定分配多less内存,或者是否曾经决定再次释放它。

话虽如此,你可以在你的代码中做一些事情来减less混乱。

  1. Range("A1").Select

    在Excel中操作它们之前select单元格通常是不好的做法。 你需要select一个单元格的唯一时间是如果你正在向macros观的观众展示一些东西。 此外,这段代码实际上可能会导致在某些版本的Excel中出现问题,因为您刚刚添加了一个工作簿,没有什么可以告诉Excel什么工作簿,以及该工作簿中应该select哪个工作表。 你应该完全删除这个代码(它不会影响你的逻辑)。

  2. Set myRange = Range( ...

    这段代码是没有必要的,因为你只用范围执行一个动作。 您根本不需要创buildmyRangevariables,因此您也不必担心将其设置为无效,或者更重要的是,将其设置为无,实际上并不能实现任何内存。

  3. ActiveCellApplication.ActiveWorkbook

    同样,这些基于对“Select”和“ActiveWorkbook”的调用的非限定引用并不明确,并且可能导致不可靠的行为,特别是当用户在同一个excel实例中打开其他电子表格时。 您最好存储一个对您在开始时添加的工作簿的引用。

总而言之,我会将您的代码更改为:

 Sub test() Const nLines As Long = 10000, xSize As Long = 200 Dim i As Long, j As Long Dim newWorkbook As Workbook Application.ScreenUpdating = False 'Creating New Empty Workbook Set newWorkbook = Application.Workbooks.Add 'Assigning some values Dim myArray(1 To nLines, 1 To xSize) As Double For j = 1 To nLines: For i = 1 To xSize: myArray(j, i) = i * 4 / 3# Next i Next j With newWorkbook.Sheets(1) .Range(.Cells(1, 1), .Cells(nLines - 1, xSize - 1)).Value = myArray End With 'Closing workbook without saving newWorkbook.Close (False) 'Cleaning up Erase myArray Set newWorkbook = Nothing Application.ScreenUpdating = True End Sub 

结束语:

除了VBA编码课程 – 请注意,打开一个新工作簿的行为将要求Excel分配大量新的内存 – 不仅仅是创build临时数组。 这是即使在closures新的工作簿之后仍然可以免费或保留的内存。 这种增长是不会有的。 请注意,Excel的内存占用量不仅与您当前的工作簿相关联,而且还与实例(支持多个工作簿)的整个生命周期以及它们的备份,优化的计算树,撤消历史等有关。比较一个新启动的excel实例的脚印和刚刚完成的“一堆东西”的脚印。

另外请注意,仅仅因为Excel并不决定释放内存,它并不会使其泄漏。 Excel可能已将内存分配给可回收/可重复使用的对象,这些对象将与您决定打开的下一个工作簿一起重新填充。 反复重新运行代码可能会导致内存每次less量增加,但Excel可以跟踪一定数量的实例操作历史logging。

为了说明我的观点,下面是Excel(2007)在打开一个新实例时的内存占用情况,并且一次运行您的代码9次,然后再运行40次。

在这里输入图像说明

这不是你的代码的错,责任不在你担心,如果你的业务用户担心,他们不应该select旧版本的Excel作为他们的目标开发平台。