How to prevent showing backing private fields of class properties in the Locals window?

Viewed 651

Although an experienced VBA programmer it is the first time that I make my own classes (objects). I am surprised to see that all properties are 'duplicated' in the Locals Window. A small example (break at 'End Sub'):

' Class module:
Private pName As String

Public Property Let Name(inValue As String)
    pName = inValue
End Property
Public Property Get Name() As String
    Name = pName
End Property

' Normal module:
Sub Test()
    Dim objTest As cTest
    Set objTest = New cTest
    objTest.Name = "John Doe"
End Sub

Why are both Name and pName shown in the Locals Window? Can I in some way get rid of pName?

3 Answers

If you really dont want to see even Mathieu's This you could wrap it into a function. This is a bit more involved, and can be achieved using

  1. a second class that stores the data in public variables. This will be marginally slower then Mattieu's implementation
  2. a collection object that accesses the data using keys. This does not require additional clutter in the project exporer's 'class module' list but will be a little slower if you call the This repeatedly in fast sucession

An example for each is given below. If you break in the Class's Initialisation function, you can add me to the watch window and only the Name property will be listed

Using 2 Objects example

insert a classmodule and name it: InvisibleObjData

Option Explicit
Public Name As String
Public plop

Private Sub Class_Initialize()
    Name = "new"
    plop = 0
End Sub

insert a classmodule and name it: InvisibleObj

Option Explicit

Private Function This() As InvisibleObjData
    Static p As New InvisibleObjData 'static ensures the data object persists at successive calls
    Set This = p
End Function

Private Sub Class_Initialize()
    This.Name = "invisible man":  Debug.Print Name
    Me.Name = "test":             Debug.Print Name
    This.plop = 111:              Debug.Print This.plop
End Sub

Property Let Name(aname As String): This.Name = aname:     End Property
Property Get Name() As String:           Name = This.Name: End Property

'_______________________________________________________________________________________
' in the immediate window type
'
'    set x=new invisibleObj

If you dont like splitting the class over two objects, a similar behaviour can be generated using a 'wrapped' collection object:

insert a classmodule and name it: InvisibleCol

Option Explicit

Private Function This() As Collection
    Static p As New Collection
    'static ensures the collection object persists at successive calls
    'different instances will have different collections
    'note a better dictionary object may help
    Set This = p
End Function

Private Function add2this(s, v)
   'a better dictionary object instead of the collection would help...
    On Error Resume Next
    This.Remove s
    This.Add v, s
End Function

Private Sub Class_Initialize()
    add2this "name", "invisible man":  Debug.Print Name
    Me.Name = "test":                       Debug.Print Name
    
    add2this "plop", 111
    Debug.Print This("plop")  ' use the key to access your data
    Debug.Print This!plop * 2 ' use of the BANG operator to reduce the number of dbl quotes
                              ' Note: This!plop is the same as This("plop")
End Sub

Property Let Name(aname As String): add2this "name", aname: End Property
Property Get Name() As String:            Name = This!Name: End Property


'_______________________________________________________________________________________
' in the immediate window type
'
'    set x=new invisibleCol
Related