[AccessD] Log Class part 1B

JWColby jwcolby at colbyconsulting.com
Sat Jan 6 22:39:01 CST 2007


Yes!  Maybe.  If you are talking about a callback function then the answer
is "damned tough".  However for objects like forms and controls....

That is exactly what I have been talking about for the last few years.  I
call these classes "wrappers" because they wrap up the functionality of an
object, and then allow you the programmer to "extend" the functionality of
the wrapped object.

I have a clsFrm, a clsCtlCbo, clsCtlTxt, clsCtlCmd, clsCtlChkBox etc.  As
you can tell from the name, each class "wraps" some native Access object
such as a form, a command button, a combo etc.  My classes then add
functionality that I find useful for those objects.  My form class has a
control scanner which scans the form as it opens looking for controls.  That
"scanner" is functionality that I find useful and have added in my form
class.  The scanner then loads a clsCtlCbo for every combo object it finds,
a clsCtlTxt for every text box etc.  Each of these classes provides me a
place to store code to implement functionality that I find useful for those
objects.

As an example, I find it useful to have the clsCtlCbo sink the combo's
DblClick event and open a form for editing the list behind the form.  In
order to enable this behavior, I simply feed the clsCtlCbo a DblClick form
name, into a string property.  If the property holds a form name, then when
the dblclick event occurs, my code opens that form.  Of course it does much
more as well.  For example if a combo has been fed a form name to open, then
the dbl-click will open that form.  I cause the labels for the combo to
change background color as a visual cue to the user that the form can be Dbl
Clicked and something will happen.  They have to learn that rule, but once
learned, it works the same in every form (that uses the form class), in
every application.

When controls such as text boxed and combos get the focus, I cause my
control class to change the background color so that the user can tell that
control has the focus.  And the list goes on and on.  

All these things are behaviors that I think are useful, and so I include
them in MY control classes.  Thus every one of my projects just
automatically has the ability to DblClick a combo and have a form open to
edit the combo's list, have text and combos change background color when
they get the focus etc.  Every form, every project.  I believe that kind of
consistency is critical to making a project usable.  The user should be able
to see, "oh, the label for this combo is a different color... That means I
can double click it and open the form.

Of course my framework also has what I call LWS (light weight security) so
that the application can determine which groups users belong to, and the
application can decide which user groups see the label change color and can
dbl-click the combos to edit the list tables.

All automatically, every form, every application.

Once you understand the concept, once you start creating your framework,
then your imagination can take over.  Want an audit trail?  Every control
already has a class, automatically loaded by the form class.  Between the
form class and the various control classes, you have the tools to create an
audit trail behavior.  I can log what users log in to what workstations,
what forms open, what controls get the focus, what data is edited, what
reports are run, all neatly date stamped.  Turn it on and off with SysVars.

Do you want the ability to have user groups be able to see and edit specific
forms, and controls in forms?  Once you have a form class and control
classes, you have the tools to implement a Light Weight Security
functionality.  Need data logging to files on the disk?  Need emails to an
admin when errors occur?  Need to be able to turn on / off functionality in
the framework or the application?  Ever hear the term SysVars?  All these
kinds of things are things I call service classes, and all these things
exist in my framework.   

Write once, use forever, you applications become consistent throughout (and
EXTREMELY powerful).  But it is not the application providing the power, it
is your framework.

That's how I do it.  

John W. Colby
Colby Consulting
www.ColbyConsulting.com

-----Original Message-----
From: accessd-bounces at databaseadvisors.com
[mailto:accessd-bounces at databaseadvisors.com] On Behalf Of Jim Lawrence
Sent: Saturday, January 06, 2007 4:46 PM
To: 'Access Developers discussion and problem solving'
Subject: Re: [AccessD] Log Class part 1B

Hi John:

The last group of messages forms an excellent reusable class. 

As you are so skilled in Access class design, I would like to pose a class
related question. Can a MS Access class, like the class used to populate
lists and combo boxes be encapsulated within a user defined/managed class?
If this is not clear I will supply code off-line as it is a little large for
the list.

TIA
Jim    

-----Original Message-----
From: accessd-bounces at databaseadvisors.com
[mailto:accessd-bounces at databaseadvisors.com] On Behalf Of JWColby
Sent: Saturday, January 06, 2007 10:14 AM
To: 'Access Developers discussion and problem solving'
Subject: [AccessD] Log Class part 1B

BTW, for those of you who follow the concept of a framework, I have a
framework object which is itself a class.  I have now built a new method of
the framework object that can initialize these log files and hold them in a
collection.  Given that my apps all use the framework, syntax becomes:
    
    cfw.log("MyLogName").Init("C:\Dev\DISNEW\", "Test", "LOG", "YYYYMMDD",
"HHMMSS")
    cfw.log("MyLogName").Log "Write some test text"
    cfw.log("MyLogName").Term        'closes the log file and unloads it
from the framework collection
 
Notice that this syntax looks strikingly similar to the syntax you would use
to work with any other object such as the database object, the form object
etc.  My framework is just an object, with methods and properties.
 
The first line causes the framework (cfw) to create an instance of the log
class, initialize it with the filespec information, and store a pointer to
the log class instance in a collection for future use. The second line uses
a previously initialized log class instance to write text.  The last line
unloads the class from memory and the collection of log files available for
use.
 
Doing things "the framework way" allows me to create a ton of log files as
required.  For example:
 
'
'From inside of the ULLICO export process class I call the framework and set
up two log files.
'
    cfw.log("ULLICOExport-Error").Init(C:\Dev\DISNEW\Export\ULLICO\",
"ULLICO-Error", "ERR", "YYYYMMDD", "HHMMSS") 
    cfw.log("ULLICOExport-Data").Init(C:\Dev\DISNEW\Export\ULLICO\",
"ULLICO-Data", "DAT", "YYYYMMDD", "HHMMSS")
 
'
'From inside of the HV Export class I call the framework and set up two log
classes.
'
    cfw.log("HVExport-Error").Init(C:\Dev\DISNEW\Export\HV\", "HV-Error",
"ERR", "YYYYMMDD", "HHMMSS") 
    cfw.log("HVExport-Data").Init(C:\Dev\DISNEW\Export\HV\", "HV-Data",
"DAT", "YYYYMMDD", "HHMMSS")
 
Now I have two different processes (a ULLICO export process and a HV export
process), each using two log files.  The Error log file is used to log any
processing errors that the export process runs into.  The Data log file is
the actual data file that is being assembled by the export process.
 
BTW, It took me almost as long to write this email as it did to write the
log class and hook it into my framework.  Classes are simple to write and
use once you understand them.  A framework magnifies the effectiveness of
service classes such as this log class enormously, making them dead simple
to set up, use and tear down.  
 
That's how I do it.
 
John W. Colby
Colby Consulting
www.ColbyConsulting.com




More information about the AccessD mailing list