[AccessD] Classes and Events - EVENTS NOT REQUIRED

Tina Norris Fields tinanfields at torchlake.com
Mon Feb 23 16:52:10 CST 2009


John,

My question is why is StartTimer() a Sub and EndTimer() a Function?  It 
is not clear to me what the distinction is between a Sub and a Function 
- they both look like "methods" or "functions" as found in Java.  So, 
please explain that difference to me.  Thanks.

Tina

jwcolby wrote:
> To this point the classes we have looked at were specifically designed to allow you to “wrap” an 
> object that generates events and add code and variables to process those events.  This lecture will 
> demonstrate that classes have other uses and do not have to wrap other objects.
>
> The class introduced today will be clsTimer, a means of timing events (things happening) in your 
> code.  The class is perhaps the simplest class I have ever written, and perhaps the simplest class 
> you will ever see.
>
> •	Click Insert / Class
> •	Save immediately as clsTimer
> •	Insert the following code into the class:
>
> Private Declare Function apiGetTime Lib "winmm.dll" _
>                                      Alias "timeGetTime" () As Long
>
> Private lngStartTime As Long
>
> Private Sub Class_Initialize()
>      StartTimer
> End Sub
>
> Function EndTimer()
>      EndTimer = apiGetTime() - lngStartTime
> End Function
>
> Sub StartTimer()
>      lngStartTime = apiGetTime()
> End Sub
>
> •	Compile and save the class.
>
> Notice that in the header of the class we have a function definition apiGetTime that calls out to 
> Windows.  This function gets the windows tick timer and has a resolution of 1 millisecond, or one 
> thousandth of a second.  This simply means that we can’t time anything that takes less than one 
> thousandth of a second without resorting to timing it several times.  It returns a long integer that 
> is simply an absolute number of “ticks”.  Since when?  It doesn’t matter, it is just “this is the 
> tick count RIGHT NOW”.
>
> To compute a “time” (and we aren’t really doing that, we are calculating a time since the first 
> time), you get the tick count and store it, then later you get another tick and compare it to the 
> first tick.  The difference is the number of 1000ths of a second since the first tick count.
>
> Notice that we have no mInit() method in this class.  Notice also that the Class_Initialize calls 
> the StartTimer() function.  As you know now, the Class_Initialize is a class event that fires as the 
> class loads, so this tells the class to load the first tick time as soon as the class instance loads.
>
> In the header of the class we dimensioned a long variable lngStartTime.  This will be used to store 
> the starting tick count.  StartTimer() simply calls out to Windows, gets the current tick count from 
> Windows, and stores that count to lngStartTime.
>
> EndTimer() simply calls out to Windows again to get the current tick count, subtracts the current 
> count to the previous count stored in lngStartTime and returns that count to you the programmer.
>
> That’s it folks!  This class has in the header a function definition to call Windows and a place to 
> store the count.  In the body of the class it then has two methods to start the “timer” and to 
> return the ticks since the timer started.  You are not going to see many classes simpler than that.
>
> So let’s discuss why we need to encapsulate this in a class.  You might be saying that you can do 
> the same thing without the class but a class allows you to create as many of these timers as you 
> want.  Let’s build some test code to see how this thing works and why we might need several.
>
> •	In the tools menu click Insert / MODULE.  We are building a normal module this time, NOT a class 
> module.
> •	Immediately save the module as basTimerTest
> •	Into this new module insert the following code:
>
> Function TmrTest()
> Dim lngCtr1 As Long
> Dim lngCtr2 As Long
> Dim clsTmr1 As clsTimer
> Dim clsTmr2 As clsTimer
>
>      Set clsTmr1 = New clsTimer
>      For lngCtr1 = 1 To 5
>          Set clsTmr2 = New clsTimer
>          For lngCtr2 = 1 To 100000
>              Pi
>          Next lngCtr2
>          Debug.Print clsTmr2.EndTimer
>      Next lngCtr1
>      Debug.Print clsTmr1.EndTimer
> End Function
>
> Function Pi() As Double
> Dim dblPi As Double
>      dblPi = 4 * Atn(1)
>      Pi = dblPi
> End Function
>
> Notice that we dim two timers, then we SET the timers on the outside of their respective loops.  As 
> you know, the SET statement loads the class, at which point the Class_Initialize fires which grabs 
> the first timer tick from windows.
>
> The Debug.Print statement simply calls the .EndTimer method of the class and prints it to the debug 
> window.
>
> Voila, a timer, with a resolution of one thousandth of a second.
>
> TmrTest simulates a real world code where you have two loops, and inner loop and an outer loop.
>
> The inner loop times how long it takes to calculate Pi.  Notice that modern computers are so fast 
> that I have to do it a hundred thousand times in order to get enough “tick counts” (thousandths of a 
> second) to even get a number to use.  The outer loop simply times how long it takes to run the inner 
> loop 5 times.
>
> I have intentionally kept this thing simple, but your outer loop might time how long it takes to 
> read a thousand records and the inner loop might be replaced with timing how long it takes to … 
> transform a string from comma delimited to pipe delimited or something like that.
>
> In this lecture we have demonstrated that a class encapsulates all of the code required to perform 
> its function, plus the variables required to store its data.  It also demonstrates that you can use 
> as many instances of the class as you need.  If you need one or a hundred timers, you just dim and 
> SET the variables and you are off to the races so to speak.
>
> Classes are used to encapsulate code and data required to implement a system.  You’re your 
> imagination is the only limit to what that system can be.
>
>   



More information about the AccessD mailing list