Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Good book on using Class objects in Access?

124 views
Skip to first unread message

Pieter Linden

unread,
Mar 12, 2003, 11:50:39 PM3/12/03
to
Hi,
I was wondering if there was a good book out there on using class
objects in Access to separate business logic from form design etc. I
already have Peter Vogel's book, which is OK, but doesn't really
answer the question for me. (Okay, what was the question again?)

I'm trying to get my head around classes in VB/A. While I understand
the basics of it, I was looking for something that would describe
things like:
(a) WHEN to use classes in your app (tell tale signs, maybe?)
(b) HOW to use them
(c) what kinds of things you can do with them

is this covered in Access Cookbook? (Or anywhere else?) The coverage
of classes in ADH2000 was not really helpful in that respect. No
complex data validation, no rules for interaction between objects -
like customers and invoices (say something like "Any customer of type
X may not make any more charges if their outstanding balance is over X
dollars.") I know you can do that in the BeforeInsert event of the
form, but then all the validation is totally based on the form.

Or am I thinking about classes in totally the wrong way?

Thanks,
Pieter

Albert D. Kallal

unread,
Mar 13, 2003, 12:53:30 AM3/13/03
to
Generally, I use and create a class object when the process, or "thing" I am
dealing with starts to become very complex.

Lets assume we have a system for patients that visit a clinic.

Hence, You don't really need a patient object. 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. You are done.

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 certainly kinds of
user interface. I have a tour booking system, and I created a tour booking
object. If you take look at the screen shots about half way down in the
following link...you will see a room swapping screen. 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
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:

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 requite 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. Note 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 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 along 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!

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 screen shot (it is half way down" that uses *two* instances of the class
tour object) can be found at:

(it is the "room swapper screen") check out:

http://www.attcanada.net/%7ekallal.msn/Rides/Rides.html

If you want to see more properites 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 proptiers of the class object listed. Check out:

http://www.attcanada.net/%7ekallal.msn/Articles/fog0000000003.html


--
Albert D. Kallal
Edmonton, Alberta Canada
kal...@msn.com
http://www.attcanada.net/~kallal.msn


Pieter Linden

unread,
Mar 13, 2003, 7:32:37 PM3/13/03
to
Cool! Thanks for taking the time to write a complete answer, Albert!

I appreciate it,

Pieter

Román Valoria

unread,
Mar 13, 2003, 10:51:44 PM3/13/03
to
OK Albert, well explained.

But what about the original book question? I also find myself looking
for books about that, but I have not seen anyone explaining it
PRACTICALLY.

OK, I know the theory, but HOW actually I code it.

I thougt that a good approach will be to have the same project
resolved using both approaches and there you could really see the
difference.

Thanks Again.

Mark Johnson

unread,
Mar 14, 2003, 2:39:58 AM3/14/03
to
"Albert D. Kallal" <kal...@msn.com> wrote:

>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.

For various fields, a class has the advantage of loading the entire
recordset once for all, and for making any modifications, and then
making the results both logically more clear and more easily available
to any other object than, say, if tied to the class module of a
particular form?

But is it true that any reference to a table means that the table is
loaded for the class? So if four tables are mentioned in the class
module, does that mean the four tables are placed in memory, and
become 'replicated', and distinct, from the tables stored elsewhere.

Brendan Reynolds

unread,
Mar 14, 2003, 8:28:28 AM3/14/03
to
I don't know of any book that specifically targets that subject, but two
books that include considerable coverage of the use of classes in Access,
along with other programming topics, are ...

The Access 2002 Developer's Handbook (or Access 2000 Developer's Handbook)
by Ken Getz et all, published by Sybex, and Programming Microsoft Access
Version 2002 (I think there's a 2000 edition too) by Rick Dobson, published
by Microsoft Press.

Ken Getz has also written many articles on the subject, some of which should
be available on-line. I don't have any specific links to hand at the moment,
but a web search using Ken's name should turn up some links.

--
Brendan Reynolds
bren...@indigo.ie

"Román Valoria" <romanv...@hotmail.com> wrote in message
news:a12bc996.03031...@posting.google.com...

Pieter Linden

unread,
Mar 14, 2003, 7:54:04 PM3/14/03
to
Thanks, Brendan.
I have ADH2000 Desktop. The coverage of classes is not really as
business objects, which is more what I was looking for. I'll have a
look at ADH2002 nd Rick Dobson's book and Ken Getz's articles.
Pieter

Brendan Reynolds

unread,
Mar 15, 2003, 5:47:34 AM3/15/03
to
I think you'll find that the way classes are used in the other sources I
mentioned is not very different from the way they're used in the ADH 2000,
Pieter. For the use of classes as business objects, you might perhaps do
better looking at VB sources.
--
Brendan Reynolds
bren...@indigo.ie

"Pieter Linden" <pietl...@hotmail.com> wrote in message
news:bf31e41b.03031...@posting.google.com...

Steve Jorgensen

unread,
Mar 15, 2003, 4:23:06 PM3/15/03
to
This seemed like a good point to share something I've recently done with class
modules and interfaces in Access 2002 (Interfaces were not supported in Access
prior to 2000).

I had some code that I wanted to be able to either test from the Debug window or
run from a button on a for, and I needed a progress report for output that would
be appropriate to the context in which it was run. The solution I decided on
was to have the function accept an optional argument of ILogWriter type where
ILogWriter is a class module containing a function to print a message (with no
body since this class is just the interface).

Next, I defined a class clsLogWriterDebug that implements the function defined
in ILogWriter and prints the message to the debug window. If no log writer is
passed to the function, it creates an instance of clsLogWriterDebug, and uses
that. Now, when I'm ready to call this form a form with its own log window, the
form itself can implement ILogWriter, and pass itself (Me) to the function.
Then the form's function for printing log messages will be called by the
function, and the form can handle message output any way it wishes.

In total, the code to implement all this is probably shorter than this reply.

Albert D. Kallal

unread,
Mar 16, 2003, 2:53:04 PM3/16/03
to
"Mark Johnson" <1023...@compuserve.com

> For various fields, a class has the advantage of loading the entire
> recordset once for all, and for making any modifications, and then
> making the results both logically more clear and more easily available
> to any other object than, say, if tied to the class module of a
> particular form?

Sure, it does. But I have a lot of forms that actually use my "tour" object.
However, if you have a form with 3 sub forms, then you have access to all
the 3 recordsets anyway. It is only when you need a whole bunch of
recordsets from other tables, and some code to process those reocrdsets does
the use of a class object really help.

>
> But is it true that any reference to a table means that the table is
> loaded for the class? So if four tables are mentioned in the class
> module, does that mean the four tables are placed in memory, and
> become 'replicated', and distinct, from the tables stored elsewhere.

That class object is just regular code, and regular reocrdsets. So, no, the
data is just loaded into regular recordsest. In my example, the problem was
that a "tour" represents quite a few reocrdsets, and it was getting
*extremely* messy in code to deal with "one" tour. I could have used regular
code, but each time I starting trying to a something simple, I had to start
declaring tons of variables, and tons of reocrdsets. So, any table mentioned
here is just regular recordset loaded. Nothing special is going here.

The real key as mentioned is when you need some data *and* code together. If
you just need some data, or just some code, you probably don't need a class
object.

0 new messages