Alison Balteramp;#039;s Mastering Microsoft Office Access 1002003 [Electronic resources] نسخه متنی

This is a Digital Library

With over 100,000 free electronic resource in Persian, Arabic and English

Alison Balteramp;#039;s Mastering Microsoft Office Access 1002003 [Electronic resources] - نسخه متنی

Alison Balter

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید



Building a Custom Error Handler Class


Implementing error handling within an application can be very tedious, especially if you attempt to place specific error-handling logic in each routine you write. Although implementing a generic error handler does not mandate the use of a class module, using a class module greatly facilitates the process of implementing error handling within your applications. Listing 16.29 illustrates this point.

Listing 16.29 An Example of an Access Subroutine

Sub AnySub2()
'Declare constant with the name of the routine
Const SUBNAME As String = "AnySub"
'Invoke error handling
On Error GoTo AnySub2_Err
'Beginning of any routine
MsgBox "This is the rest of your code...."
'Oops! Something causes an error!
Err.Raise 11
'Code after the error
MsgBox "We are Past the Error!!"
AnySub2_Exit:
'Generic exit point for routine
Exit Sub
AnySub2_Err:
Dim intAction As Integer
'Instantiate the error handler class
Set gobjErrorHandler = New ErrorHandler
'Execute the ErrorProcess method,
'passing the error information
intAction = gobjErrorHandler.ErrorProcess(ModuleName, _
SUBNAME, Err.Number, Err.Description)
'Evaluate return value to determine what action to take
Select Case intAction
Case ERR_CONTINUE
Resume Next
Case ERR_RETRY
Resume
Case ERR_EXIT
Resume AnySub2_Exit
Case ERR_QUIT
Quit
End Select
End Sub

When an error occurs, your code instantiates the ErrorHandler class. The Initialize event of the class executes, as shown in Listing 16.30.

Listing 16.30 The Initialize Event of the ErrorHandler Class

Private Sub Class_Initialize()
'Place username into private variable
mstrUsername = CurrentUser
'Place current date and time into private variable
mdatDateTime = Now
End Sub

The Initialize event of the class sets the module-level variables mstrUserName and mdatDateTime equal to the CurrentUser and the current date and time, respectively. The Username and DateTime properties of the class use these variables.

The code then executes the ErrorProcess method of the ErrorHandler class, which logs the error and then takes appropriate action in response to the error. It appears in Listing 16.31.

Listing 16.31 The ErrorProcess Method of the ErrorHandler Class

Public Function ErrorProcess(strRoutine As String, _
strModule As String, _
lngErrorNumber As Long, _
strErrorMessage As String) As Integer
'Store error information into module-level variables
mstrRoutine = strRoutine
mstrModule = strModule
mlngErrorNumber = lngErrorNumber
mstrErrorMessage = strErrorMessage
'Log error
Call LogError
'Locate the error number in tblErrors to
'determine how you should respond to the error
Dim rst As ADODB.Recordset
Set rst = New ADODB.Recordset
rst.Open "Select Response from tblErrors Where ErrorNum = " & lngErrorNumber, _
CurrentProject.Connection, adOpenStatic
'If the error number that occurred is not found
'in tblErrors, display the error form and return
'ERR_QUIT to the problem routine
If rst.EOF Then
DoCmd.OpenForm "frmError2", WindowMode:=acDialog, _
OpenArgs:="ErrorHandler"
ErrorProcess = ERR_QUIT
'If the error is in tblErrors, evaluate the contents of
'the Response field. Respond appropriately, displaying the appropriate
'form and returning the appropriate value to the offending routine
Else
Select Case rst!Response
Case ERR_QUIT
DoCmd.OpenForm "frmError2", WindowMode:=acDialog, _
OpenArgs:="Critical Error: Application will Terminate"
ErrorProcess = ERR_QUIT
Case ERR_RETRY
ErrorProcess = ERR_RETRY
Case ERR_EXIT
DoCmd.OpenForm "frmError2", WindowMode:=acDialog, _
OpenArgs:="Severe Error: Processing Did Not Complete"
ErrorProcess = ERR_EXIT
Case ERR_CONTINUE
ErrorProcess = ERR_CONTINUE
End Select
End If
End Function

The routine first sets the ModuleName, Routine, ErrorMessage, and ErrorNumber variables within the class to the values of the parameters passed to the ErrorProcess method. The Property Get routines for the ModuleName, Routine, ErrorMessage, and ErrorNumber properties, which are responsible for manipulating error information, appear in Listing 16.32. Because we only want the properties to be set via the ErrorProcess method, no Property Let routines exist.

Listing 16.32 The Property Get Routines of the Class

Public Property Get ModuleName() As String
ModuleName = mstrModule
End Property
Public Property Get Routine() As String
Routine = mstrRoutine
End Property
Public Property Get ErrorMessage() As String
ErrorMessage = mstrErrorMessage
End Property
Public Property Get ErrorNumber() As Integer
ErrorNumber = mlngErrorNumber
End Property
Public Property Get UserName() As String
UserName = mstrUsername
End Property
Public Property Get DateTime() As Date
DateTime = mdatDateTime
End Property

As you can see, the Property Get routines retrieve the values from their associated module-level variables.

Next, the function calls a routine that logs the error that occurred. This LogError routine is shown in Listing 16.33. The LogError routine uses ADO code to add a record to the tblErrorLog table. The record contains all the information about the error that occurred. Notice that the error information is retrieved from the module-level variables populated by the ErrorHandler class's ErrorProcess method.

Listing 16.33 The LogError Subroutine

[View full width]

Sub LogError()
'Declare a Connection object
Dim cnn As ADODB.Connection
Dim strSQL As String
'Point the Connection object at the connection
'associated with the current project
Set cnn = CurrentProject.Connection
'Build a SQL statement that inserts error information
'into the tblErrorLog table
strSQL = "INSERT INTO tblErrorLog ( ErrorDate, ErrorTime, UserName, ErrorNum,
ErrorString, ModuleName, RoutineName) "
strSQL = strSQL & "Select #" & Me.DateTime & "#, #" _
& Me.DateTime & "#, '" _
& Me.UserName & "', " _
& Me.ErrorNumber & ", '" _
& Me.ErrorMessage & "', '" _
& Me.ModuleName & "', '" _
& Me.Routine & "'"
'Execute the SQL statement
cnn.Execute strSQL, , adExecuteNoRecords
End Sub

After the error is logged, the number of the error that occurred is looked up in the tblErrors table. If it is not found in the tblErrors table, a form is displayed, containing all the critical information about the error that occurred. The value contained in the constant ERR_QUIT is returned from the ErrorHandler function. If the error number is found in the tblErrors table, the value contained in the Response field is evaluated. If it is the value contained in the constant ERR_QUIT, the frmError form is displayed, and the value in the constant ERR_QUIT is returned from the ErrorHandler method. If the Response field contains the value of the ERR_RETRY constant, that value is returned from the method, without the frmError form being displayed. If the Response field contains the value associated with the ERR_EXIT constant, the frmError form is displayed, and the ERR_EXIT value is returned from the ErrorHandler method. Finally, if the value in the Response field is the value associated with the ERR_CONTINUE constant, no error information is displayed, and the ERR_CONTINUE value is returned from the ErrorHandler method.

All the code contained in the ErrorHandler class is similar to that contained in the basErrorHandler module. The code has been modified so that it is implemented using properties and methods of a Class object.

The other code that is changed to use classes is the code behind the error form. Listing 16.34 shows the load event of the error form, modified to call methods of the appropriate classes.

Listing 16.34 The Form_Load Event of the Error Form

Private Sub Form_Load()
Dim objSys As SystemInformation
Set objSys = New SystemInformation
'Call routine to obtain system information
Call objSys.GetSysInfo(Me)
'Call routine to obtain error information
Call gobjErrorHandler.GetErrorInfo(Me)
'If FormCaption property contains a value, use the
'value as the caption for the form
If Not IsNull(Me.OpenArgs) Then
Me.lblAction.Caption = Me.OpenArgs
End If
End Sub

Notice that instead of calling the GetSysInfo function and the GetErrorInfo function, the load event executes the GetSysInfo method of the SystemInformation object and the GetErrorInfo method of the ErrorHandler object.

The GetSystemInfo function and associated declarations were moved to a SystemInformation class. No other changes were made to the code.

The GetErrorInfo function was moved to the ErrorHandler class and modified to retrieve properties of the class, as shown in Listing 16.35.

Listing 16.35 The GetErrorInfo Method of the ErrorHandler Class Retrieving Properties of the Class

Sub GetErrorInfo(frmAny As Form)
'Populate form controls with error information
'contained in the type variable
frmAny.lblErrorNumber.Caption = Me.ErrorNumber
frmAny.lblErrorString.Caption = Me.ErrorMessage
frmAny.lblUserName.Caption = Me.UserName
frmAny.lblDateTime.Caption = Format(Me.DateTime, "c")
frmAny.lblModuleName.Caption = Me.ModuleName
frmAny.lblRoutineName.Caption = Me.Routine
End Sub

Notice that instead of using a type structure, the code references its own properties. The Private variables associated with these properties were set by the ErrorProcess method of the class.


/ 544