Using Property Let with a Type as member of a Class

K

Ken Dahlberg

I've encountered a need to build a Class module that has a couple of
Types as members. So first the Type is defined in a standard module,
thus:

Public Type FitParms
XVar as String
YVar as String
Formula as String
Par(6) as Double
End Type

Then, in a Class module called PcGroup there are these statements:

Private jprms as FitParms
Public Property Get JParms() As FitParms
JParms = jprms
End Property
Public Property Let JParms(RHS As FitParms)
jprms = RHS
End Property

Now here's the "problem": the Let doesn't work the way I would like it
to. If gp is an instance of the PcGroup class, the Get works just as
expected: the statement

Private JFormula as String
JFormula = gp.JParms.Formula

assigns the appropriate value from the jprms Type to the local
variable JFormula. But if I try to do it the other way:

gp.JParms.Formula = JFormula

this again invokes the Property Get module, not the Let, and nothing
is assigned to the Formula field in jprms. The only way I can use the
Let is by defining a local FitParm variable and then assigning the
whole thing, like this:

Private fp as FitParm
fp = gp.JParms
fp.Formula = JFormula
gp.JParms = fp

Then the Let module is invoked and the assignment is made.

Am I missing something here? Is this really the way this works, or is
there some way make the Let to work the way I want it to? VBA doesn't
allow me to declare the Type as a Public member of the Class, so I
can't bypass the Get/Let construction.

Thanks,
Ken Dahlberg
 
G

George Nicholson

Yes, you are missing something. Are you sitting down?

*Set* jprms = RHS

User-defined types (and classes) need to be treated as objects & require the
use of Set.

:) Happens to all of us.

Hope this helps,
 
K

Ken Dahlberg

George,

Thanks for trying, but this isn't it. If I follow your suggestion,
the statement

gp.JParms.Formula = JFormula

still invokes the Property Get method, not the Let. And if I try

gp.JParms = fp

as described below, there is a compilation error on the

Set jprms = RHS

statement: it says "Object Required". So Types are not treated as
objects. If they were, I would need to be using the Property Set
(which also doesn't work) instead of the Let. So apparently there is
no way to set a single element of the type gp.JParms using the
construction

gp.JParms.Formula = JFormula

Oh well - it isn't a major problem.

Ken Dahlberg
 
G

George Nicholson

I would like to retract my previous response. In my research I was looking
at the use of a class as the property of a class, not a datatype as a
property of a class. I was wrong. Sorry.
*************
Current response:

Another way to do what you want is to:
1) change FitParms data type to a class
2) change your JParms Let/Get to Set/Get
then gp.JParms.Formula = JFormula will access the Formula property of the
FitParms class directly.

Otherwise, then yes, i think you'll need to do what you laid out: establish
a datatype ref, assign the class property to it and then manipulate the
datatype. It seems you can access the datatype itself, but not its parts,
without the interim step. You could roll that step up into a method of the
PcGroup class:

Public Function ChangeFormula(sNewValue As String)
Dim fp As FitParm
fp.Formula = sNewValue
jprms = fp
End Function
 
O

onedaywhen

Looking at your Property Let JParms procedure, it is expecting an
argument of type FitParms. Therefore, I'm not surprised the statement

gp.JParms.Formula = JFormula

does not invoke the Property Let because there's nothing in there to
pass it a FitParms variable i.e. on the R.H.S you have a String
(JFormula) rather than a FitParms.

This kind of construct would work if FitParms were a class rather than
a UDT but it still wouldn't use Property Let JParms, rather the
Property Get to return the internal instance of FitParms.

To demonstrate, create two classes as follows:

' In class module named PcGroup:
Option Explicit
Private jprms As FitParms
Public Property Get JParms() As FitParms
Set JParms = jprms
End Property
Public Property Set JParms(RHS As FitParms)
Set jprms = RHS
End Property
Private Sub Class_Initialize()
Set jprms = New FitParms
End Sub

' In class module named FitParms:
Option Explicit
Private m_strFormula As String
Public Property Get Formula() As String
Formula = m_strFormula
End Property
Public Property Let Formula(ByVal NewValue As String)
m_strFormula = NewValue
End Property

Put this code in a standard module:

' In a standard module:
Option Explicit
Private JFormula As String
Sub test()
Dim gp As PcGroup
Set gp = New PcGroup
JFormula = "blah"
gp.JParms.Formula = JFormula
End Sub

If you set a breakpoint in sub Test and step into the code, you will
see that Property Get JParms fires followed by Property Let Formula,
but Property Set JParms never fires.

--
 
K

Ken Dahlberg

I got everything working with the clunky construction using the type.
It seemed like overkill to use a class module since I didn't need any
methods or events. But I'm not so sure - with a class I would only
need one copy of each instance and not have to make 2 additional
working copies for the manipulations of changing values of individual
members. Thanks for the input.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top