Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Creating an Error Log? 4

Status
Not open for further replies.

Varga

Technical User
Mar 28, 2003
43
CA
Hello,
I have created a database and I want to deal with any problems that may occur once it's up and running.
I want to add Error handling code to my database that creates a new record in the 'Error' table, each time there is an error, and stores information about the type of eror that occured and when it occured.

Sub Example()
On Error GoTo ErrorCode
Statements...
Statements...
End

ErrorCode:
MsgBox ("Error")
Open recordset...
AddNew record...
End Sub


First of all, is there a way to get visual basic to take a screen print when the Error occurs and then paste that image into a cell in the 'Error' table?
(If not I can just write unique text to the 'Error' table to identify which code was running at the time, but a screen print would be more helpful.)

Second, I believe the code above, on an error, would go to the error code then just end. Is there a way to rearrange the code so that the error code would run, then continue running the rest of the original code?

Third, the forms in my database are not directly linked to a table, they set themselves to the users tables in their Form Load procedure. I get messages poping up when the form loads because the RecordSource is not valid until it's set, and each coded query asks for confirmation before completing.
I can go to the 'Tools' menu, then 'Options' and then click the 'Edit/Find' tab and change the 'Confirm' settings, but I think that only works on my computer. I don't want these messages poping up on User's computers. Is there a way to get Access to change the Confirm settings for each user.
(Or a more helpful, better way)

Lastly, does anyone know of a better way to record, and manage, system errors?


Please let me know
Thank you,
Blair ;-)
 
create a table and a function to capture the data and update the table.... this example (which I've only performed limited testing in XP) requires an Error Handler in each Sub and a call to the function. The field types in the table are String for Name of the Form and Name of the Module, Long for the Err Number and Memo for the Error Description.

Function fErrorLog(strForm, strMod, lngErr, strDescrip)
Dim db As DAO.Database, rst As DAO.Recordset
Set db = CurrentDb
Set rst = db.OpenRecordset("tblErrorLog")
With rst
.AddNew
!NameOfForm = strForm
!NameOfModule = strMod
!NumErr = lngErr
!DescripErr = strDescrip
.Update
End With
Set db = Nothing
Set rst = Nothing
End Function


then in the sub you add something like this

errExit:
Exit Sub
errHandler:
Call fErrorLog(Me.Name, Me.Module.Name, Err.Number, Err.Description)
MsgBox Err.Number & " : " & Err.Description, vbCritical, "Unexpected Error"
GoTo errExit


PaulF
 
Paul,
That's awesome.
Thanks for the assistance.
------------------------------------------------
Is there a way to get the code to continue where it left off?
Say the procedure has 10 statements in it and the error occurs after the third statement, the error code would run then go directly to the "GoTo errExit" point.
That means that I would have to choose a spot in the statement for the code to resume.
Because I don't know where an error might occur, let's say the error occurs on statement 5 and the "GoTo errExit" is before statement 3, would that create a loop?
I wouldn't want that.
Can the code just resume where it left off?
Or is there a better way?

Please let me know,
Thanks,
Blair :)
 
As far as turning your Confirm messages on/off, see SetOption and GetOption via on line help.

For handling errors, I would suggest creating a new database which will become your library database which you will reference in all of your databases. Then create a new module in the library database that represents your error handling routine. Once the error routine is in the library, you can build onto it as requirements demand and, consequently, all of your databases will adhere to the new requirements. For example, at first all you want to do is to log the error messages. So you build a couple databases that implement your error handler. Then, suppose, at some later date, you want to be notified (via email or whatever) when certain errors occur. You can add that functionality later and all previous database will will notify you when those errors occur.

Now that you have a library database, you can add modules to it as needed. For example, one of your applications may need a function to calculate age. Might as well put that code in your library so, if you have a use for it in the future, you won't have to reinvent the "wheel".

With all that said, this is how I handle errors. The arguments for my error handling function mimic Microsoft Access' MsgBox with a couple of additional arguments. I then log all of the information to a file (or table).

When I want to view the error logs, I display all of the information on a form. Then, when I press a command button on that form, the OnClick event issues the Msgbox command with the info from the record. Consequently, it is displayed to me just like the user saw it. Note that the form contains information that I need but the user doesn't need to see or cares about.

Here is an example of calling the error handler:
Code:
    On Error Goto ErrHandler

    bunch of code here

ExitProcecure:

    Exit Sub

ErrHandler:

    Lib_MsgBox Err.Description,vbExclamation,,,,gintcShowLogError,"NameOfThisSubProcedure",Err.Number
    Resume ExitProcedure

End Sub
Note the last 3 arguments of Lib_MsgBox.

1. gintcShowLogError is a constant (declared in your library) which tells the error handler to show the message to the user and log it. Sometimes, you may only want to log the message but not display it to the user (batch jobs for example). In that case you could pass it another value (i.e. gintcLogError). On some errors, you may want to display message but not log it (i.e. gintcShowError)
2. The name of the procedure where the error occurred. This way you can narrow down where the problem occurred much faster.
3. The error number itself. I usually include it in the title of the message box if no title is passed to the error handler routine

Here's the concept for the error handling function:
Code:
Public Function Lib_MsgBox(strPrompt_Caller As String, _
                  Optional varButtons As Variant, _
                  Optional varTitle As Variant, _
                  Optional varHelpFile As Variant, _
                  Optional varContext As Variant, _
                  Optional varLog As Variant, _
                  Optional varProcedure As Variant, _
                  Optional varErrCode As Variant)

insert declarations here

    If (IsMissing(varErrCode)) Then
        lngErrNumber = Err.number
    Else
        lngErrNumber = varErrCode
    End If

    strSource = Err.Source
    lngLastDllError = Err.LastDllError

    On Error goto ErrHandler

    If (IsMissing(varButtons)) Then
        intButtons = 0
    Else
        intButtons = varButtons
    End If

    If (IsMissing(varTitle)) Then
        strTitle = "Error: " & lngErrNumber                                       'Application.Name
        If (Not IsMissing(varProcedure)) Then strTitle = strTitle & "  (" & varProcedure & ")"
        
    Else
        strTitle = varTitle
    End If

    blah blah blah

    if (displayMessageToUser) then
        If ((Not IsMissing(varHelpFile)) And (Not IsMissing(varContext))) Then
            
            strHelpFile = varHelpFile
            intContext = varContext
MMC_MsgBox = MsgBox(strPrompt, intButtons, strTitle, strHelpFile, intContext)
Code:
        Else
MMC_MsgBox = MsgBox(strPrompt, intButtons, strTitle)
Code:
        End If

    If (LogFile) then
        rst!strPrompt = strPromt_Caller
        rst!intButtons = intButtons
        ...
rst!strCurrentUser = CurrentUser
rst!strFormName = CodeContextObject.Name
rst!strCurrentDB = CurrentDb.Name
rst!lngErrNumber = lngErrNumber
rst!dtmLog = Now
Code:
    End if

blah blah blah

Note the stuff in read. It logs:
1. The name of the user that produced the error
2. The name of the form/report that in which the error occurred
3. The name of the databse in which the error occurred
4. The error number
5. The date/time the error occurred.
 
Some of that went over my head.
Thanks for the tips though.
I figured out the SetOptions, I added code to the Switchboards Load procedure which is opened by Access's startup settings:
[blue]Private Sub Form_Load()
SetOption "Confirm Record Changes", False
SetOption "Confirm Document Deletions", False
SetOption "Confirm Action Queries", False
End Sub[/blue]


Now let's see how much else I understood...

Would the 'rst' variable be set in the current database's modUtility to refer to the 'ErrorLog.mdb' database and it's 'ErrorLog' table?

I'm not too good with functions yet.
Do I declare all the "Public Function Lib_MsgBox" code in the current database's modUtility?

Do I then call the "Lib_MsgBox (..., ...,)" function in the error handling section of each procedure?

Please explain:
strSource = Err.Source
lngLastDllError = Err.LastDllError
On Error goto ErrHandler


What does the Error source refer to?
What is "Err.LastDllError"?
"On Error GoTo ErrHandler" why is this in the midle of the code? Is it just incase there is an error within the function itself?


If I don't set a point in a procedure for the error to exit to once it's finished, will the code automatically start again where it left off?

You've been a great help so far.
Thank you,
Blair ;-)
 
I was in the middle of responding to you about an hour ago when my daughter came in the house, one of our feeder calves died. So I had to deal with that.

rst refers to the table. For example,

Dim dbs as DAO.Database
Dim rst as DAO.Recordset

Set dbs = CurrentDB
Set rst = dbs.OpenRecordset("Select * from ErrorLog;")

rst.AddNew
rst!...
rst.Update
rst.close

For an explanation of Err.Source and Err.LastDllError, goto on line help and check out the properties of the Err object.

The reason the On Error Goto ErrHandler is in the middle is because if the caller doesn't pass the Err.Number to the routine, the statements prior to the On Error statement grab that information. Note that once the On Error Goto statement is issued, that information is lost (i.e. Err.Number, etc.). So I grab it before it's lost.

It gets a little more complicated when you put the module in a library database (but not much, maybe 10 minutes more of work). And you will appreciate taking the initial steps of creating a library database in the future. If you want to take this route I will elaborate further if you want.


You can create a new module in your current database and insert the Lib_MsgBox (from above, although all of the code you need is not there, including the End Function statement). By default the module is Public.

In every procedure, where you want to trap errors, you need to put the following code in:

On Error GoTo ErrHandler

your code here

ExitProcedure

Exit Sub (or Function)

ErrHandler:

Lib_MsgBox ...
Resume ExitProcedure

End Sub

Check on line help for the Resume statement, it will tell you what statements will be executed after the error is processed.
 
Firstly, I'm sorry to hear about you feeder calf. I assume you live on a farm. Was it from anything in particular?

I really like your way of logging errors. I would like a little more elaboration though. I'm understanding things more and more clearly. (i.e. err.source etc.)

I understand how to open a recordset and add a new record.
Would OpenRecordset code refer to the secondary database instead of 'CurrentDB'?
Or would the code be put in the secondary database, using 'CurrentDB' to refer to itself, and be run remotly from the original database?

I would like you to explain the 'Library' thing. Would the 'ErrorLog.mdb' and the 'Library Database' be the same thing? (I mean would the Library database also contain the error log records?)

Please explain where the different sections of code would go.

I understand most of the code you wrote.
I would have to Dim lngErrNumber and lngLastDllError as strings to capture the information before putting the "On Error GoTo..." statement.
I would also need 'If (...) Then' statements to determin if the error is logged, or displayed, or both.

Would they go something like:[blue]
If (varLog = "gintcShowLogError") Then
Log error...
MsgBox (error message...)
End if[/blue]

And so on for each possibility?

I do appreciate all your help,
Thank you very much!
I love learning new things :)
Blair
 
Great! I'm glad you're taking this route (i.e. library database).

Your library database is like any other database. You have a front end and a back end. And they both reside on a server to which everyone who uses your database has access to. For example,

FrontEndName = Prefix_Library_AccessVersion_FE.mda
BackEndName = Prefix_Library_AccessVersion_BE.mda

Where Prefix might represent your company name/initials and Version the version of Access the library was written in. Something like this:
IBM_Library_Access2000_FE.mda
IBM_Library_Access2000_BE.mda

The BE database will contain the table(s). Initially the Error Log table (i.e. tblIBM_ErrorLog). The FE will link to this table.

Note that when you want to refer to the stuff in the library database, you use CodeDB rather than CurrentDB. CurrentDB refers to the Current Database (which is your main application database...not the library database). CodeDB represents the library the code is currently running in.

So, create a new module in the FE library db and call it something like modPublicDeclarations. This is where you will declare all public constants and declarations (that will be visible in all of your modules in your db as well as the library db).

In this module (named something like: modPublicDeclarations), include the following (note the prefix naming convention, not necessary but helps to know that the variable has been declared in your library rather than in you database).
Code:
Option Compare Database
Option Explicit

'***************************
'*  Constant Declarations  *
'***************************

    Public Const gintcIBM_ERRLOG_SHOW = 0                           'Show message but do NOT log it
    Public Const gintcIBM_ERRLOG_SHOWLOG = 1                        'Show message and log it
    Public Const gintcIBM_ERRLOG_LOG = 2                            'Do NOT show message but log it

    Public Const gstrcIBM_ERRLOG_TBLNAME As String = "tblIBM_ErrLog"           'Name of MsgBox table


Now, create a new module in your library database and name it something like modIBM_MsgBox. And insert the following code.

Code:
Public Function IBM_MsgBox(strPrompt_Caller As String, _
                  Optional varButtons As Variant, _
                  Optional varTitle As Variant, _
                  Optional varHelpFile As Variant, _
                  Optional varContext As Variant, _
                  Optional varLog As Variant, _
                  Optional varProcedure As Variant, _
                  Optional varErrCode As Variant)

'********************************
'*  Declaration Specifications  *
'********************************

    Dim dbsL As DAO.Database                  'Points to Library database (CodeDb)
    Dim rst As DAO.Recordset
    
    Dim intButtons As Integer                 'Working Variable (See "Buttons" below)
    Dim strTitle As String                    'Working Variable (See "Title" below)
    Dim strHelpFile As String                 'Working Variable (See "Helpfile" below)
    Dim intContext As Integer                 'Working Variable (See "Context" below)
    Dim strForm As String                     'Working Variable (Name of Form where error occurred)
    Dim strProcedure As String                'Working Variable (Name of Procedure where error occurred)
    Dim bytLog As Byte                        'Working Variable (See "varLog" below)
    Dim lngErrNumber As Long
    Dim lngLastDllError As Long
    
    Dim strPrompt As String
    Dim strSource As String
    
'******************
'*  Error Number  *
'******************

    strPrompt = strPrompt_Caller
    
    If (IsMissing(varErrCode)) Then
        lngErrNumber = Err.number
    Else
        lngErrNumber = varErrCode
    End If
    
    strSource = Err.Source
    lngLastDllError = Err.LastDllError
    
    On Error GoTo ErrHandler

'**************************************************************************************
'*  Buttons:  Numeric expression that is the sum of values specifying the number and  *
'*            type of buttons to display, the icon style to use, the identity of the  *
'*            default button, and the modality of the message box.  If omitted, the   *
'*            default value for buttons is 0.                                         *
'**************************************************************************************

    If (IsMissing(varButtons)) Then
        intButtons = 0
    Else
        intButtons = varButtons
    End If
    
'******************************************************************************************
'*  Title:  String expression displayed in the title bar of the dialog box.  If you omit  *
'*          title, the application name is placed in the title bar.                       *
'******************************************************************************************
    
    If (IsMissing(varTitle)) Then
        strTitle = "Error: " & lngErrNumber                                       'Application.Name
        If (Not IsMissing(varProcedure)) Then strTitle = strTitle & "  (" & varProcedure & ")"
        
    Else
        strTitle = varTitle
    End If
    
'*******************************************************************************************
'*  Helpfile:  String expression that identifies the Help file to use to provide           *
'*             context-sensitive Help for the dialog box.  If helpfile is provided,        *
'*             context must also be provided.                                              *
'*                                                                                         *
'*******************************************************************************************
'*  Context:  Numeric expression that is the Help context number the Help author assigned  *
'*            to the appropriate Help topic.  If context is provided, helpfile must also   *
'*            be provided.                                                                 *
'*******************************************************************************************
'*  varLog:   0 = Display Message but don't log it (i.e. write it to database).  DEFAULT   *
'*                (Public Const gintcIBM_ERRLOG_SHOW = 0)                                  *
'*            1 = Display Message and log it                                               *
'*                (Public Const gintcIBM_ERRLOG_SHOWLOG = 1)                               *
'*            2 = Don't display message but log it                                         *
'*                (Public Const gintcIBM_ERRLOG_LOG = 2)                                   *
'*******************************************************************************************

    If (Not IsMissing(varLog)) Then
        bytLog = varLog
    Else
        bytLog = 0
    End If
    
'**********************
'*  Display message?  *
'**********************
    
    If (bytLog < 2) Then
        
        If ((Not IsMissing(varHelpFile)) And (Not IsMissing(varContext))) Then
            
            strHelpFile = varHelpFile
            intContext = varContext
            
            IBM_MsgBox = MsgBox(strPrompt, intButtons, strTitle, strHelpFile, intContext)
        
        Else
            
            IBM_MsgBox = MsgBox(strPrompt, intButtons, strTitle)
        
        End If

    End If
        
'******************
'*  Log message?  *
'******************
    
    If (bytLog > 0) Then
    
        If (lngErrNumber <> 10508) Then    'IFT, Message asks the user if he's sure he wants to delete the records.  No need to log it.
        
            Set dbsL = CodeDb
            Set rst = dbsL.OpenRecordset(gstrcIBM_ERRLOG_TBLNAME)
            
            With rst
            
                .AddNew
    
                !dtmLog = Now
                !strPrompt = strPrompt
                !strFormName = IIf(Len(CodeContextObject.Name) <= !strFormName.size, CodeContextObject.Name, Mid(CodeContextObject.Name, 1, !strFormName.size))
                !strUserName = IIf(Len(CurrentUser) <= !strUserName.size, CurrentUser, Mid(CurrentUser, 1, !strUserName.size))
                !strCurrentDb = IIf(Len(CurrentDb.Name) <= !strCurrentDb.size, CurrentDb.Name, Mid(CurrentDb.Name, 1, !strCurrentDb.size))
                !lngErrNumber = lngErrNumber
                !strSource = IIf(Len(strSource) = 0, Null, strSource)
                !lngLastDllError = lngLastDllError
                
                If (Not IsMissing(varButtons)) Then !intButtons = varButtons
                If (Not IsMissing(varTitle)) Then !strTitle = IIf(Len(varTitle) <= !strTitle.size, varTitle, Mid(varTitle, 1, !strTitle.size))
                If (Not IsMissing(varHelpFile)) Then !strHelpFile = IIf(Len(varHelpFile) <= !strHelpFile.size, varHelpFile, Mid(varHelpFile, 1, !strHelpFile.size))
                If (Not IsMissing(varContext)) Then !intContext = varContext
                If (Not IsMissing(varProcedure)) Then !strProcedureName = IIf(Len(varProcedure) <= !strProcedureName.size, varProcedure, Mid(varProcedure, 1, !strProcedureName.size))
    
                .Update
        
            End With
    
            rst.Close

        End If
        
    End If
    
'*******************
'*  Exit Function  *
'*******************

ExitProcedure:

    Exit Function
    
'****************************
'*  Error Recovery Section  *
'****************************

ErrHandler:

    If (Err.number = 7955) Then Resume Next  'IFT, error on CodeContextObject.Name above
    
    MsgBox &quot;Unexpected Error!&quot; & vbCrLf & vbCrLf & Err.Description & vbCrLf & vbCrLf & vbCrLf & _
           &quot;Procedure: IBM_MsgBox &quot;, vbExclamation, &quot;Unexpected Error!&quot;

    Resume ExitProcedure
    
End Function

Note that I haven't tested the above code.

Now create another module and name it something like &quot;modIBM_OpenForm&quot;. It should look something like this. Actually the arguments to this function should mirror Access' OpenForm method. But for now...
Code:
Function IBM_OpenForm(strFormName as String)

    DoCmd.OpenForm strFormName,,,,,acDialog

End Function

Now create a new form in your library database and name it something like frmIBM_MsgBox. The Recordsource for this form will be your error log table. Place a command button on the form whose caption says something like (Display Message) and in the OnClick event include the following.
The OnClick event will display the error just like the user saw it.
Code:
Private Sub cmdDisplayMessage_Click()
    
'********************************
'*  Declaration Specifications  *
'********************************

    Dim intResponse As Integer                          'Response from MsgBox
    Dim hlpButtons As Integer                           'Help buttons to display (Or'd together)
    
    Dim hlpTitle As String                              'Help Title
    
    On Error GoTo ErrHandler
    
'**************
'*  Buttons:  *
'**************

    If (IsNull(txtButtons)) Then
        hlpButtons = 0
    Else
        hlpButtons = txtButtons
    End If
    
'******************************************************************************************
'*  Title:  String expression displayed in the title bar of the dialog box.  If you omit  *
'*          title, the application name is placed in the title bar.                       *
'******************************************************************************************
    
    If (IsNull(txtTitle)) Then
        hlpTitle = &quot;Error: &quot; & txtlngErrNumber                                       'Application.Name
        If (Not IsNull(txtProcedureName)) Then hlpTitle = hlpTitle & &quot;  (&quot; & txtProcedureName & &quot;)&quot;
        
    Else
        strTitle = txtTitle
    End If
    
    
'*******************************************************************************************
'*  Helpfile:  String expression that identifies the Help file to use to provide           *
'*             context-sensitive Help for the dialog box.  If helpfile is provided,        *
'*             context must also be provided.                                              *
'*                                                                                         *
'*******************************************************************************************
'*  Context:  Numeric expression that is the Help context number the Help author assigned  *
'*            to the appropriate Help topic.  If context is provided, helpfile must also   *
'*            be provided.                                                                 *
'*******************************************************************************************
    
'**********************
'*  Display message?  *
'**********************
    
    If ((Not IsNull(txtHelpFile)) And (Not IsNull(txtContext))) Then
          
        intResponse = MsgBox(txtPrompt, hlpButtons, hlpTitle, txtHelpFile, txtContext)
        
    Else
            
        intResponse = MsgBox(txtPrompt, hlpButtons, hlpTitle)
        
    End If

'***********************
'*  Exit subprocedure  *
'***********************

ExitProcedure:
    
    Exit Sub

'****************************
'*  Error Recovery Section  *
'****************************

ErrHandler:
    
    IBM_MsgBox &quot;Unexpected error!&quot; & vbCrLf & vbCrLf & Err.Description & vbCrLf & vbCrLf & &quot;Contact Help Desk.&quot;, 48, _
               &quot;Fatal Error!&quot;, , , gintcIBM_ERRLOG_SHOWLOG, &quot;cmdDisplayMessage_Click&quot;
    Resume ExitProcedure

End Sub

Now close the Library database, open your database, set a reference to your library database and force and error in a module with the following code included in the module.

On Error Goto ErrHandler

bunch of code here

ExitProcecure:

Exit Sub

ErrHandler:

IBM_MsgBox Err.Description,vbExclamation,,,,gintcIBM_ERRLOG_ShowLog,&quot;NameOfThisSubProcedure&quot;,Err.Number
Resume ExitProcedure

End Sub

You may be wondering why the module IBM_OpenForm. The reason is so that you can open a form that exists in the library via your database. For example, if you want to open the form frmIBM_MsgBox from your database, call IBM_OpenForm(&quot;frmIBM_MsgBox&quot;).
 
By the way, in our example, we're logging errors to a table. If, for example, you're doing transaction logging and an error occurs and you call the error logging routine and then rollback the transaction, you have also rolled back the log to the error table. Therefore, the error would not be logged.

Also, Access 2000 will not let you make modifications to a library database if users are attached to it (that is, they have a database opened that has referenced the library). Therefore, once it is completed, I would make a .mde version of the database and reference the .mde version rather than the .mda version. That way you can make changes to it. When the changes are complete, simply have everyone log out of their database, and convert the new version of the .mda to the .mde version that everyone is referenced to.
 
Paul,
Thank you once again.
I've been using Access's help menu's to learn more about &quot;Set Options from Visual Basic&quot;, &quot;Error Statement&quot;, &quot;MsgBox Function&quot;, &quot;Resume Statement&quot;, and &quot;Set References to Type Libraries&quot;.
(Would you recomend setting the reference throught the tools menu or through VB? Is one better?)

Everything is becomming much clearer.
There are a few things that you will have to dumb down a little for me.

I know that &quot;.Mda&quot; means &quot;Microsoft Access Add-in&quot; and that allows it to be referenced in other databases. I've learned that a referenced library database should only contain code.
Is there anything else I should know about &quot;.Mda&quot; 's?

The help information stated that (Err.LastDllError = 0), does it always equal 0? What am I missing?

In the 'Log message?' part:
Why &quot;If (lngErrNumber <> 10508) Then&quot; what does it mean?
What does &quot;IFT&quot; mean?

I'm going to start creating this library so I'll probably have more questions later on.

Thanks for your help,
Blair
 
Access uses the naming convention .mda for Add-Ins and libraries. They are exactly the same as an .mdb. Just a different file extension. Your library could have an extension of .mdb, but, to follow convention, I use .mda.

Not only do I store code in my library, but also forms, queries, and reports. (It's just like any other database.)

Set your reference via the tools menu. Use a share name (if one is setup for your server) rather than hardcoding a drive letter. (Some users may have the drive letter you choose reserved for something else.)

At the end of the statement If (lngErrNumber <> 10508) Then I have a comment that begins 'IFT, that's my syntax for IF TRUE. In other words, if the IF-THEN statement is TRUE, then it means, in this case, that error number was 10508 which means that the user is attempting to delete a record. Therefore, don't bother reporting the error (i.e. message).

I can't remember why I put this in (Err.LastDllError = 0), but there was a reason.

Finally, you should be able to just copy and paste my code into your library database and it should work. (However, your error log table needs to be created prior to using it.) Then test it out. A simple test would be

IBM_MsgBox &quot;This is a test&quot;,vbExclamation,,,,gintcIBM_ERRLOG_ShowLog,&quot;This is the name of my module&quot;,Err.Number

The message &quot;This is a test&quot; will be logged to your error log table. Then create a quick form (nothing fancy for testing) whose recordsource is set to you error log table. Put a command button on the form and copy the OnClick code from my previous post.

The whole thing should take no more than 5 minutes to copy/paste/create a test form/ and test. The 5 minutes doesn't include creating your error log table.

I would test it exactly as it is. Then when you see how it all works, go back and change the prefixes to something meaningful to you (i.e. change &quot;IBM&quot; to whatever).

Note that you can do all of your testing within your library database. It's just another database. Once you have it working then set a reference to it from your other database and test it there.

Let me know how it all works out.
 
I kept getting the message
&quot;Field 'tblIBM_Err_Log.strPrompt' cannot be a zero-length string.&quot;

I changed the IBM_MsgBox code to only log the strPrompt if it has a valid value.

If Not (strPrompt = &quot;&quot;) Then !strPrompt = strPrompt

That seem to work better.
Errors are now logging to the Error Table. (Thank you)

However, I'm still getting errors in my code that log to the table with no details. The prompt that comes up is:
&quot;Error: 0 (&quot;My procedure&quot;)&quot;
with and exclamation and an &quot;OK&quot; button. It logs to the Error table but doesn't log anything for the strPrompt, lngErrNumber, or strSource.
(fyi These procedures are 'Sub's called from other procedures on the same form.)

Any ideas as to what is going on?

p.s. The lngLastDllError is constantly logging a value of &quot;997&quot;
Do you remember why this is in here? What it means?

Everything else is working great. I've learned so much from you. Thank you again and again for all your help, and patience. Hopefully others will find this thread as usefull as I have.

Thanks,
Blair :)
 
I fixed the 'blank error' problem.

I needed to add the &quot;Exit Sub&quot; code before the error handling code because without it I guess the error handling code was running as part of the procedure. (...oops)

I still haven't been able to log any values for &quot;strTitle&quot;, &quot;intContext&quot;, or &quot;strHelpFile&quot;.

Do you know of an example error number that I could force, that would have a helpfile and stuff?

 
strTitle is what will be displayed in the Title bar of the message box. intContext and strHelpFile are only applicable if you created a help file for your application.

Note that the first 5 arguments of IBM_MsgBox duplicate the arguments of Access' MsgBox Function. So check online help for those arguments (i.e. strTitle, intContext, strHelpFile). Note also, that I didn't pass any values for those arguments (see ,,,, below)

IBM_MsgBox Err.Description,vbExclamation,,,,gintcIBM_ERRLOG_ShowLog,&quot;NameOfThisSubProcedure&quot;,Err.Number
Resume ExitProcedure
 
FancyPrarie,

Once again, very impressive code you've put up. Thanks much.

I haven't read through it too thoroughly yet, but I did just e-mail myself the thread so I can read through it more closely.

When I learned to do error handling, it was from a VB guy who was very suspicious of Access's stability. He had me log directly to a text file. I've got a page on my method in the Developer's section of my website.

Jeremy

==
Jeremy Wallace
AlphaBet City Dataworks
Access Databases for Non-Profit Organizations

Please post in the appropriate forum with a descriptive subject; code and SQL, if referenced; and expected results. See thread181-473997 for more pointers.
 
Thanks for the compliment JeremyNYC. I initially developed this concept in Access 2.0 (the code shown is a modified version of mine, that's why I said I hadn't tested it). I have since read (including some of your previous posts) where people log the errors to a text file. This would certainly solve the problem when, rolling back transactions, the error log would be rolled back also (unless you rolled it back prior to logging the error). What other advantages are there to logging to a text file?
 
Well, it's just a simpler beast, so it's more difficult for it to get corrupted. And you can read it with just about any program ever made, so you don't have to worry about whether or not your installation of Access got hammered or some other severe damage got done (quite rare, of course). And it's smaller than a database, so you're less likely to be tempted to archive any of the data out.

I'm sure there are some disadvantages, too, but since it's worked for me so far, I'll stick with it for now.

Jeremy

==
Jeremy Wallace
AlphaBet City Dataworks
Access Databases for Non-Profit Organizations

Please post in the appropriate forum with a descriptive subject; code and SQL, if referenced; and expected results. See thread181-473997 for more pointers.
 
Hi Paul,
Sorry I have taken so long to respond, I’ve been super busy with work.
My program is working well (thanks to you) and I seem to be upgrading it all the time.

I love the fact that I can trouble shoot errors at any time after they have occurred.
I’m finding and fixing errors that people aren’t even reporting to me.

The only other thing I can think of that would make this thread complete, is if you would please elaborate on the e-mailing thing.
You had mentioned previously that Access could send an E-mail when specific errors occur.

Where, and how, would I add some VB code to get the program to email me when an error occurs? Could the e-mail include the details of the error too?

That’s it.
Thank you very much for all your help.
Blair :)
 
When an error occurs, I want Access (2000) to do a screen print (i.e. 'Ctrl' + 'Print Scrn') and e-mail it to me.

I would prefer that Access open a powerpoint presentation then paste the screen print into it, and e-mail me the powerpoint document, so that the e-mail is smaller than the screen print being put directly into an e-mail.

Is this possible?

Please let me know,
Thanks,
Blair :)
 
Varga, check out this thread thread702-689314 on how to simulate print screen and paste into powerpoint.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top