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:
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
becomes
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 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.
VariableType = Mid(Me.Line, Me.AsPos + Len(msAS), Len(Me.Line))
End Property
This gets everything after ” As “, which should be the data type.
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
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
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.
[…] ????????Public Property???GET/SET???xla ????Link??. Class: Part 1 Part 2 Part 3 Part […]