Bill Patten
bill_Patten at earthlink.net
Fri Jun 9 11:48:03 CDT 2006
Thanks Drew, this is just what I was looking for. You are a classy guy... Pun intended. Bill ----- Original Message ----- From: <DWUTKA at marlow.com> To: <accessd at databaseadvisors.com> Sent: Friday, June 09, 2006 9:32 AM Subject: [AccessD] Basic Unbound Form with Classes and Collections Part 1. I will do this demo with Access 2000 (97 will be a little different). Let's start with a blank database. We'll add a table called tblPeople with the following fields: PersonID (AutoNumber) (Primary Key) FirstName (Text) LastName (Text) Now we want to create a class module. (Again, in 97 this is a little different). The best way to do this (without creating a blank module that you'd have to remove) is to click Tools--> Macro --> Visual Basic Editor. You are now in the Visual Basic Editor. We need a Class Module, so click Insert --> Class Module. (You will note that Class modules and Basic Modules have different icons. There should be a tool bar with the Access icon a basic module icon and your save icon. That basic module one has a drop down, which will also let you create a new class module. (To do this in 97, you have to start with a new basic module, which you can remove later, but when you are in a code page in 97, that is when you will get the option to create a new class module.) This new module will be called Class1 by default. Let's change the name (in the properties pane) to Person. Now, in the code page of our Person Class, let's add the necessary properties. Our table has three fields, so we'll create three easy properties, and a fourth which will be derived. So, in the code page type the following under the 'Option Compare Database' line: Public ID As Long Public FirstName As String Public LastName As String We also want to create a 'Full name' property, which is going to be a combination of the first and last names. For now we are going to leave this property as read only. Put the following procedure in your class module: Property Get FullName() As String FullName = FirstName & " " & LastName End Property See what we have done? We now have 4 properties, ID, FirstName, LastName, and FullName. The first three can be read and written too, the last one is read only. For a simple value only property using the Public declaration in a class module allows a simple variable to be a property all on it's own. However, you can create more complex properties using the Property Get and Property Let statements. We used the Get statement to provide the FullName property, but if we wanted to make that property writable we would use a let statement. I'll do that in the intermediate example. We now have a class to represent a person in our database. Now let's create a class to represent all of the people in the database. Create a new class, and name it People. (Follow the same steps we used to create the Person class). We are going to create to collections of Persons in our People class. One will be sorted by first name, one by last name. Here's how we are going to do it, first we are going to dimension the collections. Below the Option Compare Database, put the following: Dim PeopleByFirst As Collection Dim PeopleByLast As Collection Now we need to create a procedure to fill these collections. Create the following procedure: Private Sub GetPeople() Dim rs As ADODB.Recordset Dim strSQL As String Dim ps As Person Set PeopleByFirst = New Collection Set PeopleByLast = New Collection Set rs = New ADODB.Recordset strSQL = "SELECT PersonID, FirstName, LastName FROM tblPeople ORDER BY FirstName" rs.Open strSQL, CurrentProject.Connection, adOpenKeyset, adLockReadOnly If rs.EOF = False Then rs.MoveFirst Do Until rs.EOF = True Set ps = New Person ps.ID = rs.Fields(0).Value ps.FirstName = rs.Fields(1).Value ps.LastName = rs.Fields(2).Value PeopleByFirst.Add ps, "ID:" & ps.ID Set ps = Nothing rs.MoveNext Loop rs.Close Set rs = Nothing strSQL = "SELECT PersonID, LastName FROM tblPeople ORDER BY LastName" If rs.EOF = False Then rs.MoveFirst Do Until rs.EOF = True Set ps = PeopleByFirst("ID:" & rs.Fields(0).Value) PeopleByLast.Add ps, "ID:" & ps.ID Set ps = Nothing rs.MoveNext Loop rs.Close Set rs = Nothing End Sub A few things to note in this procedure. First, we initialize the collections we have dimensioned in the class modules header. We also pull the recordset up the first time and let ADO/Jet sort the initial list by FirstName. We then add all of the people to the collection in the order provided by the recordset. Note that when we add it, we give it the 'ps' object as what we are adding, but the second argument is a custom ID. Collections can be recalled by the order in the collection (ie, PeopleByFirst(1) would give you the first person in the collection), or by the custom (and unique) id that you give it, which we do in the second loop (PeopleByLast("ID:" & rs.fields(0).value)). In the second loop, we are again letting ADO/Jet sort things for us, but we aren't creating any more Person objects. A Collection is really a set of pointers to objects, so you can have 1 object in several different collections. The advantage to this is that if you change an object that is in multiple collections, referencing it from any of those collections will show the change. ie, if we Change Bob Smith to Bobby Smith, both collections (sorted by first and last name) will reference the new 'Bobby Smith' object. A point is simply a long integer, so if we were dealing with larger class objects, we wouldn't suffer from having duplicate objects in memory. Now we need to set it so this class initializes itself. In the top left of the code page, you should see a drop down that currently says (General), this is your object drop down (it lists the objects this code page/class sees). Select the only other option in there (right now) 'Class'. It will change the right side dropdown to 'Initialize', which is one of two events every class has. (The other event is terminate). You should now have a 'Private Sub Class_Initialize()' procedure. we just want it to run our GetPeople routine, so type that in there, it should look like this: Private Sub Class_Initialize() GetPeople End Sub I will continue in another email (to keep the size of this down a bit) Drew -- AccessD mailing list AccessD at databaseadvisors.com http://databaseadvisors.com/mailman/listinfo/accessd Website: http://www.databaseadvisors.com