VBA Class Routines
Private
and Public
routines
Classes are datatypes.
A class is a special datatype because it can contain both variables and routines.
The routines can be Private
or Public
.
For routines, there is no default. Private
routines can only be used by the other routines of the class (by both Private
and Public
). The Private
routines are encapsulated by the class. Public
routines can be called from outside the class. The Public
routines are part of the interface of the class.
Example: Public
versus Private
If you have some time, spend a few minutes to study the following code. It is a class implementing a simple logger.
Here is the interface of the class.
First, do you see the relation between the class definition and its interface?
It is very simple: all variables and routines that are Public
are part of the interface. In the above example all the routines, except for Flush
are Public
and, thus, are in the class interface. As you can see for the Property
routines, by default, a routine in a class is Public
.
Now focus on the routine Flush
.
This routine writes the variable Message_
to a file. As the routine is Private
, it cannot be called from outside the class. The only way to activate the routine is to call either the routine ToLog
or Class_Deserialize
, where calling the latter explicitely is probably not a good idea. Actually, writing to a file is encapsulated by the class, i.e. the class manages it itself. The user of your class has one less thing to remember and, cannot forget it. As a class designer, this should make you happy. It is an example of good design.
Now, imagine we make the routine Flush
public.
Then, this is the interface.
In itself, there is nothing wrong. Your class design is still good. As before, the class still manages the file writing itself, and the user of your class cannot forget to write the log messages to a file. The only thing that has changed is the class interface. By making the function Flush
public you simply offer the class user the option to initiate the file writing himself (or herself). Ok, why not. But... on the other hand, why should you? We don't really see a good reason (do you?). We are in favor of keeping the class interface as simple as possible, offering only just enough flexibility.
Kinds of routines
There are three kinds of routines in a class. All routines can be Public
versus Private
.
Sub
Nothing special. As all other subs in VBA.
Function
Again nothing special. As all other functions in VBA.
Properties
Routines that behave as variables. This is special!
Properties
Properties are to classes what high heels are for women: you don't need them but, if there, they allow for elegant design.
A Property
is a special kind routine
- that behaves like a class variable, and,
- can have exactly the same name as a class variable.
If you use Public
properties (and almost all of the time, they will be Public
), the class interface will display the properties as if they were Public
variables. Often, properties will encapsulate a Private
class variable (but this need not be the case). If they do, for the user of the class, it will be as if the class variables are Public
while they are still safely encapsulated. Properties allow the class designer to build elegant class interfaces.
There are four kinds of properties.
- To return the value of a class variable. The return data type of the
Get
property must be the same datatype as the last argument of associated theLet
property.1234Property Get MyPropertyName () As ...MyPropertyName = ...End Property - To return a reference to a class variable. The return data type of the
Get
property must be the same datatype as the last argument of associated theSet
property.1234Property Get MyPropertyName () As ...Set MyPropertyName = ...End Property - To set a class variable of a value datatype. The last argument of the
Let
property must be the same datatype as the return data type of the associatedGet
property.123Property Let (...)End Property - To set a class variable of a reference datatype. The last argument of the
Set
property must be the same datatype as the return data type of the associatedGet
property.1234Property Set (...)Set ... = ...End Property
Example: Properties
If you have some time, spend a few minutes to study the following code. It is a class implementing a simple logger.
Here is the interface of the class.
First, do you see the relation between the class definition and its interface?
It is very simple: all variables and routines that are Public
are part of the interface. All the variables are Private
and none of them are in the interface. The class variables all end with _ and there are no things ending with _ in the interface. As you can see for the Property
routines, by default, a routine in a class is Public
.
Now focus on the property PathOfLogFile
.
Note that the only way to change the variable PathOfLogFile_
is by using the property PathOfLogFile
. The Private
variable PathOfLogFile_
is safely encapsulated. Well done for the class designer! It is an example of good design.
Here is how to change the path of the log file. The property PathOfLogFile
behaves like a Public
class variable.