Let and Get in a class with a user-defined data type

In a module I have:

Public Type Corners
    C2xOS2 As Integer
    C2xOS16 As Integer
    C2xIS12 As Integer
End Type


In a class I have:

Private m_PlanCorners As Corners

Public Property Get PlanCorners() As Corners
    PlanCorners = m_PlanCorners
End Property

Public Property Let PlanCorners(ByVal v_PlanCorners As Corners)
    m_PlanCorners = v_PlanCorners
End Property



I get a compile error saying: Only public user defined types in public object modules can be used as parameters or return types for public procedure of class modules or as fields of public user defined types

Any ideas what going on?

Thanks, Jebus
dj__jebusAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

wsteegmansCommented:
You can't use User Defined Data Types in a Class. User Defined Data Types only can be used in Modules ...

What to do?
Convert your Corners to a real Class (with three properties). Then it will work!

Regards!
0
dj__jebusAuthor Commented:
lmao, but there are a lot more than 3 propertys, there are about 50, and I have more than just that one data type to do.

Thanks, Jebus
0
prasitleeCommented:
Dear dj__jebus,
    Why don't you create your own customer object class instead of type ? It also give you the same result as you needed from type.
    Let 's try and any further question , please let me know.
                                                                   Meng
0
Big Business Goals? Which KPIs Will Help You

The most successful MSPs rely on metrics – known as key performance indicators (KPIs) – for making informed decisions that help their businesses thrive, rather than just survive. This eBook provides an overview of the most important KPIs used by top MSPs.

dj__jebusAuthor Commented:
There are just so many properties, I don't wanna have to write let and gets for each one, theres gotta be a better way..

Thanks ,Jebus
0
prasitleeCommented:
Dear dj__jebus,
    You don't need to create each property for the object. You can define 50 public variables in an object class. And then you could access the same way as type does.

'Class Module.
Option Explicit

Public C2xOS2 As Integer
Public C2xOS16 As Integer
Public C2xIS12 As Integer

    Any further question, please let me know.
                                                                          Meng


                                                                 Meng
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
dj__jebusAuthor Commented:
So wait... if you can just make them public in the class, whats the point in having let and get properties in the first place?

Thanks, Jebus
0
prasitleeCommented:
Dear dj__jebus,
   The way I am suggesting you is to create your own new Class Module instead of Type. This new class could be used instead of the public type you defined in the Module.
    Actually you do not need to create each property let and get for each variable. Each let and get property procedure was used to protect and filter the incorrect value into each property. But if you have a lot of properties and you do not need to provide each let and get property. You could define each of them as public variable so anyone who use this class can define and set any value into each property or pubic variable.
    All you need to do is to make a decision between get way to write the code easier but the value in the variable might not correct. So it 's your point to make a decision.
    Any further question, please let me know.
                                                                     Meng
0
wsteegmansCommented:
Normally, you don't want that a property (Get/Set) directly reflects the real data (your real variable). When creating classes and programming a bit object oriented, you hide your variables with the real data ...

A property is sometimes more then passing one variable holding a value (some processing, ...)

But in your case, to convert your user defined types (just holding data one to one), you can best use public variables, so you don't need the property let and get.

Also a quick way to create your classes (with real properties) is to use the Add-In Class Builder.

Regards!
0
dancebertCommented:
Let and Get properties allow encapsulation of code.  For example, you could make a class like this:

public HomePhone as string

Anyother class could read from it and write to it.

You could also make a class like this

private mHomePhone as string

Public Property Let HomePhone( byval RHS as string)

End Property


Public Property Get HomePhone() as string

End Property
0
wsteegmansCommented:
> There are just so many properties, I don't wanna have to write let and gets for each one,
> theres gotta be a better way..

To answer your real question. I'm afraid there is no better way. Because you can't use user defined data types in clases, you MUST build classes to do the same ...

Regards!
0
dancebertCommented:
Oops, I hit the wrong key, I wasn't finished.  

Let and Get properties allow encapsulation of code.  For example, you could make a class like this:

public HomePhone as string

Any other class could read from it and write to it.

You could also make a class like this

private mHomePhone as string

Public Property Let HomePhone( byval RHS as string)
    ' Validation code here
End Property


Public Property Get HomePhone() as string
    ' Formatting code here
End Property

By using Gets and Lets you can place the validation and formating logic with the data, so that any user of the class has property validated and formatted phone numbers.  With the first example, that of just a public variable, there is no validation or formatting so it has to be handled by each user of the class individually.  The former is OO, the latter is the usual structured programming chaos.


0
amebaCommented:
To have that syntax, you must declare your UDT in "public class module" - you can have public class module in ActiveX project (DLL or EXE), but not in Standard Exe.
So, change project type, add class - make sure it isn't Private, but Public (Instancing = 2, 5 or 6) and move UDT declaration to class.

Another solution which will work for Standard Exe: change "Public" to "Friend" in your methods, e.g.:
Friend Property Get PlanCorners() As Corners
0
Mike TomlinsonHigh School Computer Science, Computer Applications, and Mathematics TeachersCommented:
ameba is right with one extra stipulation.  You cannot pass a UDT ByVal, it must be ByRef.  So in your class you would put:

Private m_PlanCorners As Corners

Friend Property Get PlanCorners() As Corners
    PlanCorners = m_PlanCorners
End Property

Friend Property Let PlanCorners(ByRef v_PlanCorners As Corners)
    m_PlanCorners = v_PlanCorners
End Property

Idle_Mind
0
dj__jebusAuthor Commented:
This is my clsCorners, all those declarations:
Public C2xOS2 As Single
Public C2xOS16 As Single
Public C2xIS12 As Single

Then in clsPlan
Public PlanCorners As clsCorners


See now I'm trying to load them from my access db.

Public CN As ADODB.Connection
Public RS As ADODB.Recordset

    SQL = "SELECT * FROM PlanCorners WHERE PlanID='" & PlanID & "'"
    RS.Open SQL, CN
    objPlan.PlanCorners.C10xIS10 = RS!C10xIS10
    RS.Close

I get run-time error 3021 "Either BOF or EOF is true, or the record has been deleted. Requested operation requires a current record."  Whats the problem with that?


Thanks, Jebus
0
wsteegmansCommented:
> I get run-time error 3021 "Either BOF or EOF is true, or the record has been deleted.
> Requested operation requires a current record."  Whats the problem with that?

There seems no record where PlanID has the value of your variable PlanID.
Always, when using recordsets, check if the recordset isn't EOF (End Of File), which means we're after the last record. When opening a recordset, and it's immediately EOF, this means there are no records for the SQL-Statement.

So, change your code a bit, like this:

    SQL = "SELECT * FROM PlanCorners WHERE PlanID='" & PlanID & "'"
' - Because you just open your recordset to read, open it explicity as ForwardOnly and ReadOnly (much faster!)
    RS.Open SQL, CN, adOpenForwardOnly, adLockReadOnly
    If RS.EOF Then
        ' do some errorhandling, or just skip ...
    Else
      objPlan.PlanCorners.C10xIS10 = RS!C10xIS10
    End If
    RS.Close

Kind Regards!
0
dj__jebusAuthor Commented:
ok, so that fixed that, so I have in there:

    If RS.EOF = True Then
        objPlan.PlanCorners.C10xIS10 = 0
    Else
        objPlan.PlanCorners.C10xIS10 = RS!C10xIS10
    End If

It now says: "Object variable or With block variable not set."  How can this be?  objPlan works with other things everywhere else.

Thanks, Jebus
0
prasitleeCommented:
Dear dj__jebus,
    Are you sure that you have create the new instance of PlanCorners Object ? I feel that you are not instantiate this variable before use it.
    Try to new this variable first as the following code.
    Set objPlan.PlanCornets = new clsCorners
    Any further question, please let me know.
                                                                 Meng
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Delphi

From novice to tech pro — start learning today.