I have a composite data structure which I have defined using two nested classes. I am presenting a simplified version of the structure here:-
Routine Variable Type
------- -------- ----
Sub_1 l Long
y Class_A
z Class_B
Class_A a() Class_B
i Integer
Class_B s String
So my my first question: Is the above allowable?
Here is the code:
'1. sub
Sub NestedArray()
Const ciNumberToString As Integer = 64
Dim l As Long
Dim y As Class_A
Dim z As Class_B
Set y = New Class_A
Set z = New Class_B
For l = 0 To 10
y.pI = l
z.pS = Chr(l + ciNumberToString)
y.pA = z
Next l
End Sub
'2. Class_A
Option Explicit
Private a() As Class_B
Private i As Integer
Public Property Get pI() As Integer
pI = i
End Property
Public Property Let pI(oI As Integer)
If Not oI < i Then
ReDim Preserve a(oI)
End If
i = oI
End Property
Public Property Get pA() As Class_B
Set pA = a(i)
End Property
Public Property Let pA(oA As Class_B)
Set a(i) = oA
End Property
'3 Class_B
Option Explicit
Private i As Integer
Public Property Get pI() As Integer
pI = i
End Property
Public Property Let pI(oI As Integer)
i = oI
End Property`
I put a stop on the 'End Sub' line. This is the expected result (as it appears in the Watches window):-
Expression Value Type
---------- ----- ----
y Class_A
a Class_B(0 to 10)
a(0) Class_B
s "@" String
pS "@" String
a(1) Class_B
s "A" String
pS "A" String
a(2) Class_B
s "B" String
pS "B" String
.
.
.
a(10) Class_B
s "J" String
pS "J" String
i 10 Integer
pA Class_B
s "J" String
pS "J" String
pI 10 Integer
Here is my actual result:-
Expression Value Type
---------- ----- ----
y Class_A
a Class_B(0 to 10)
a(0) Class_B
s "J" String
pS "J" String
a(1) Class_B
s "J" String
pS "J" String
a(2) Class_B
s "J" String
pS "J" String
.
.
.
a(10) Class_B
s "J" String
pS "J" String
i 10 Integer
pA Class_B
s "J" String
pS "J" String
pI 10 Integer
y.a(0) is set correctly initially, i.e. it has a value of 0. However on the next iteration it is reset to 1. this is done before y.a(1) is set by the code here:-
For l = 0 To 10
y.pI = l
z.pS = Chr(l + ciNumberToString)
y.pA = z
Next l
This is the Class_B code which is executed
Public Property Let pS(oS As Integer)
s = oS
End Property
Because z.pS has changed, y.a is altered from:-
Expression Value Type
---------- ----- ----
y Class_A
a Class_B(0 to 10)
a(0) Class_B
pS "@" String
s "@" String
to:-
y Class_A
a Class_B(0 to 10)
a(0) Class_B
pS "A" String
s "A" String
... and every iteration of an existing element in the array is set to z.pS
I have a composite data structure which I have defined using two nested classes. I am presenting a simplified version of the structure here:-
Routine Variable Type
------- -------- ----
Sub_1 l Long
y Class_A
z Class_B
Class_A a() Class_B
i Integer
Class_B s String
So my my first question: Is the above allowable?
Here is the code:
'1. sub
Sub NestedArray()
Const ciNumberToString As Integer = 64
Dim l As Long
Dim y As Class_A
Dim z As Class_B
Set y = New Class_A
Set z = New Class_B
For l = 0 To 10
y.pI = l
z.pS = Chr(l + ciNumberToString)
y.pA = z
Next l
End Sub
'2. Class_A
Option Explicit
Private a() As Class_B
Private i As Integer
Public Property Get pI() As Integer
pI = i
End Property
Public Property Let pI(oI As Integer)
If Not oI < i Then
ReDim Preserve a(oI)
End If
i = oI
End Property
Public Property Get pA() As Class_B
Set pA = a(i)
End Property
Public Property Let pA(oA As Class_B)
Set a(i) = oA
End Property
'3 Class_B
Option Explicit
Private i As Integer
Public Property Get pI() As Integer
pI = i
End Property
Public Property Let pI(oI As Integer)
i = oI
End Property`
I put a stop on the 'End Sub' line. This is the expected result (as it appears in the Watches window):-
Expression Value Type
---------- ----- ----
y Class_A
a Class_B(0 to 10)
a(0) Class_B
s "@" String
pS "@" String
a(1) Class_B
s "A" String
pS "A" String
a(2) Class_B
s "B" String
pS "B" String
.
.
.
a(10) Class_B
s "J" String
pS "J" String
i 10 Integer
pA Class_B
s "J" String
pS "J" String
pI 10 Integer
Here is my actual result:-
Expression Value Type
---------- ----- ----
y Class_A
a Class_B(0 to 10)
a(0) Class_B
s "J" String
pS "J" String
a(1) Class_B
s "J" String
pS "J" String
a(2) Class_B
s "J" String
pS "J" String
.
.
.
a(10) Class_B
s "J" String
pS "J" String
i 10 Integer
pA Class_B
s "J" String
pS "J" String
pI 10 Integer
y.a(0) is set correctly initially, i.e. it has a value of 0. However on the next iteration it is reset to 1. this is done before y.a(1) is set by the code here:-
For l = 0 To 10
y.pI = l
z.pS = Chr(l + ciNumberToString)
y.pA = z
Next l
This is the Class_B code which is executed
Public Property Let pS(oS As Integer)
s = oS
End Property
Because z.pS has changed, y.a is altered from:-
Expression Value Type
---------- ----- ----
y Class_A
a Class_B(0 to 10)
a(0) Class_B
pS "@" String
s "@" String
to:-
y Class_A
a Class_B(0 to 10)
a(0) Class_B
pS "A" String
s "A" String
... and every iteration of an existing element in the array is set to z.pS
Share Improve this question asked yesterday Steve RobertsSteve Roberts 114 bronze badges 0
1 Answer
Reset to default 1With small modifications, it works:
Sub NestedArray()
Const ciNumberToString As Integer = 64
Dim l As Long
Dim y As Class_A
Dim z As Class_B
Set y = New Class_A
Set z = New Class_B
For l = 0 To 10
Debug.Print "l", l
y.pI = l
z.pS = Chr(l + ciNumberToString)
y.pA = z
Debug.Print "------------- -------------"
Next l
End Sub
Class_A
Private a() As Class_B
Private i As Integer
Public Property Get pI() As Integer
pI = i
End Property
Public Property Let pI(oI As Integer)
If i <= oI Then
ReDim Preserve a(oI)
i = oI
End If
End Property
Public Property Get pA() As Class_B
Set pA = a(i)
End Property
Public Property Let pA(oA As Class_B)
Set a(i) = oA
End Property
Class_B
Private i As Integer
Public Property Get pS() As String
End Property
Public Property Let pS(oA As String)
i = Asc(oA)
Debug.Print "pS", oA
End Property
-->
l 0
pS @
------------- -------------
l 1
pS A
------------- -------------
l 2
pS B
------------- -------------
l 3
pS C
------------- -------------
l 4
pS D
------------- -------------
l 5
pS E
------------- -------------
l 6
pS F
------------- -------------
l 7
pS G
------------- -------------
l 8
pS H
------------- -------------
l 9
pS I
------------- -------------
l 10
pS J
------------- -------------
Surely, 'y.a' contains 11 references to a single Class_B object. And, at the end, any 'a(i).i' is the same - 74 (J). To recover it, modify:
Sub NestedArray()
Const ciNumberToString As Integer = 64
Dim l As Long
Dim y As Class_A
Dim z As Class_B
Set y = New Class_A
For l = 0 To 10
Debug.Print "l", l
y.pI = l
Set z = New Class_B
z.pS = Chr(l + ciNumberToString)
y.pA = z
Debug.Print "------------- -------------"
Next l
End Sub