VBA:差异宣告一个新的对象有两种方法? (试图理解为什么我的解决方案的工作原理)我的、有两种、工作原理、差异

2023-09-08 10:54:59 作者:知足的幸福

我创建一个循环内的新对象,并添加该对象的集合;但是当我以后回读集合,它总是充满完全用我所添加的最后一个对象。我想出了解决此两种方式,但我只是不明白为什么我的初步实施错了。

I was creating a new object within a loop, and adding that object to a collection; but when I read back the collection after, it was always filled entirely with the last object I had added. I've come up with two ways around this, but I simply do not understand why my initial implementation was wrong.

原文:

Dim oItem As Variant
Dim sOutput As String
Dim i As Integer

Dim oCollection As New Collection
For i = 0 To 10
    Dim oMatch As New clsMatch
    oMatch.setLineNumber i
    oCollection.Add oMatch
Next
For Each oItem In oCollection
    sOutput = sOutput & "[" & oItem.lineNumber & "]"
Next
MsgBox sOutput

这导致每一个行号为10;我是显然不是创建新的对象,但使用的同一个,而不是每一次通过循环,尽管声明作为循环内

This resulted in every lineNumber being 10; I was obviously not creating new objects, but instead using the same one each time through the loop, despite the declaration being inside of the loop.

所以,我说设置oMatch =无立即下一页前行,这解决了这一问题,它现在是0分至10因此,如果旧的对象被显式销毁,那么它愿意创建一个新的?我本来以为通过循环下一次迭代将导致循环中声明不被破坏任何东西由于范围有多大?

So, I added Set oMatch = Nothing immediately before the Next line, and this fixed the problem, it was now 0 to 10. So if the old object was explicitly destroyed, then it was willing to create a new one? I would have thought the next iteration through the loop would cause anything declared within the loop do be destroyed due to scope?

好奇,我想声明一个新的对象的另一种方式:昏暗oMatch作为clsMatch:设置oMatch =新clsMatch 。这也导致在0至10。

Curious, I tried another way of declaring a new object: Dim oMatch As clsMatch: Set oMatch = New clsMatch. This, too, results in 0 to 10.

任何人都可以向我解释为什么第一个实施错了?

Can anyone explain to me why the first implementation was wrong?

推荐答案

芬克的回答得到你的主要问题吧,这是你的第一个循环是增加多次引用clsMatch的同一个实例到您的收藏。我就详细说明为什么你的修复工作。

Fink's answer gets your main problem right, which is that your first loop is adding multiple references to the same instance of 'clsMatch' to your collection. I'll just elaborate on why your fix works.

在VBA,这样一行:

Dim c As New Collection

实际上并没有创建一个新的集合。在'点心'语句是永远只是一个声明。想想作为新的形式作为简写这样的:

doesn't actually create a new collection. The 'Dim' statement is always just a declaration. Think of the 'As New' form as being shorthand for this:

Dim c As Collection
'...

'(later, when you're about to use 'c')

If c Is Nothing Then
    Set c = New Collection
End If

'...

这就是为什么通过设置包含它'没有'正在变摧毁你的参考。 [注:给任何人编辑这样说不 - 改变答案的意义,使它不正确。请仔细阅读原来的问题。在OP发现,设置参数为空的没有的工作,而我explaing的为什么的是这样的话,当循环回来绕到oMatch.setLineNumber行,VBA有益为你oMatch'变量是指创建clsMatch的新实例,然后在您的收藏得到了多个不同的实例。

That is why destroying your reference by setting the variable that contained it to 'Nothing' was working. [NOTE: to whomever edited this to say "was not" - that changes the meaning of the answer and makes it incorrect. Please read the original question. The OP found that setting the variable to Nothing did work, and I was explaing why that was the case.] When the loop came back around to the 'oMatch.setLineNumber' line, VBA "helpfully" created a new instance of 'clsMatch' for your 'oMatch' variable to refer to, and then you got multiple different instances in your collection.

这可能会更好明确做到这一点:

It would probably be better to do this explicitly:

Dim oMatch As clsMatch   

For i = 0 To 10                
    Set oMatch = New clsMatch                
    oMatch.setLineNumber i                
    oCollection.Add oMatch                
Next  

请注意,(不像在C / C ++或??。NET)没关系所在的暗淡的声明去。它没有被执行内循环多次,和它所宣称的范围是程序范围内,即使它出现在循环中。

Note that (unlike in C/C++ or ??.NET) it doesn't matter where the 'Dim' declaration goes. It's not being "executed" multiple times inside the loop, and the scope of what it declares is procedure-wide even though it appears inside the loop.

 
精彩推荐
图片推荐