View Single Post
  #5   Report Post  
Posted to microsoft.public.excel.programming
Desmond Walsh Desmond Walsh is offline
external usenet poster
 
Posts: 28
Default Problem getting a pointer to a User Defined Type (UDT)

As I mentioned in my second post, switching the member UDT (UDTb) to a class (Classb) was very simple and gave me the pointer that I wanted
Here is test code that I wrote to illustrate the problem ;
--------------------------------------------------
================================================== ================================================== ====================
Name: Module1
================================================== ================================================== ====================
Option Explicit
' Module 1 TestUdtClass
'
' Test code to demonstrate a difference between a User Defined Type(UDT) and a Class
'
'-------------------------------------------------------------------------------------------
Public Type Udtb
bmember1 As Integer
bmember2 As Integer
End Type

Public Type Udta_v1
' Some members are references to other UDT's
index As Integer
amember1 As Udtb
amember2 As Udtb
End Type

Public Type Udta_v2
' Identical to Udta_v1 with UDT members replaced by Class members
index As Integer
amember1 As Classb
amember2 As Classb
End Type

Public Sub UsingUdt()
'
' Attempting to get a pointer to a UDT one layer down in the data structure
' The data structure is an array of UDT's with some members also UDT's (different UDT)

Dim marray() As Udta_v1
Dim udtb_pointer As Udtb

ReDim marray(1 To 2) As Udta_v1

Debug.Print vbNewLine & "USINGUDT Data structures use UDT's only"
marray(2).index = 2
marray(2).amember1.bmember1 = 111
marray(2).amember1.bmember2 = 122

udtb_pointer = GetUdtPointer(2, marray)
'
' Display contents of Udtb
Debug.Print "USINGUDT Using marray bmember1: " & marray(2).amember1.bmember1
Debug.Print "USINGUDT Using marray bmember2: " & marray(2).amember1.bmember2
Debug.Print vbNewLine

Debug.Print "USINGUDT Using GetUdtPointer bmember1: " & udtb_pointer.bmember1
Debug.Print "USINGUDT Using GetUdtPointer bmember2: " & udtb_pointer.bmember2

End Sub

Public Function GetUdtPointer(i As Integer, marray() As Udta_v1) As Udtb

' Intent was to get a pointer to a specific Udta. But the debug statements clearly show that
' a new instance of Udtb was created which inherited data from the targetted Utdb
' The function GetClassPointer is equivalent code for the Udta_v2 data structure
' NOTE: Use Local Window in debug mode to see the data structures being updated

GetUdtPointer = marray(2).amember1
'
' Now have two Udt pointers. Add some data
GetUdtPointer.bmember2 = 277
marray(2).amember1.bmember2 = 299

'
' Display contents of Udtb
Debug.Print "GETUDTPOINTER Using marray Varptr: " & VarPtr(marray(2).amember1)
Debug.Print "GETUDTPOINTER Using marray bmember2: " & marray(2).amember1.bmember1
Debug.Print "GETUDTPOINTER Using marray bmember2: " & marray(2).amember1.bmember2
Debug.Print vbNewLine

Debug.Print "GETUDTPOINTER Using GetUdtPointer Varptr: " & VarPtr(GetUdtPointer)
Debug.Print "GETUDTPOINTER Using GetUdtPointer bmember2: " & GetUdtPointer.bmember1
Debug.Print "GETUDTPOINTER Using GetUdtPointer bmember2: " & GetUdtPointer.bmember2
Debug.Print vbNewLine
End Function

Public Sub UsingClass()
'
' Attempting to get a pointer to second layer elements in the data structure
' The data structure is an array of UDT's with some members defined as instances of a class (Classb)


Dim marray() As Udta_v2
Dim classb_pointer As Classb

ReDim marray(1 To 2) As Udta_v2

Debug.Print vbNewLine & "USINGCLASS Data structures use UDT's and Classes"
marray(2).index = 2
'
' Because we are now using classes, must first create a class instance
Set marray(2).amember1 = New Classb
marray(2).amember1.bmember1 = 111

Set marray(2).amember2 = New Classb
marray(2).amember1.bmember2 = 122

Set classb_pointer = GetClassPointer(2, marray)
'
' Display contents of Udtb
Debug.Print "USINGCLASS Using marray bmember1: " & marray(2).amember1.bmember1
Debug.Print "USINGCLASS Using marray bmember2: " & marray(2).amember1.bmember2
Debug.Print vbNewLine


Debug.Print "USINGCLASS Using GetClassPointer bmember1: " & classb_pointer.bmember1
Debug.Print "USINGCLASS Using GetClassPointer bmember2: " & classb_pointer.bmember2

End Sub

Public Function GetClassPointer(i As Integer, marray() As Udta_v2) As Variant
'
' This code is identical to GetUdtPointer except for
' 1 Function name is GetClassPointer instead of GetUdtPointer
' 2 Marray defined as Udta_v2 instead of Udta_v1
' 3 Use Set keyword to define new pointer
' 4 Function returns a Variant
' NOTE: Use Local Window in debug mode to see the data structures being updated

Set GetClassPointer = marray(2).amember1
'
' Now have two pointers. Add some data
GetClassPointer.bmember2 = 277
marray(2).amember1.bmember2 = 299

'
' Display contents of Udtb
Debug.Print "GETCLASSPOINTER Using marray Objptr: " & ObjPtr(marray(2).amember1)
Debug.Print "GETCLASSPOINTER Using marray Varptr: " & VarPtr(marray(2).amember1)
Debug.Print "GETCLASSPOINTER Using marray bmember2: " & marray(2).amember1.bmember1
Debug.Print "GETCLASSPOINTER Using marray bmember2: " & marray(2).amember1.bmember2
Debug.Print vbNewLine

Debug.Print "GETCLASSPOINTER Using GetClassPointer Objptr: " & ObjPtr(GetClassPointer)
Debug.Print "GETCLASSPOINTER Using GetClassPointer Varptr: " & VarPtr(GetClassPointer)
Debug.Print "GETCLASSPOINTER Using GetClassPointer bmember2: " & GetClassPointer.bmember1
Debug.Print "GETCLASSPOINTER Using GetClassPointer bmember2: " & GetClassPointer.bmember2
Debug.Print vbNewLine
End Function


================================================== ================================================== ====================
Name: Classb
================================================== ================================================== ====================
' Class Classb
'
' The members of this class are identical to the UDT Udtb
' No methods are defined for this class
'
'-------------------------------------------------------------------------------------------
Public bmember1 As Integer
Public bmember2 As Integer
-----------------------------------------------------------

Here is the output ;
USINGUDT Data structures use UDT's only
GETUDTPOINTER Using marray Varptr: 2152204
GETUDTPOINTER Using marray bmember2: 111
GETUDTPOINTER Using marray bmember2: 299


GETUDTPOINTER Using GetUdtPointer Varptr: 112225048
GETUDTPOINTER Using GetUdtPointer bmember2: 111
GETUDTPOINTER Using GetUdtPointer bmember2: 277


USINGUDT Using marray bmember1: 111
USINGUDT Using marray bmember2: 299


USINGUDT Using GetUdtPointer bmember1: 111
USINGUDT Using GetUdtPointer bmember2: 277

USINGCLASS Data structures use UDT's and Classes
GETCLASSPOINTER Using marray Objptr: 162841984
GETCLASSPOINTER Using marray Varptr: 138064736
GETCLASSPOINTER Using marray bmember2: 111
GETCLASSPOINTER Using marray bmember2: 299


GETCLASSPOINTER Using GetClassPointer Objptr: 162841984
GETCLASSPOINTER Using GetClassPointer Varptr: 112225000
GETCLASSPOINTER Using GetClassPointer bmember2: 111
GETCLASSPOINTER Using GetClassPointer bmember2: 299


USINGCLASS Using marray bmember1: 111
USINGCLASS Using marray bmember2: 299


USINGCLASS Using GetClassPointer bmember1: 111
USINGCLASS Using GetClassPointer bmember2: 299

------------------------------------------------------------------------
Meeting this kind of problem is intimidating. Excel cannot detect that this coding is not what the author intended. Only a close examination of the data will reveal unintended behaviour.