Class Module question.

L

Lee Taylor-Vaughan

Hi

Can someone please explain, in simple terms, what is the purpose of a class
module?

How does a class module differ from a regular module?

When is it appropriate to use a class module?

Thanks

Lee
 
A

Albert D. Kallal

A class module allows you to to create what is called a object. Object
orentation programming is all the rage to day.

While languaes like Java and .net are true Object Orentaiton languaes (OO),
both VB, and ms-access which share the same lanage are not true OO.

However, you can use some of the same ideas and concpets in ms-access, and
one of hte OO conepcts is the creating of your own ojbejct. You use a class
module to creae those ojbects.

I don't want anyone to all of sudden think that we must start using class
objects in ms-access. No more so, then one does in VB. They both are not
real OOP environments.

99 out of 100 times just a few well written functions and subs is
sufficient. The same goes for the VB environment. (in fact, there is no real
difference between VB and VBA these days anyway). Hence, I will be the first
to say that we don't need these objects very often.

However, I do strongly believe in their use when appropriate. I also believe
that they can have a substantial impact on reducing code, and even more so
on variable declarations. The reason why objects can reduce variable
declarations is because you can have multiple instances of the object. This
difference becomes critical, since now you don't have the problem of passing
variables between a group of functions and subs. It also means that you can
eliminate the problem of global variables. You can't have two instances of
global variables. With a object you can have two "sets" of those critical
variables that needs to be shared between a whole bunch of routines. Hence,
each object can operate independently, and not worry about global vars.

Generally, I use and create a class object when the process, or "thing" I am
dealing with starts to become very complex.

Hence, You don't really need a patient object for a medical billing system.
On the other hand, if you
need to execute several "processes" on a patient, then a object starts to be
come handy.

If the process on the patient is simply you entering a last visit date, and
then some report gets printed...then you can set-up a button and some code
to do this.

When you find that you need a lot of code AND data to compete a certain
procedure, then a class object start to make sense.

Hence, if for example you have a complex booking system that allocates
doctors to that patient, or you have to schedule certain tests that requires
booking to special rooms then a booking object, or a patient object can
really start to pay off. In fact, in this case..I would concentrate on
creating a booking object. In other words, when you need code that brings
together both a bunch of data, and a bunch of code procedures then a object
starts to make sense. Since booking people for limited time on a cat scan
machine, or special type of "procedure" room can start to get very complex,
then a booking object can "bring" the whole mess back down to a earth like
manageable task.

Remember, there is nothing in a object that cannot be done by standard
coding approaches. It is just that things start to get real messy after a
certain amount of complexity.

In addition, the other advantage of a object is that you can have more than
one instance of the object. This is really critical for certain kinds of
user interface. I have a tour booking system, and I created a tour booking
object. This screen allows you
to move people from one tour booking to another.

On the left side is one tour booking, and on the right side is another. Each
tour object has a zillion things like:

myTourObject:
The hotel name
The type of rooms at his hotel
The room rates for the particular season
How many rooms available
How many tour buses available
How many seats on each tour bus
Name of the tour bus company
How many corporate bookings are holding seats..but not yet used

The above list gets quite long. Each of the above "how many" questions is
in fact a bunch of code and queues to calculate the results.

Lets assume we have a booking record for a customer. Ok, lets display the
Tour name, and the hotel a user is booked into. Lets say the user is booked
to tourID 222 (this number just the simple internal autonumber for that
tour). To get the hotel name for this booking, I would have to do the
following.

dim rstTour as recordset
dim rstHotel as recordset

set rstTour = currentdb.openrecordset("select * from tblTours where tourid =
" & lngTourId
' ok...so now we have the tour, display the tour name

msgbox "tour name = " & rstTour!TourName

' now display the hotel name. The hotel name of course is simply a hotelID
in the tour

lngHotelId = rstTour!Hotel

set rstHotel = currentdb.openrecordset("select * from tblHotels where
hotelID = " & lngHotelId)

msbox "hotel name = " & rstHotel!HotelName

You can see what pain it is to just get the tour name, and the hotel name.
We have to deal with two related tables, build two queries, declare two
recordsets. Man, what a pain! We could perhaps use the dlookup function
above to reduce some code..but even dlookup becomes a real hassle here. We
also could use a query that is a relational join to reduce the above code.
However, there is a lot of additional things we need when working with the
tour.

Now extend the above to include the room type description (a another
table), the room rates (another table, and complex looking to a seasonal
pricing system). Grab the bus? Heck...this is becoming a night mare to
simply display a few things about the users booking.

Now, lets do all of the above with a class object. These properties of the
object are actual ones that I use:

' decleare a instance of our tour object

dim myTour as New clsRidesTour

myTour.TourId = lngTourId
' at this point, I can retrieve, and ask virtually anything I want about his
tour. So.

myTour.TourName returns the name of the tour
myTour.HotelName returns the name of the hotel
myTour.HotelSpace returns the space allocated in the hotel
myTour.HotelRooms returns the number of rooms in this tour
myTour.HotelRoomsUsed returns the number of rooms used

I will stop at this point, but to get the above simple answers with regular
coding methods..it will require at lest 50 lines or more of code? Yikes!! Is
not the above incredibly easy? Hey, lets get the space remaining in the
tour:

myTour.HotelSpaceRemain

How nice and easy it is to get the hotel space remaining. Not only that,
but inteli-sense works for all of the above..so I don't even have to
remember all the names of subroutines/code as I type.

And to get number of people on the bus for this tour..?

myTour.InBusTotal

Here is the code for above example in the class object for InBusTotal:

Public Property Get InBusTotal() As Integer

InBusTotal = 0
If m_rstBusList.RecordCount > 0 Then
m_rstBusList.MoveFirst

Do While m_rstBusList.EOF = False

InBusTotal = InBusTotal + Nz(m_rstBusList!InBus)
m_rstBusList.MoveNext

Loop
End If

End Property

Now, if you look at the above property of the object, you will notice that a
recordset m_rstBusList is already loaded. In other words, when I create and
set the myTour = "tour id", then all of the recordsets for bus company,
hotels, rates etc gets loaded into the object. Hence, the above code as a
result is MUCH BETTER then just writing a stand alone subroutine called "in
bus total". Since, a stand alone routine would have to still LOAD up a very
complex query into the recordset. I DON'T have to do that since the class
object is a collection of those reocrdsets and routines to give me the
"things" I need to know about a tour. The more you add code to the class
object...the more it simplifies the application. When you don't use a
object..the more code you write..the worse your application will get!
(ask your self, where would I put those recordsets? and how would I
SHARE THEM between each routine? I can't use global vars, since then
I would be restricted to working with ONE TOUR in memory at a time).

Anyway...you can see that the whole thing just becomes such a pain to code
simple questions about a tour. Create a tour object, and virtually anything
you need about that tour is ready made at your finger tips.

The following screen shot shows TWO instances of the tour object in use.
With traditional coding methods, this screen would be a night mare. Just
to get hotel rates, and hotelnames etc would be VERY difficult. The two
objects in use in this screen represent HUNDREDS of variable declarations.
(and I can have TWO in memory at the same time as the following example
shows).

Here is that screen shot...

http://www.attcanada.net/~kallal.msn/Rides/swap2.gif

(note that in the above example, the two bookings are for
the same tour..but they did not have to be..).

If you want to see more properties and methods of the tour object, you can
read my notes on this project. I also give out a few other neat tips on
reducing development costs. At the end of the article...you will find the
methods and properties of the class object listed. Check out:

http://www.attcanada.net/~kallal.msn/Articles/fog0000000003.html
 
G

GVaught

Good information Albert.

However, with .NET, VB is true Object Oriented and everything written uses
namespaces, classes, among other methods that only was available in C++, so
if you learn now the switchover isn't too bad. :)

Access is still Access.
 
L

Lee Taylor-Vaughan

Thanks... You certainly gave some good realistic information and you really
helped me find an answer to my question. (the examples you gave helped to
put it into perspective). Now i just have to think about when to use these
class and not keep writing out long code. for a novice this seem a cool
thing to do, but a difficult thing to recognise when to use it.

thanks again

lee

:)
 
K

Ken Ismert

My comments on Albert's post:

AK -- "Object oriented programming is all the rage to day"

Well, yes, because OO is an extremly effective method for organizing
and managing large, complex development efforts. It has become as
fundamental to coding as the relational data model is to table
structures.

AK -- "both VB and ms-access, which share the same language, are not true OO."

VB6, and its equivalent, VBA (for A2K and later) are actually pretty
powerful Object-Oriented languages. Look what they support:

* True Instancing
* Formal Interfaces
* Events
* Initialize and Terminate
* Methods and Properties
* COM (limited in VBA)

In VB, your objects can use Encapsulation (the binding of data and
code together), as well as Abstraction and Polymorphism, especially if
you define it through Interfaces. You can design quite elaborate
object Collaborations in VB. VB has enough object power to keep you
busy for a long time.

Purists will argue that VB is limited, and they're right. Among other
things, VB doesn't support:

* Inheritance
* Overloading of Property names

VB.NET supports these features. It is fair to say that VB6 is a
procedural language with object features grafted on, while VB.NET is a
from-the-roots-up object-oriented language. In VB.NET, everything is
an object.

AK -- "Remember, there is nothing in a object that cannot be done by standard
coding approaches."

Well, you first would have to exclude Events and formal Interfaces,
which flat out aren't supported in standard code modules. Events give
you a handy way to send and receive messages from other objects.
Interfaces allow you to enforce standard ways for objects to interact
with one another.

That aside, the threshold at which a procedural implementation becomes
infeasible compared to an object approach can be quite low. Take the
implementation of simple data structures like a stack, or linked
lists. The coding and use of object implementations of these
structures are vastly simpler than any procedural approach.

Or, take the mundane problem of initialization. Setting up global
initialized settings for an Access app can be quite a chore if done
purely procedurally. Objects, with their Initialize and Terminate
events, make initialization and cleanup much easier.

Properly done, object implementations are not only easier to use, but
more flexible than their procedural counterparts.

AK -- "Generally, I use and create a class object when the process,
or "thing" I am dealing with starts to become very complex."

That is one criteria for considering an object. Some others are:

* Your thing needs to have State, i.e. to remember its settings
between uses.
* You need to have an indeterminate number of things active at once.
* You need to trap events from another object
* You want to make repeated use of small mundane tasks simpler and
more consistent.
* You need to support different variations of the same kind of thing,
like OS versions, different databases or data access methods.
* Your thing needs to have consistent setup and shutdown procedures

AK -- "Create a tour object, and virtually anything you need about that tour
is ready made at your finger tips."

With his Tour object, Albert has provided quite a good example of
encapsulation, the binding of data and code together. This is a very
useful class of objects for the Access programmer, and are a good
place to start your exploration of object programming.

-Ken
 

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