Estaba creando un nuevo objeto dentro de un ciclo y agregando ese objeto a una colección; pero cuando volví a leer la colección, siempre estaba completa con el último objeto que había agregado. He encontrado dos formas de evitar esto, pero simplemente no entiendo por qué mi implementación inicial fue incorrecta.VBA: ¿Diferencia en dos formas de declarar un objeto nuevo? (Tratando de entender por qué mi solución funciona)
original:
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
Esto dio lugar a todos los lineNumber siendo 10; Obviamente no estaba creando nuevos objetos, sino que usaba el mismo cada vez que pasaba el ciclo, a pesar de que la declaración estaba dentro del ciclo.
Entonces, agregué Set oMatch = Nothing
inmediatamente antes de la línea Next
, y esto solucionó el problema, ahora era 0 a 10. Entonces, si el antiguo objeto se destruía explícitamente, ¿estaba dispuesto a crear uno nuevo? Pensé que la próxima iteración a través del ciclo causaría que algo declarado dentro del ciclo fuera destruido debido al alcance?
Curioso, probé otra manera de declarar un nuevo objeto: Dim oMatch As clsMatch: Set oMatch = New clsMatch
. Esto también da como resultado de 0 a 10.
¿Alguien me puede explicar por qué la primera implementación fue incorrecta?
En VBA es considéré d mala práctica para usar "Como nuevo". Como descubriste por las malas, puede conducir a todo tipo de errores sutiles. Lo mejor es declarar todas las variables en la parte superior y usar "= Nuevo" cuando corresponda. (Nota al margen: diría exactamente lo contrario en VB.Net) –
El alcance más pequeño posible en VBA es el nivel de procedimiento; un bloque 'For ... Next' (o cualquier otro bloque) no crea un alcance. –