Separate speaker notes to accompany presentation on classcollection:

Slide #1:

This accompanies the program SAVACCT04 which deals with class, collection, error handling etc. In the middle of this presentation, there are a series of slides that just show code. The analysis of that code follows.

Slide #2:

This program keeps track of transactions by account. When Display Transactions is clicked, the transactions for the active account appear in the list box.

Note that I have created two accounts (the accounts are displayed in the left window). The transactions shown are for the account that I retrieved by clicking on the Retrieve Account button.

Slide #3:

This code shows the establishment of the transaction collection associated with the individual account.

This slide shows the Balance and IntRate, but not the Account Number which was added to SavAcct when I developed the SavAccts collection so that I could get access to individual accounts. The account number is shown on the next slide.

Slide #4:

Account numbers should not be changed. If you need to change an account number, you should delete the account and add a new account.

Note that static means that AcctNbrSet is not reset when the the Let is executed. "Variables declared with the Static statement retain their values as long as the code is running." from Microsoft VB help

Note that Static could also be declared by doing:

Public Static Property Let etc. In this case, Static "Indicates that the Property Let procedure's local variables are preserved between calls. The Static attribute doesn't affect variables that are declared outside the Property Let procedure, even if they are used in the procedure." from Microsoft VB help

Slide #5:

This is the code to return the transaction collection. It is what gives you access to the Transactions collection for an account.

The AS clause defines the data type and in this case we want to return an object that is a data type transactions collection.

Slide #6:

This slide shows the methods associated with SavAcct. Note that in each of these, I add the transaction to the collection associated with that account.

Slide #7:

When a deposit is made using the Deposit Method in SavAcct, it sets up the information for the transaction that will become part of the transaction collection associated with the account. It passes the account number of the active account, the type of transaction (in this case DEP) and the amount of the transaction to the Add in the Transactions collections when the colTransactions.Add is issued.

In the code of the Transactions collection, this data is received and a new transaction number is created. Then the information is used to set up a new transaction which is added to the Transactions collection.

The same applies to the withdrawal and posting interest methods.

Slide #8:

Now we need to look at the Transaction class. It contains the properties of the class and the Let and Get property procedures.

This slide shows the module level variables associated with this class. Notice again that they are defined as private so they are only accessible through the class module. It also shows a Get and Let property procedure associated with each of the properties of the Transaction class.

Slide #9:

I will deal with errors at the end of this presentation. For now look at the code in the SavAccts collection. I define colSavAccts as Collection and instantiate it in the Class_Initialize. This shows the Add that is executed when a new account is added to the SavAccts collection. The Add receives only the account number and the rate because the balance can only be affected by a method such as deposit, withdrawal and post interest.

Slide #10:

This shows the remove which simply takes the account number and removes the account from the collection.

Again we will deal with errors at the end of the presentation.

Remember the NewEnum() function which was explained in a previous presentation.

Note I set up the Count function but I never did anything with it.

Slide #11:

To finish up showing the different class modules, this is the Transactions class. It is a collection. I will relate what is happening on future slides, this is here to show the code. Note that I have defined colTransactions as Collection under option explicit and have then instantiated it in the Class_Initialize. The add has been looked at in a previous slide.

Slide #12:

This shows the last part of the code in the Transactions collection. Note that the Add was shown on the previous slide and that there is no Remove. I do not want the ability to remove transactions from the collection because of the integrity of the "paper trail".

The Item function is used to locate a transaction in the transaction collection based on the transaction key.

Again note that the Function NewEnum() is used so that I can use the For Each to loop through the transactions in the collection and display them in the list box.

The count function is not used - it is here to remind you of its existence.

Slide #13:

This is simply showing the code that exists on the form. We will show how they tie together next.

Note that Dim WithEvents objSavAcct as SavAcct sets up the possibility of triggering or raising events based on the processing.

Notice Dim statements for objSavAcct as SavAcct and colSavAccts as SavAccts.

Slide #14:

This shows the click events to deposit and display accounts. Remember the Enum function was necessary to do this ForEach...In...

Slide #15:

This shows the display of the transactions in the right window. It is because of this code that the Enum needs to be set up with the Transactions collection. It also shows the reset and the retrieval of an account.

Slide #16:

This shows more form code: the response to a a series of click events, the form load which instantiates objSavAcct and colSavAccts and the message box that is displayed when the insufficient funds event is raised.

Slide #17:

This is the end of the code associated with the form. It shows a series of LostFocus events where information is transferred to the work area. In the case of the interest rate, the appearance is changed and the text box is locked as well. This code shows the initialization of the variables used in the code.

Starting with the next slide, we will follow the processing that is done when a button on the form is clicked.

Slide #18:

The withdrawal command button has been clicked. The command to do the withdrawal is:

colSavAccts.Item(wkAcctNbr).WithDrawal wkTranAmt

This means that the Item method (a function) uses the account number to find the correct savings account and then the amount of the transaction is passed to the withdrawal method in SavAcct and the withdrawal is made.

Item is a method of the collection object which returns a SavAcct object. Withdrawal is a method of the returned SavAcct object that actually makes the withdrawal.

If the account is not there, the withdrawal can not be made.

The error processing assures that if there is an error the WthDrwlErr will be executed to avoid a program crash.

Note that to make this work you must have set Tools/Options/General to Break on Unhandled Errors. You get in trouble and crash if you do not make sure this setting is correct!

Slide #19:

Once the Item function has been executed. The withdrawal method in the SavAcct class is used to make the withdrawal.

Again, the commnd is:

colSavAccts.Item(wkAcctNbr).WithDrawal wkTranAmt

If there are insufficient funds in the account, the InsufficientFunds event is raised. If there is a sufficient balance the transaction amount which was passed to the withdrawal method is subtracted from the curBalance. Then we need to add the transaction to the collection of transactions associated with this account.

Now lets look at how I am using ans. If there are insufficient funds, the InsufficientFunds error is raised and on the form, ans is set to the return code from displaying the event message that says there were insufficient funds. Now notice in the cmdWthDrwl I set ans = "". I then retrieve the account and do the WithDrawal method. If the withdrawal method raises the InsuffientFunds event, ans gets changed from spaces. When the WithDrawal method is complete, I check ans for '''. If it is still empty then I know that the InsufficientFunds event was not raised and I can display the Balance. If there is something in ans, then I know that the InsufficientFunds event was raised and so I do not want to change balance on the form. This is a somewhat awkward approach based on the fact that when I was illustrating events I decided to use Insufficient Funds as an event as opposed to just setting it up as an error condition!

Slide #20:

To add the transaction to the transaction collect the Add method in the transaction collection is used. Remember, it generates a transaction number and then combines this with the information passed to create a new transaction. If the attempt to add generates an error because the transaction already exists, an error would be raised. Note that this is not likely to happen since I am generating the unique transaction number in the code.

If an error exists, this information is being passed to the form which handles showing the error. This can be seen on the next slide.

The error is raised in the class module. It is handled for display purposes on the form.

Slide #21:

The Get Balance retrieves the balance so it can be shown in the lblClsBal.Caption.

Note again the error processing, if an error occurs the processing will go to WthDrwlErr. If the error is saerrKeyNF which is the account does not exist code, then it is one kind of error, if not it is another error. I can handle errors by either sending messages from the point where the error is raised or by having messages here. In this case, I will see these error messages if the error exists.

Slide #22:

In this example, I established an account. Did a deposit and then did a withdrawal. I had a balance of 75. Then I attempted another withdrawal of 80 which raised the insufficient funds event and resulted in the message you see displayed.

Slide #23:

Note that in the top slide, the 80 did not have an impact on the closing balance because of the code using ans described previously. When I withdraw 50, the closing balance changes.

Slide #24:

When I click on the Deposit Command Button, the first thing that happens is that I execute the function to retrieve the savings account of the account number from the collection. In fact what happens is:

colSavAccts.Item(wkAcctNbr).Deposit.wkTranAmt which gets the account using the Item function and then if the retrieval is successful, does the deposit to that account.

Item is a method of the collection object which returns a SavAcct object. Deposit is a method of the returned SavAcct object that actually makes the deposit.

If the account is not there, the savings account error is raised in the SavAccts module and the messages are displayed from the form. Here I sent over messages that in fact were not used because I used my own messages in the form. I can choose to send messages when the event is used and then I can choose to use or ignore these messages when I actually show the messages.

Slide #25:

Now using colSavAccts.Item(wkAcctNbr).Deposit wkTranAmt I can use the Deposit method within SavAcct to add the transaction amount that I am sending to the account. Deposit also calls the Add method of the Transactions collection to add this transaction to the transactions associated with the active account.

Slide #26:

The Get provides the Balance to place in the lblClsBal.Caption.

Slide #27:

The code is:


which again means that the correct account must be accessed before the interest is posted.

Slide #28:

Note that I am not passing anything to the PostInterest method because the interest rate is a property of the SavAcct. This is different from the withdrawals and deposits where an amount was entered on the form that needed to be used to adjust the balance.

Slide #29:

Reset simple initializes the work area and form variables and enables the buttons used for deposit, withdrawal and reset.

Slide #30:

When the user clicks the cmdAddAcct on the form, this code is executed.

colSavAccts.Add in the SavAccts collection will receive the account number and the interest rate. It will use this information to create a new account which I am calling NewSavAcct. This object will then be added to the SavAccts collection with .AccountNumber as the key.

Once the account has been added, I call cmdRetrvAcct_Click to show the information on the form. This code is shown on the next screen. Note that I am using the click event that is used to simply retrieve a record if I want to see it on the form.

Note that If an error is raised I can either send the messages or I can simply send the code and determine the messages when the problem is diagnosed. Both methods are shown here with the passing of the messages remarked out.

Slide #31:

Here I am showing the retrieval of the account by executing the Item method (a function) to get the account information and I am setting objSavAcct to reference this information. I can then get the Balance and the IntRate using the Get property procedures for Balance and IntRate.

Slide #32:

This shows the retrieval of the Balance and IntRate properties of the SavAcct to display on the form.

Slide #33:

When the user wants to remove an account, I will do the Remove Method of the SavAccts collection. Note that I raise an error if the balance of the account that is to be removed is not 0. I do this by retrieving the Balance using the Get property procedure in SavAcct. If the account is not 0 then I remove the account with the appropriate account number from the collection.

This time I use the case structure to determine which error happened and the message to display.

Note that this would have been a way to handle InsufficientFunds that would have avoided using ans. However, I really wanted an event other than an error event, so...

Slide #34:

In this example, when the user wants to see all of the accounts, I simply Dim objDisplyAcct as SavAcct and then for each of these objects in the SavAccts collection I set up a DsplyLine which consists of the account number, balance and interest rate properties of the account. When the line is set up, it is displayed in the ListBox using AddItem.

Note that the Get is used to retrieve the objDsplyAcct.AccountNumber, objDsplyAcct.Balance, and objDsplyAcct.IntRate from the SavAcct object.

Slide #35:

With this For Each, I have defined objDsplyTrn as a Transaction. I have then said that I want the Transactions that go with the specified account number being retrieved from the SavAccts collection. Once I have the transactions that are for that account, the For Each will loop through setting up the display line with the properties of the Transaction and then putting them in the right most ListBox using AddItem.

Slide #36:

Note the contrast between the display of the accounts and the display of the transactions. The display of the accounts simply moves through the account collection displaying each object. The display of the transactions is the display of the transactions associated with the account. Therefore it uses the SavAccts collection .Item method to get the appropriate SavAcct object and the Transactions method of the SavAcct object to get the transactions associated with that account.

In the display of the accounts, the properties of the account are displayed. In the display of the transactions associated with the account, the properties of the transaction are displayed.

Slide #37:

These are the errors associated with the SavAccts collection. I have given each a name and then after the 512 reserved number, I have used a arbitrary number of my choice to designate each error.

In this example if the problem is the zero balance error, I tell it to raise the error saerrNZBal. If it is not that error then the else handles the saerrKeyNF error.

Note that I am in the SavAcct collection when I raise the error and I will send information to the form which will deal with the error. Some of the information I send is actually going to be ignored because I have set up some of my own messages on the form. This means that in these cases, the messages were not necessary.

Slide #38:

As shown on the previous slide, the error was raised and the error number and messages were sent. On the first case, the message is ignored and the error number that was passed is used. On the second case, the error description that was passed was used.

Slide #39:

These are the errors that I defined in the Transactions collection. There is one for duplicate key and there is one for key not found.

This time if an error happens I am raising the error trnerrKeyNF and sending messages to the form.

This routine uses the transaction key that was passed to it to get the appropriate transaction from the Transaction collection. This method is not used in this program.

Slide #40:

If the Add transactions encounters a problem it raises an error.