Programming with Class, Part 214 Dec, 2004 By: Mike Tuersley Cadalyst
Going a step further with those often-unfamiliar yet very useful class modules
Last month I introduced the Class Module (click here for column archives), and this month I am going to expand upon it. To refresh, a Class in layman's terms is a user-defined programming object. It is just like an internal VBA or AutoCAD object -- it can have properties, methods, and events.
I've started with the TitleBlock example from last month and have expanded it to include more functionality (figure 1). I couldn't talk my editor into posting all the code for the project within this document, so download the code from last month. It might help you to download the sample project now, so you have it loaded as you read this after opening the example, be sure to add references to Microsoft VBScript Regular Expressions v5.5 (or later) and Microsoft ActiveX Data Objects v2.8 Library (or later) if they are missing. This project also uses an Excel spreadsheet to store data, so you must change its location within the TitleBlock class module's Read_Excel function.
Figure 1. Completed class example project.
Example Project Scope
Last month, the code wrote the values stored by the class module to a text box to demonstrate how the class module worked. This month, the TitleBlock class has methods that will do a lot of the work for this project. Remember, one of the reasons for using class modules is to simplify your code. When completed, this class module can be sent to another programmer, and all he needs to do is add it and use it. He doesn't need to understand how to access an Excel spreadsheet through an ADO connection or how to retrieve the logged-in user's name through the Windows' API. To demonstrate, here is all the code from the basic module that runs this program:
Option Explicit Public oTb As Titleblock Sub Test() Set oTb = New Titleblock Dim vTmp As Variant Dim iIndex As Integer Dim oForm As New UserForm1 Load oForm With oForm For Each vTmp In oTb.Drawings .cboDrawings.AddItem vTmp Next .txtShtTitle.Text = .cboDrawings.Text & _ " - " & .cboDwgType.Text oTb.DwgTitle = .txtShtTitle .cboDrawings.ListIndex = 0 .txtDrwnBy = oTb.UserInitials .Show End With End Sub
The code for the module is short and clean. I start by declaring a public instance of the TitleBlock class. Then, I set it to a New instance remembering that using the New command within the declaration statement is not a good idea with classes. If the New is within the declaration, the class is not initialized until a reference is made to it. Using the separate Set line with New initializes the class then, so it is populated with information. To see about this, set a break point immediately after the Set line, or add a watch to oTB, and check out the information that has been populated at that point to the TitleBlock object. Then look at the CLASS_INITIALIZE event within the TitleBlock class module. Within the Initialize event, I:
- Set up my ADO connection
- Retrieve the user name from the Windows login through the API
- Query the Excel spreadsheet for the user's initials
- Retrieve the "base" drawings
- Preset the drawing discipline to Architectural and retrieve its "base" drawing types
- Set the drawing number's alpha value
Opening the TitleBlock class module and looking at its code, you might notice a command that you haven't seen before now. Friend is a declarative scope statement just like Private and Public. Everyone should know the difference between the two, but in case you don't:
- Private: This restricts the visibility of the object to the module within which it was declared.
- Public: This opens the object's visibility to everything -- within the creation module, to other modules within its host project, and to any projects that reference the host project.
Friend Function ReadDataBase() As Recordset
In my project, TESTCLASS.DVB, I add a module. From this module, I can access the ReadDataBase method of my class object. This is just as it would be if I declared ReadDataBase using Public. Now I create another project called TESTCLASS2.DVB, and I add a reference to TESTCLASS.DVB. From the new TESTCLASS2.DVB, I cannot access the ReadDataBase method. (Note: Friend can only be used in Class modules or forms, not basic modules.)
Here's a reoccurring scenario. My program needs to keep making decisions based on a particular state. If it's a black-and-white situation, a public Boolean value will suffice. But rarely are situations black-and-white -- usually they are varying shades of gray! A typical solution would be to create a public integer value and keep testing it. This too works well, providing I remember the meanings of all the possible integer values. But what happens if someone else works on my project? Will they know the values' meanings that I've put to memory? Of course not!
A better method for tracking something with more values than true/false is using Enums (enumerated constants). With this Class project, I wanted to track which drawing discipline the user chose because the discipline controls the drawing types, drawing number prefix, and the SQL statement for retrieving the drawing types from the Excel spreadsheet. So, with Frank's help, I decided to use Enums. (Thanks, Frank!)
Public Enum dwgDiscipline Architectural = 1 Electrical = 2 HVAC = 3 Plumbing = 4 End Enum
The syntax is simple. Just declare the Enum with a unique name, then define its possible constant values. The constant values must evaluate to a long data type -- no strings, integers, or other such values. Once declared, these values are available through Intellisense.
Now I, or any other programmer looking at this code, will know what I'm testing without the typical trial-and-error, hunt-and-peck methods of trying to read the original programmer's mind.
Kick It UP a Notch!
This wraps up a two-month blitz on the Class module. I hope I've met my goal of getting readers comfortable with Class modules. If so, you won't really need this month's Kick It Up a Notch! Those who feel more comfortable will dive right in and extend the functionality of their projects. For those still on the fence, do some research on the Internet or at your public library. Both have plenty of Visual Basic resources that present different approaches to learning and using Class modules. Take care until next month!