jwcolby
jwcolby at colbyconsulting.com
Mon Feb 16 08:47:10 CST 2009
One of the big uses of Classes and Events is to build wrappers around existing Access objects, with the purpose of making those existing objects behave consistently in a manner that we (the developer) want them to behave. An application should behave consistently so that the user can "know" that if something works like this over here, it will work like that over there. Access gives us Events for almost all of the objects such as forms, combos, text boxes, radio buttons etc. but it is our business what those events are used for. While it is pretty easy to figure out a behavior that we want some object to perform, getting it consistent across our application is tougher. As an example, take the combo box. There is an event called NotInList. When this event fires it means that the text typed into the combo box does not match any of the objects in the list behind the combo. That is incredibly useful in some instances, we can use the event to display a message to the user informing them that the item does not exist in the list and asking them if they want to add the item. Or, we can inform them that they are not allowed to add any more items to the list - think state table, gender table and others where the list is simply not allowed to change. One problem however is that the list might need to have more than one piece of information (field) added to the table. So if the list pulls from a table where there is only a single field to be added, then a simple response is in order: • Inform the user that the item is not in the list. • Ask the user if the item should be added to the list. • If yes, then add the item to the list. • And requery the combo box If the table behind the list has more than a single field things get more complicated. However we still need a consistent response, we just need a different consistent response. • Inform the user that the item is not in the list. • Ask the user if the item should be added to the list. • If yes, then open a list form to allow adding the data to the list. • Place the form in AddNew • When the form closes, requery the combo box. Now, there is nothing in all of that that could not be handled in a complex function, the function placed into a module and a call to the function placed in the event NotInList handler in the form’s class. So why use a class for this behavior? The answer lies in programming techniques. Until you have classes available as a tool, you cannot use these techniques so you don’t think to use them. Once you understand classes, you have the tools and will start thinking about when to use these techniques. As I have mentioned before, one of the objectives of a good programmer is to place code and data together in one place, a technique called “encapsulation”. This not in list event is a great example of having data and code requirements which need to be kept together. In order to handle the NotInList we need: 1. The table and field name to place the data in if this is a “simple” event (only a single field to add). 2. The form name to open if this is a non-simple event (multiple fields to store). 3. An event sink to sink the NotInList event and start the processing 4. The code to figure out what to do for this specific NotInList event for this specific combo. A class allows you to do all of this in one place. You can build a clsCtlCbo (we already have), then when we decide we need a new behavior, we have a single place to go to add the event stub, the storage for data for our behavior, and the code for our behavior. When you design the next behavior, you go back into the same class, add another event stub (if you are sinking a new event), new variables to store the data required for the new behavior, and new code for those new behaviors. I have another behavior in my clsCtlCbo where the user can dbl-Click to open the list form in Edit mode. If the user is looking at data in the combo and sees an error in the data, (s)he can dbl-Click to open that same list form, but this time in Edit mode. The code needs to move the form to the data record that the user is looking at in the combo box. Again, when the form closes, the combo needs to be requeried. As you can see, we have a completely different event being hooked, similar information (form name) but different code. Equally important however, setting up all of these behaviors becomes as simple as dimensioning the object (the clsCtlCbo) and setting properties of the clsCtlXXX. After that any and all events that should behave in a certain way do so. The events stubs for that object aren’t cluttering up the form’s class module, and the object (combo) behaves consistently across your entire application. Suddenly the OnOpen event of the form becomes a very busy place where you start programming all of the combos to handle their NotInList and other objects (JustInTime subform loading of tabs?). You have ONE place to go to look at what is being programmed. No longer do you have to go hunting for the event stub for 5 different combos to see how you handled them. Just look in the OnOpen of the form. Are they mentioned there? If not, they aren’t programmed yet. Not only have you made your application interface consistent, you have made your programming of the interface consistent. In the next few lectures I will be creating some new object wrapper classes for objects that we haven’t started handling yet, and adding behaviors to those objects to let us do some really useful things. I will demonstrate how to program your application’s interface (objects on a form) from the form OnOpen. I will demonstrate how to tie each clsCtlXXX into the form’s control scanner such that these classes load automatically. Once we do that we will build a property to the form class for each wrapper class such that you can get at all of the object classes directly, by name, and program the object classes back in the form. This is the fun stuff! Even better, you guys get to invent your own behaviors and add them to your application interface (share the ideas with the rest of us?). As we work through these next few lessons you will understand exactly how to go about doing this in a consistent manner. Your applications will start to straighten around and work the way you want, every time. You will be able to retrofit existing applications to use these behaviors simply by referencing a library (how to do that is coming up) and programming each form to use the new system. I hope that now you begin to understand why I am such a strong proponent of classes. They are the tool that moves you from programmer to application interface designer. I really need those of you who are working through this stuff to speak up and let me and others know how you are finding these lectures. Is this stuff easy to learn? A tad difficult but doable? Pretty tough? Suggestions to make it easier to learn. There may be people who still aren't tackling this stuff because they think it is just too hard. My desire is to show everyone that any programmer can learn and understand classes and events. If I am not making it easy enough, I need feedback on what to do to make it easy enough for any programmer to learn. Thanks for sticking with me on this. -- John W. Colby www.ColbyConsulting.com