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