IN THE SPOTLIGHT: MDE to MDB Conversion Service
(also supports: ACCDE to ACCDB, ADE to ADP, etc)
IN THE SPOTLIGHT: Access Database Repair Service
An in-depth repair service for corrupt Microsoft Access files
IN THE SPOTLIGHT: vbWatchdog
VBA error handling just got easier...
" vbWatchdog is off the chart. It solves a long standing problem of how to consolidate error handling into one global location and avoid repetitious code within applications. "
- Joe Anderson,
Microsoft Access MVP
Meet Shady, the vbWatchdog mascot watching over your VBA code →
(courtesy of Crystal Long, Microsoft Access MVP)
IN THE SPOTLIGHT: vbMAPI
An Outlook / MAPI code library for VBA, .NET and C# projects
Get emails out to your customers reliably, and without hassle, every single time.
Use vbMAPI alongside Microsoft Outlook to add professional emailing capabilities to your projects.
IN THE SPOTLIGHT: Code Protector
Standard compilation to MDE/ACCDE format is flawed and reversible.
We understand that most developers using the SimplyVBA GLobal Error Handler will want two distinct error dialogs:
With the VBA Global Error Handling system you get many options when deciding what kind of dialog to use;
We provide you with a sample database application that is designed to show you how to implement error dialogs into your applications. In particular, the sample covers using both the Vista-style dialog and an Access form for both 'release' and 'developer' scenarios.
We provide a Sample MDB Access application that demonstrates some of the main features of the error handler. The sample application is installed with our software - you can find it in the EverythingAccess.com folder of your Start menu.
When you open the demo application, you will be presented with the demo form:
To implement this form, we have designed four separate (and re-usable) global error handling subroutines which are defined in the VBA module ModGlobalErrorHandler:
Public Sub MyGlobalErrorHandler_Release() >> Show full code
Public Sub MyGlobalErrorHandler_Developer() >> Show full code
Public Sub MyGlobalErrorHandler_Release_AccessForm() >> Show full code
Public Sub MyGlobalErrorHandler_Developer_AccessForm() >> Show full code
When you click on any of these options on the form, the EnableErrorHandler subroutine (also defined in
ModGlobalErrorHandler) chooses the corresponding global error handler subroutine name and calls
ErrEx.EnableGlobalErrorHandler to activate
the subroutine as the global error handler. For the two Vista-dialog options, the vista dialog is set up here with a call to SetupErrorDialog_Release or
SetupErrorDialog_Developer as appropriate (these routines customize the Vista-dialog).
Although four options are given for demonstration purposes, typically you would only implement two of these - one 'release' and one for yourself, the 'developer'.
It is also important to realise that in a real world application you will probably want to set the global error handler only once - usually in a subroutine that is called from the applications AutoExec macro (using the RunCode macro command).
Global error handling routines can be implemented in a variety of ways. In the Sample.mdb they have been implemented in the most common way as it lends itself most closely to the way developers usually implement normal VBA error handling.
Each of the four of our global error handlers have been implemented as follows;
To give a better understanding, we'll now look at the error simulators on our demo form.
Tip: Along with these details below, it is highly recommended to step through the demo code line by line so that you can better understand the program flow.
Private Sub btnOpenFormError_Click() ' We won't bother with local error handling here. Our global error handler will handle it nicely. ' The form ABC does not exist, so will produce an error. DoCmd.OpenForm "ABC" ' A lot of simple procedures can be implemented without any local error handling, ' which makes code maintenance much easier and reduces code size too. ' Normally we'd never get here, but if we are using the 'developer' error dialog ' then the user can select 'Ignore & Continue', and we will resume here... MsgBox "btnOpenFormError_Click: We must have resumed after the error." End Sub
Case OnErrorGoto0
' ---------------------------------------------------------------
' Unhandled errors
' ---------------------------------------------------------------
LogErrorToTable
ErrEx.State = ErrEx.ShowErrorDialog
This adds error details to the error log table and then shows the Vista error dialog to the user.In the example above, if we're using MyGlobalErrorHandler_Release, then after the user clicks 'Close' to the error, ErrEx.State is assigned the value of OnErrorEnd, and then program flow is stopped.
However, if we're using MyGlobalErrorHandler_Developer, then the error dialog has been setup to have extra buttons ('debug' and 'ignore & continue') - the error dialogs have been previously setup in SetupErrorDialog_Release and SetupErrorDialog_Developer respectively.
If the user selects 'Ignore & Continue' (OnErrorResumeNext) then this acts as if the developer had put On Error Resume Next just before the error occurred.
If the user selects 'End' (OnErrorEnd) then this acts as if the developer pressed the 'End' button on the old VBE error dialog. In other words, the program flow will stop immediately after our error handler has returned.
If the user selects 'Debug' (OnErrorDebug) then this acts as if the developer has pressed the 'Debug' button on the old VBE error dialog. In other words, the VBE editor opens and highlights the line of error.
Private Sub btnRecordsetError_Click() Dim rs As DAO.Recordset ' Upon encountering an error we want to ensure the recordset object has definitely been released. ' In order to do this, we use a small local error handler that will pass any errors ' on to the global error handler with a flag set to ensure that the global error handler ' will display the error dialog (otherwise it would just ignore the error because of the way it ' is implemented in this example). Step through the code to grasp a better understanding. On Error GoTo LocalErrorHandler ' Customers table does not exist, so will cause an error. Set rs = CurrentDb.OpenRecordset("SELECT * FROM CUSTOMERS") ' Normally we'd never get here, but if we are using the 'developer' error dialog ' then the user can select 'Ignore & Continue', and we will continue... MsgBox "btnRecordsetError_Click: We must have resumed after the error." Cleanup: On Error Resume Next ' Ignore errors when cleaning up. rs.Close Set rs = Nothing Exit Sub LocalErrorHandler: ErrEx.CallGlobalErrorHandler ' Call the global error handler to deal with unhandled errors Resume Cleanup ' After showing the error dialog, we will clean up End Sub
Case OnErrorGotoLabel
' ---------------------------------------------------------------
' Ignore locally handled errors
' ---------------------------------------------------------------
LocalErrorHandler: ' Pass the error on to our global error handler ErrEx.CallGlobalErrorHandler ' Call the global error handler to deal with unhandled errors Resume Cleanup ' After showing the error dialog, we will clean up
In this example, we wanted to:
To do this, our local error handler calls ErrEx.CallGlobalErrorHandler which then calls our global error handler MyGlobalErrorHandler_Release again but with a special ErrEx.State of CalledByLocalHandler ...
Case CalledByLocalHandler ' --------------------------------------------------------------- ' ErrEx.CallGlobalErrorHandler was called ' ' This is a special case for when local error handling was in use ' but the local error handler has not dealt with the error and ' so has passed it on to the global error handler ' --------------------------------------------------------------- LogErrorToTable ErrEx.State = ErrEx.ShowErrorDialog ' --------------------------------------------------------------- ' NOTE: ' ' Since this global error handler routine is for 'release', not ' 'development', we don't really want to end abruptly here. ' ' So instead, we set ErrEx.State = CalledByLocalHandler ' which ensures we resume after the CallGlobalErrorHandler ' line - where cleanup code can then be done ' --------------------------------------------------------------- ErrEx.State = CalledByLocalHandlerThis adds error details to the error log table and shows the Vista-style error dialog to the user.
Resume Cleanup
Cleanup:
On Error Resume Next ' Ignore errors when cleaning up.
rs.Close
Set rs = Nothing
Exit Sub
Job done!Private Sub btnChangePropertyExample_Click() ' Error handling is done in the subroutine. ChangeProperty "ABC", dbText, "Blah" End Sub 'ChangeProperty as defined in module ModPropertyExample Public Function ChangeProperty(stPropName As String, PropType As DAO.DataTypeEnum, vPropVal As Variant) As Boolean On Error GoTo LocalErrorHandler Dim Db As DAO.Database Dim Prop As DAO.Property Set Db = CurrentDb Db.Properties.Delete stPropName Db.Properties.Delete stPropName ' This causes an error because the property doesn't already exist Set Prop = Db.CreateProperty(stPropName, PropType, vPropVal, True) Db.Properties.Append Prop ChangeProperty = True Cleanup: On Error Resume Next ' Ignore errors when cleaning up. Set Prop = Nothing Set Db = Nothing Exit Function LocalErrorHandler: ' Handle local specific errors here: Const conPropNotFoundError As Long = 3265 Select Case Err.Number Case conPropNotFoundError ' We will ignore the 'property does not exist' error Resume Next End Select ErrEx.CallGlobalErrorHandler ' Call the global error handler to deal with unhandled errors Resume Cleanup ' After showing the error dialog, we will clean up End Function
Case OnErrorGotoLabel
' ---------------------------------------------------------------
' Ignore locally handled errors
' ---------------------------------------------------------------
LocalErrorHandler: ' Handle local specific errors here: Const conPropNotFoundError As Long = 3265 Select Case Err.Number Case conPropNotFoundError ' We will ignore the 'property does not exist' error Resume Next End Select ErrEx.CallGlobalErrorHandler ' Call the global error handler to deal with unhandled errors Resume Cleanup ' After showing the error dialog, we will clean upIn this example, we first wanted to handle the specific error of 'property does not exist', so we check that here.
Notice that we use Err in local procedure handling, and ErrEx when in the global error handler, although in practice it doesn't make any difference as long as we always use ErrEx in the global error handler.
Case conPropNotFoundErrorThis is true.
Resume NextThis then puts program flow at the line after the error
Set Prop = Db.CreateProperty(stPropName, PropType, vPropVal, True)Program flow is then as expected - the property is created successfully and CleanUp continues.
Notice that no error dialog is displayed in the example since it is an example of a commonly used way of trapping when a known error might occur.
iTech Masters | VAT: GB202994606 | Terms | Sitemap | Newsletter