What is the difference between
Public Variable As Integer
and
Private pVariable As Integer
Public Property Let Variable(ByVal lVariable As Integer)
pVariable = lVariable
End Property
Public Property Get Variable()
Variable = pVariable
End Property
in a VBA class module?
And why would I use the second version?
As much as VBA is object-oriented it's still limited in many ways, but as far as this example goes it should be sufficient to just understand the basics of the OOP in VBA.
Your code
is
wronga bit unnecessary.NOTE: You may do that in cases where you want to handle errors / validate data coming in but generally if it's as simple as setting and getting the value you wouldn't do that.
Why would you ever need a private backing field if you are exposing both the Let/Set and Get properties? All you need for this is the public variable itself and no need for properties.
The story changes 360 degrees when you have to only expose one of the properties and not the other (ie. either setter or getter only ). Maybe it's easier to understand by working through an example...
Example
Let's start by working through an easy "banking" example (obviously you wouldn't do that in VBA in real-life but it's a good concept to evaluate as a base)
Imagine you have to build a class to simulate a bank account. You need a way to
deposit
andwithdraw
money from the account as well displaybalance
.Normally you wouldn't have a
setter
for thebalance
field because no-one should be allowed to explicitlyset
the balance. (if you know a bank that allows this please let me know ;)) . The actual balance should be a private variable. There should be a property which exposes it and that's all you should consider here.Consider a VBA class (an interface)
IAccountServices.cls
and another class to represent the account
Account.cls
NOTE: This obviously is the simplest of simple examples and it does not have any error handling or checking whether the balance is sufficient to withdraw etc. This is just for demonstration purposes and not to be used in a real-life application.
With this encapsulation I see/know right away
accBalance
is a private field not accessible anywhere outside the class.I can only retrieve the
balance()
and not explicitly set it on an instance of theAccount
class.I can
deposit()
andwithdraw()
money from the account (publicly accessible methods)In you standard module (module1) even with intelli-sense you get the .Balance listed and that's all your library/class user ever have to worry about.
Now having a standard coding module to test both classes (Module1)
To get an intro to VBA OOP I could recommend:
How to use the Implements in Excel VBA
How to use comparison methods between class object modules in VBA in a similar manner as VB.NET?
A property allows external access as though the property was a public field, while allowing the class to keep control of the data.
The Get property may compute a "variable" that doesn't actually exist in the class. E.g. a mass Get property might return the product of density times volume.
A Let property might check validity, e.g. not accept a negative volume. Or it can keep an object's field properties in sync:
You can also make a property read-only (or write-only -- not used much) by omitting the Let or Get property.
Other than a very slight degradation in performance, it's good practice to use properties from the start for any fields that you allow public access, even if the properties are initially trivial, to facilitate future modifications to the class.