Solved

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

Posted on 2003-11-29
17
889 Views
Last Modified: 2013-11-23
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
0
Comment
Question by:dj__jebus
  • 5
  • 4
  • 4
  • +3
17 Comments
 
LVL 7

Expert Comment

by:wsteegmans
ID: 9844073
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
 

Author Comment

by:dj__jebus
ID: 9844076
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
 
LVL 6

Expert Comment

by:prasitlee
ID: 9844083
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
 

Author Comment

by:dj__jebus
ID: 9844088
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
 
LVL 6

Accepted Solution

by:
prasitlee earned 225 total points
ID: 9844097
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
 

Author Comment

by:dj__jebus
ID: 9844102
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
 
LVL 6

Expert Comment

by:prasitlee
ID: 9844113
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
 
LVL 7

Expert Comment

by:wsteegmans
ID: 9844115
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
Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 9

Expert Comment

by:dancebert
ID: 9844116
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
 
LVL 7

Expert Comment

by:wsteegmans
ID: 9844123
> 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
 
LVL 9

Expert Comment

by:dancebert
ID: 9844130
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
 
LVL 15

Expert Comment

by:ameba
ID: 9844213
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
 
LVL 85

Expert Comment

by:Mike Tomlinson
ID: 9844407
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
 

Author Comment

by:dj__jebus
ID: 9844504
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
 
LVL 7

Expert Comment

by:wsteegmans
ID: 9844852
> 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
 

Author Comment

by:dj__jebus
ID: 9844893
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
 
LVL 6

Assisted Solution

by:prasitlee
prasitlee earned 225 total points
ID: 9845047
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

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

If you have ever used Microsoft Word then you know that it has a good spell checker and it may have occurred to you that the ability to check spelling might be a nice piece of functionality to add to certain applications of yours. Well the code that…
Enums (shorthand for ‘enumerations’) are not often used by programmers but they can be quite valuable when they are.  What are they? An Enum is just a type of variable like a string or an Integer, but in this case one that you create that contains…
Get people started with the process of using Access VBA to control Outlook using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Microsoft Outlook. Using automation, an Access applic…
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…

705 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now