我的目的是为Excel范围的单元格指定二维变量数组的值。
该分配工作正常,但我遇到了内存问题(泄漏):当我启动Excel时,该过程需要或多或少22 Mo的Ram。运行以下代码(创建新工作簿,分配范围,关闭工作簿而不保存)后,该过程需要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
答案 0 :(得分:8)
VBA不是C,不依赖于能够以任何方式控制Excel的内存占用。 Excel在内存管理方面本身并不擅长,而且往往是你运行宏或你在这些宏中做的事情几乎无法控制Excel决定分配多少内存,或者它是否曾经决定再次释放它。
话虽如此,您可以在代码中执行一些操作来尝试减少其混乱。
Range("A1").Select
在Excel中对单元格进行操作之前选择单元格通常是不好的做法。您需要选择单元格的唯一时间是您向宏的查看器说明内容。此外,这个代码实际上可能会导致excel的某些版本出现问题,因为你刚刚添加了一个工作簿,而且没有什么可以告诉excel什么工作簿,以及它应该选择的工作表中的工作表。您应该完全删除此代码(无论如何它都不会影响您的逻辑)。
Set myRange = Range( ...
此代码不是必需的,因为您只对范围执行一个操作。您根本不需要创建myRange变量,因此您也不必担心将其设置为空,或者更重要的是 - 将其设置为空的这一事实实际上并没有实现任何内存方式。< / p>
ActiveCell
和Application.ActiveWorkbook
同样,基于对“选择”和“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分配大量新内存 - 而不是创建临时数组。即使在关闭新工作簿之后,这也是可以自由或保持存在的内存。这些增加将无法解决。请注意,Excel的内存占用量与您当前的工作簿无关,它是实例的整个生命周期(支持多个工作簿),以及它们的备份,优化的计算树,撤消历史记录等。它真的没有意义将新推出的excel实例的足迹与刚刚完成的“一堆东西”的实施例进行比较。
另请注意,仅仅因为Excel不决定释放该内存,它不会使其成为泄漏。 Excel可能已在可循环/可重用对象中分配内存,这些对象将使用您决定打开的下一个工作簿重新填充。反复重新运行代码可能会导致每次内存略有增加,但Excel也可以跟踪一定量的实例操作历史记录。
To(传闻)说明了我的观点,这是Excel(2007)在打开一个新实例,运行代码一次,再运行9次,然后再运行40次之后的内存占用情况。
这不是您的代码的错,您不担心责任,如果您的业务用户担心,他们不应该选择旧版本的Excel作为他们的目标开发平台。