Class Method Can't Use Private Property of Same Class? - vba

What am I misunderstanding about Private Properties in VBA classes? As a novice, I expected Private Properties to be accessible to other methods within the same class (module), but instead I get "Method or data member not found" when trying to compile.
Breaks as Private Property Let lngMarketID
Here's what I have in my standard module:
Option Explicit
Public Model As classModel
Set Model = New classModel
Model.Setup
with this class module named classModel:
Option Explicit
Private plngMarketID As Long
'plngMarketID Properties
Public Property Get lngMarketID() As Long
lngMarketID = plngMarketID
End Property
Private Property Let lngMarketID(ByVal lngMarketID As Long)
plngMarketID = lngMarketID
End Property
Public Sub Setup()
SetuplngMarketID
End Sub
Private Sub SetuplngMarketID()
Model.lngMarketID = CLng(DefaultLogicOptions.textboxMarketID.Value)
End Sub
Works as Public Property Let lngMarketID
The "Method or data member not found" highlights the .lngMarketID of the line in SetuplngMarketID. This compiles fine when I change Private Property Let lngMarketID to Public Property Let lngMarketID.

It's the "Model" in that line. Model is a global variable pointing to some specific instance of your class. From that object, only the public things are visible.
You want to refer to that from "inside" an arbitrary instance of your class, so just drop the Model prefix:
Private Sub SetuplngMarketID()
lngMarketID = CLng(DefaultLogicOptions.textboxMarketID.Value)
End Sub

You are calling "Model.lngMarketId", Model is the name of your variable of classModel object that isn't visible in the object it self.
you have to use "lngMarketId = Clng(something)"

Related

Add A Method To A Property Of A Class

I am confused. I am new to VBA classes. I want to add multiple methods to a property of a class, or add properties to another property. I may not have the terminology correct?
I can add one property, but I want to drill down deeper.
For instance if I make a class person:
PersonClass.Features.Hair.Texture.Color
PersonClass.Features.Hair.Texture.Style
PersonClass.Features.Hair.Length
I am not sure how to go about this.
e.g.
MyClass.MyProperty.MyMethod1
MyClass.MyProperty.MyMethod2
MyClass.MyProperty.MyMethod3
or
MyClass.MyProperty.MyMethod1.MyMethod2
Here is an example to illustrate the concepts mentioned in the comments:
Main Form
Option Explicit
Private Sub Form_Load()
Dim p As Person
Set p = New Person
p.Features.Hair = "Red"
MsgBox p.Features.Hair
End Sub
Person Class
Option Explicit
Private m_Features As Features
Private Sub Class_Initialize()
Set m_Features = New Features
End Sub
Public Property Get Features() As Features
Set Features = m_Features
End Property
Features Class
Option Explicit
Private m_Hair As String 'this would actually be another class
'in your example
Public Property Get Hair() As String
Hair = m_Hair
End Property
Public Property Let Hair(ByVal Value As String)
m_Hair = Value
End Property

How do VB.NET static classes work?

I understood them to be modules, such as my little one:
Public Module Config
Public Property ImportSettings As ImportConfig
Sub New()
ImportSettings = ImportConfig.Read()
End Sub
End Module
Yet, I cannot access ImportSettings. I'm told it's not declared, and its value is 'Nothing'.
Static(C#)/Shared(VB) method/property in a class:
Public Class Config
Public Shared ReadOnly Property ImportSettings As ImportConfig
Get
Return ImportConfig.Read()
End Get
End Property
End Class
Usage:
Dim configs = Config.ImportSettings
Since it is Static/Shared we do not need to initialize the Config class.

Using collections as properties of an object in VBA

With class module "Class1Test" as
Private pGreetings As Collection
Public Property Get Greetings() As Collection
Greetings = pGreetings
End Property
Public Property Let Greetings(Value As Collection)
pGreetings = Value
End Property
If I run the sub
Dim MyPhrases As Class1Test
Public Sub Test()
Set MyPhrases = New Class1Test
MyPhrases.Greetings.Add "Have a nice day"
End Sub
I get the a compile error "Argument not optional"
Why can't I add the string to the the collection myphrases.greetings ? Please forgive the newbie question. Just learning VBA.
A few things wrong.
Collection is an object, so you must use the Set keyword when assigning. Also in the Let procedure for consistency in naming conventions, I would use lGreetings instead of Value although that should not really matter.
Private pGreetings As Collection
Public Property Get Greetings() As Collection
Set Greetings = pGreetings
End Property
Public Property Let Greetings(lGreetings As Collection)
Set pGreetings = lGreetings
End Property
This will still raise an 91 error (Object variable or with block not set) because you have not instantiated the collection object. Probably the way you should do this is in the class module's Initialize routine.
Private Sub Class_Initialize()
Set pGreetings = New Collection
End Sub

How to use classes as properties only?

I have been trying to do this for a long time but I can't find anything anywhere. I think I am not searching it as it should...
A little example:
Class MainClass
Property ExampleProperty As New ExamplePropertyClass
Private Class ExamplePropertyClass
Sub DoSomething()
End Sub
End Class
End Class
In the previous code the ExamplePropertyClass is used as an property of the MainClass.
There is always an error that says I can't expose a private class as propery.
But how is it possible to make only the property "Visible", I mean The user who is going to use the code should only use the property and not the class, how can the class be not inherited or visible?
What is property actually syntactic sugar for setter and getter.So mostly it is default public
You declare class as private. So it will be invisible outside. Then there is conflict if it be not visible then how people will know to assign and get that object without knowing its type. So that type should be public and visible
dim m as new MainClass()
m.ExampleProperty=? ' What is ExampleProperty ?int , object. So it should not be unknown
Another way you claim that you are not going to use that property outside.This way it is ok to have private class inside.
'Explicitly make property to be used only within class
Private Property ExampleProperty As ExamplePropertyClass
You do this with interfaces:
Public Interface IDoesSomething
Sub DoSomething()
End Interface
Public Class MainClass
Public Sub New()
m_example = New InternalClass
End Sub
Private m_example As IDoesSomething
Public ReadOnly Property Example() As IDoesSomething
Get
Return m_example
End Get
End Property
Private Class InternalClass
Implements IDoesSomething
Public Sub DoSomething() Implements IDoesSomething.DoSomething
End Sub
End Class
End Class

Object from module sees private variable from class

I don't know if I'm doing wrong, but I think this is not normal.
I have class clsPerson
Private pNameFirst As String
Public Property Get NameFirst() As String
NameFirst = pNameFirst
End Property
Public Property Let NameFirst(sNameFirst As String)
pNameFirst = sNameFirst
End Property
Now in Module I have procedure test
Sub test()
Dim Person As New clsPerson
Person.NameFirst = "test"
End Sub
When I look at Locals and unwrap Person object I can see there my private variable pNameFirst.
Why?
The locals window will still display your Private variables from the class. What you can't do in the module is alter the value directly of the private variable.
The locals window will show all your declared variables and ignore scope.
Edit:
See further discussion here:
Should I have to have duplicate values in VBA class objects?