VBA 变量,对象和内存

huangapple go评论98阅读模式
英文:

VBA Variable, Object & Memory

问题

  1. 变量中包含大字符串、大量数据(如数组)或对象是否会使用大量内存?
  2. 如果过程完全执行,它们(所有局部变量和对象)是否也会完全释放内存?

有时在复制范围中执行操作时会出现错误。当我检查代码时,它说“ws”为空(未设置为“Sample”工作表)。

过程“CreateSheet”和“CopySomeRange”都将“ws”用作对象。这是否有任何联系?

英文:

There is a question about variable in vba:

  1. Is variable with huge string or huge amount of data (like array) or object will use alot of memory?
  2. If the procedure completly executed, are they (all local variables and objects) also completely released from the memory?

Another sample, I have some code:

Sub Routine()
   'Step 1
   Call CreateSheet
   Call CopySomeRange
End Sub

Sub CreateSheet()
    Dim ws As Worksheet
    Set ws = Thisworkbook.Add
    With ws
        .Name = "Sample"
        '... some activity here...
    End With
End Sub

Sub CopySomeRange()
    Dim ws As Worksheet
    Set ws = Thisworkbook.Worksheet("Sample")
    With ws
        .Range("A1:A100").Copy .Range("B1:B100") '>>> Sometimes error
    End With
End Sub

Sometimes my action in copy range get error. When I inspect the code, It says ws is empty (not set as "Sample" worksheets).

Both procedure CreateSheet and CopySomeRange are used ws as object. Is that any connection?

答案1

得分: 1

a) ws 是你两个程序中的局部变量。它们是完全独立的。

b) 局部变量在程序段结束时销毁(静态变量除外)。在 ws 的情况下,只有指向工作表的引用会被销毁,而不是工作表本身。

c) 使用 new 关键字创建的对象会在没有引用时被销毁。因此,如果你在程序段中创建一个对象并将其分配给局部变量,然后将对象引用复制到一个在子例程结束后仍然存在的变量中,例如全局变量,作为函数的结果,或者作为参数传递,那么该对象不会被销毁。VBA 的垃圾回收功能非常好,你几乎找不到关于它的任何信息,它只是正常工作。

d) 在你的代码中,你想要创建一个新的 Excel 工作表。这个工作表由 Excel 处理,而不是 VBA,VBA 无法销毁它(它只能调用删除方法来请求 Excel 删除并因此销毁它)。

e) 对象和数组占用的内存大致符合你预期的数量。1000*1000 个 Double 类型的数组占用 8MB(1 百万次 8 字节),再加上非常小的开销。字符串略微复杂一些,但作为一个经验法则,现在你不必担心内存消耗。

有关内存的更多信息,请查看 https://nolongerset.com/memory-management-in-vba/


查看你的代码,至少有 2 个问题。这两个问题已经引发了编译时错误,因此你的代码根本不会被执行。

在 Sub CreateSheet 中,创建新工作表的行是

Set ws = ThisWorkbook.Worksheets.Add

在 Sub CopySomeRange 中,将工作表引用分配给变量的行是

Set ws = ThisWorkbook.Worksheets("Sample")

假设这些错误已经被纠正,我看不出会导致 ws 变为 Nothing 的任何原因。

英文:

a) ws is a local variable in both of your routines. They are completely independent.

b) Local variables are destroyed when the code of a routine finishes (with the exception of static variables). In case of ws, this is only the reference pointing to the worksheet, not the worksheet itself.

c) Objects that are create with the new keyword are destroyed when there is no more reference to it. So if you create an object in a routine and assign it to a local variable, then copy the object reference into a variable that survives the end of the subroutine, eg a global variable, as a result of a function, into a variable that is passed as parameter, the object is not destroyed. The VBA garbage collection is so good that you hardly find any information about it, it simply works.

d) In your code, you want create a new Excel worksheet. This worksheet is handled by Excel, not VBA, VBA cannot destroy it (it can only call the delete-method to ask Excel to delete and therefore destroy it).

e) Objects and Array uses more or less the amount of memory you would expect. An array of 1000*1000 Doubles takes 8mb (1 million times 8 bytes) of data, plus a very small overhead. Strings are a little bit more complicated, but as a rule of thumb, you don't have to take care about memory consumption nowadays.

For more about memory, have a look to https://nolongerset.com/memory-management-in-vba/


Looking at your code, there are (at least) 2 problems. Both raise already a compile time error, so your code is not executed at all.

In Sub CreateSheet, the line to create a new sheet would be

Set ws = ThisWorkbook.Worksheets.Add

In Sub CopySomeRange, the line to assign a worksheet reference to a variable is

Set ws = ThisWorkbook.Worksheets("Sample")

Assuming that those errors are corrected, I don't see any reason that could cause ws to be Nothing.

答案2

得分: 0

Q1. 变量包含大量字符串、大量数据(如数组)或对象会使用大量内存吗?

A. 是的,但对于现代计算机来说,这不应该是问题。

Q2. 如果过程完全执行,所有局部变量和对象是否也会完全释放内存?

无论过程是否完全执行,变量最终都会超出范围 - 这个参考链接更好地解释了这一点理解范围和可见性 - Microsoft Learn

Q: 过程CreateSheet和CopySomeRange都使用ws作为对象。这之间有什么联系吗?

不,它们之间没有联系。请参考上面的链接。

"有时候在复制范围的操作中会出错。"

我不明白这是如何可能的,因为你的代码根本不会运行。请参考@VBasic2008的评论。它有多个语法错误。

英文:

Q1. Is variable with huge string or huge amount of data (like array) or object will use alot of memory?

A. Yes, but that shouldn't be a problem with modern computers

Q2. If the procedure completly executed, are they (all local variables and objects) also completely released from the memory?

It doesn't matter whether the procedure is completely executed or not, the variables will at some stage go out of scope - this reference explains it better Understanding scope and visibility - Microsoft Learn

Q: Both procedure CreateSheet and CopySomeRange are used ws as object. Is that any connection?

No - there is no connection. See the link above.

> "Sometimes my action in copy range get error. "

I don't see how that is possible as your code will not run at all. See the comment from @VBasic2008. It has multiple syntax errors

huangapple
  • 本文由 发表于 2023年5月11日 15:14:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/76224985.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定