停止运行宏后Excel冻结

1tu0hz3e  于 2022-12-24  发布在  其他
关注(0)|答案(1)|浏览(132)

让我解释一下。
我在excel中有一个状态相似性实现,其中一个叫做state的模块在顶层包含了很多公共字典。
我用大量的对象类填充每个字典-大多数只是来自工作表的数据。简单的练习。问题开始后,宏已经正常工作,它离开所有这些字典在内存中,在任务管理器中Excel占用从2GB-这也是正常的。

    • 状态模块-独立模块**
public Dict1 as Dictionary
public Dict2 as Dictionary

'Persists sheets data
public Dict3 as Dictionary
public Dict4 as Dictionary

'For persists renaming some objs
public Dict5 as Dictionary
public Dict6 as Dictionary
public Dict7 as Dictionary
    • 类模块-数据接口示例-clsData**
Public Name as string
Public Prop1 as string

Public Prop2 as Integer
Public Prop3 as Date
Public Prop4 as string

Public Value as double

下面的代码只是一个stackoverflow的例子,在我的模块中,我从一个带有Range. CurrentRegion的工作表中获取数据,并迭代lbound到ubound。

    • 另一个数据采集器**
Function DataGrabberFromSheet(ByRef CurrentDict as Dict) as String

Dim i as long
Dim data as variant

Dim DataObj as clsData

set CurrentDict = New Dictionary  <--- That's recreate dict obj and start clear old data for some how, but i do not need that anymore. 

data = Sheet1.Range("A1:Q5000").Values

for i = 1 to 5000

  set DataObj = new clsData

  DataObj.Name = data(i, 1)
  DataObj.Prop1 = data(i,2)

  ...

  call CurrentDict.add(DataObj.Name, DataObj)
next

'For logging, it just an example:
If Success then
  DataGrabberFromSheet = "Success"
else
  DataGrabberFromSheet = "Bad"
endif

end Function

所以我决定在debbuger中按下停止按钮来强制停止程序。此时,excel冻结了很长一段时间,因为我已经在RAM中有50个或更多这样的字典,其中一些每个字典有200k个元素。有时需要大约300秒,有时不知何故它会立即清除它。
旧数据被逐项删除,我想,但我不再需要那些数据了。excel能不能跳过那部分内存,重写一个新数据。
如何在宏重新运行时立即重新定义这些字典,而不必等待漫长的清理过程?此时不再需要数据
经典的互联网方法优化没有解决这个问题:

Application.Calculation = xlCalculationManual
Application.ScreenUpdating = False
...
hmae6n7t

hmae6n7t1#

我认为这是VBA的一个已知问题-清除大量对象需要很长时间:而不管它们是存储在字典、集合还是数组中。
例如:

Dim arr() As clsData

Sub Tester()
    Const NUM As Long = 120000
    Dim i As Long, obj As clsData, t
    
    t = Timer
    Debug.Print "---------"
    ReDim arr(1 To NUM)
    Debug.Print "Reset", Timer - t
    
    t = Timer
    For i = 1 To NUM
        Set obj = New clsData
        obj.Prop1 = "Item" & i
        obj.Prop2 = "Item" & i
        obj.Prop3 = "Item" & i
        obj.Prop4 = "Item" & i
        Set arr(i) = obj
    Next i
    Debug.Print "Fill", Timer - t
    
End Sub

其中,clsData仅为:

Public Prop1
Public Prop2
Public Prop3
Public Prop4

第一次运行的输出(在VBE中点击"停止"后):

Reset          0 
Fill           0.34375

第二次运行:

Reset          8.601563   <<<<<
Fill           0.3554688

相关问题