Public Variables in Class Modules

Rob’s post made me revisit some class module code, so it’s probably going to be class module week. Stop groaning out there.

First, a quick discussion on the merits of property statements vs. public variables. Rob comments:

I don’t see the point of traditional public property get/set if only to set a private variable. It tends to be a bit tidier in Intellisense too.

I’m not sure what the Intellisense comment means, but I can’t refute the first part. Yet, I still won’t be using public variables in my class modules. That’s because I’m old and crotchety and I just don’t want to. So there.

I use MZ Tools to convert my Public variables into Property Get/Let statements. Besides the problem with the hotkeys, I also have to do them one at a time. Since I was knee-deep in code today, I thought I would fix that problem by writing my own converter. And here it is:

Sub ConvertPublicToPrivate()
   
    Dim Child As CodeModule
    Dim i As Long
    Dim clsPublic As CPublic
   
    Set Child = GetChildModule
   
    For i = Child.CountOfDeclarationLines To 1 Step -1
        If Child.Lines(i, 1) Like “Public * As *” Then
            Set clsPublic = New CPublic
            clsPublic.Line = Child.Lines(i, 1)
            Child.InsertLines i + 1, clsPublic.PrivateLine
            Child.InsertLines Child.CountOfLines + 2, clsPublic.PropertyGet
            Child.InsertLines Child.CountOfLines + 2, clsPublic.PropertyLet
            Child.DeleteLines i, 1
        End If
    Next i
   
End Sub

GetChildModule returns a code module that is selected from a ListBox on a Userform. You can check it out in the download if you like. Once I have the Child, I loop through the declaration lines backward. I know that I will be deleting some lines, so I need to go backward so I don’t screw up the counter. I’m looking for variable declarations that are Like “Public * As *”. If I find one, I create a new CPublic class. All this class does is abstract the string manipulation away so that my procedure isn’t so cluttered. Once I have the Public line, I insert a Private line, a Property Get procedure, a Property Let procedure, and delete the Public line. This

Public LastName as String

becomes

Private msLastName as String

Public Property Get LastName() As String: LastName = msLastName: End Property
Public Property Let LastName(ByVal sLastName As String): msLastName = sLastName: End Property

I mentioned in a previous post that I should put those property procedures that only return a variable value on one line to help clean up the class module, so I decided to implement it here. If I want to add some error checking or other code in the property, I can expand it out and do that. If I just want to return the variable, I can leave it on one line.

The CPublic class has three properties that I use; PrivateLine, PropertyGet, and PropertyLet. In addition to those I have a crap load of read-only properties to manipulate the strings. Here’s what I know I’ll need for the LastName variable

  • The base variable name – LastName
  • The data type – String
  • The prefix I use for that data type – s
  • The private variable – msLastName
  • The argument to the Let statement – sLastName
Private Const msPUB As String = “Public “
Private Const msAS As String = ” As “
Private Const msMOD As String = “m”
Private Const msEND As String = “End Property”
Private Const msDEFAULTPRE As String = “obj”
Private Const msPUBPROP As String = “Public Property “

Public Property Get VariableName() As String
   
    VariableName = Mid(Me.Line, Len(msPUB) + 1, Me.AsPos – Len(msPUB) – 1)
   
End Property

This extracts the string between “Public ” and ” As ” which is the variable name.

Public Property Get VariableType() As String
   
    VariableType = Mid(Me.Line, Me.AsPos + Len(msAS), Len(Me.Line))
   
End Property

This gets everything after ” As “, which should be the data type.

Public Property Get TypePrefix() As String
   
    Select Case Me.VariableType
        Case “Boolean”
            TypePrefix = “b”
        Case “Byte”
            TypePrefix = “bt”
        Case “Currency”
            TypePrefix = “c”
        Case “Date”
            TypePrefix = “dt”
        Case “Double”
            TypePrefix = “d”
        Case “Integer”
            TypePrefix = “i”
        Case “Long”
            TypePrefix = “l”
        Case “Single”
            TypePrefix = “sn”
        Case “String”
            TypePrefix = “s”
        Case “Variant”
            TypePrefix = “vb”
        Case “Collection”
            TypePrefix = “col”
        Case Else
            TypePrefix = msDEFAULTPRE
    End Select
   
End Property

This converts the data type into a prefix. Now the easy part. With all those properties written, I just start concatenating properties together to make variable names and code lines

Public Property Get PrivateName() As String
   
    PrivateName = msMOD & Me.TypePrefix & Me.VariableName
    ‘msLastName

End Property

Public Property Get RHS() As String
   
    RHS = Me.TypePrefix & Me.VariableName
    ‘sLastName

End Property

Public Property Get PrivateLine() As String
   
    PrivateLine = “Private “ & Me.PrivateName & msAS & Me.VariableType
    ‘Private msLastName As String

End Property

Public Property Get PropertyGet() As String
   
    Dim sReturn As String
   
    sReturn = msPUBPROP & “Get “ & Me.VariableName & “()” & msAS & Me.VariableType
    sReturn = sReturn & “:” & Me.VariableName & ” = “ & Me.PrivateName
    sReturn = sReturn & “:” & msEND
   
    PropertyGet = sReturn
   
End Property

Public Property Get PropertyLet() As String
   
    Dim sReturn As String
   
    sReturn = msPUBPROP & Me.LetSet & Me.VariableName & “(ByVal “ & Me.RHS & msAS & Me.VariableType & “)”
    sReturn = sReturn & “:” & Me.PrivateName & ” = “ & Me.RHS
    sReturn = sReturn & “:” & msEND
   
    PropertyLet = sReturn
   
End Property

Public Property Get LetSet() As String
   
    If Me.TypePrefix = msDEFAULTPRE Then
        LetSet = “Set “
    Else
        LetSet = “Let “
    End If
   
End Property

You can download VBHelpers.zip

Posted in Uncategorized

2 thoughts on “Public Variables in Class Modules

  1. Cool code generator. I really like how you’ve one-lined the get/set with colons.

    I must be going crazy because I thought Private Property showed in Intellisense. I did a quick test and it definitely is hidden.
    Now that I see how tidy it can be, perhaps I’ll reconsider my stray from tradition.


Posting code? Use <pre> tags for VBA and <code> tags for inline.

Leave a Reply

Your email address will not be published.