Results 1 to 6 of 6

Thread: VB6 DAO Error Handling

  1. #1

    Thread Starter
    Member G_Hosa_Phat's Avatar
    Join Date
    May 2008
    Location
    Oklahoma City, OK
    Posts
    44

    VB6 DAO Error Handling

    Hello, all. I've been maintaining a legacy system for a while now that uses VB6 with an MS Access database on the back end using DAO for communication. I'm still working on getting something developed under .NET with a "real" RDBMS, but in the meantime I'm doing everything I can to keep the existing system afloat.

    One of the biggest problems I've found so far is the number of DAO errors that come up when multiple users are in the database (shocking, huh?). Most of these are related to table/record locking, so I figured I might try to find a way to better handle those types of errors.

    I've now come up with the use of a function to determine whether or not the error is "serious" enough to stop execution of the application. After researching online, I've gone through the entire list of trappable MS Jet and DAO errors. I think I have a list of "acceptable" errors for which I can simply put in a little sleep timer and let the application try the operation again (not indefinitely, of course). What I need now is bascially some confirmation that these errors are indeed "acceptable". Here's my preliminary list:

    ERROR MESSAGE
    3009 You tried to lock table <table> while opening it, but the table cannot be locked because it is currently in use. Wait a moment and then try the operation again.
    3158 Could not save record; currently locked by another user.
    3186 Could not save; currently lockec by user <name> on machine <name>.
    3187 Could not read; currently lockec by user <name> on machine <name>.
    3188 Could not update; currently locked by another session on this machine.
    3197 The Microsoft Jet database engine stopped the process because you and another user are attempting to change the same data at the same time.
    3211 The database engine could not lock table <name> because it is already in use by another person or process.
    3212 Could not lock table <name>; currently in use by user <name> on machine <name>.
    3218 Could not update; currently locked.
    3254 ODBC - Cannot lock all records.
    3260 Could not update; currently locked by user <name> on machine <name>.
    3261 Table <name> is exclusively locked by user <name> on machine <name>.
    3262 Could not lock table.
    3330 Record in table <name> is locked by another user.
    3412 Cannot perform cascading update on the table because it is currently in use by another user.
    3413 Cannot perform cascading operation on table <name> because it is currently in use by user <name> on machine <name>.
    3414 Cannot perform cascading operation on table <name> because it is currently in use.
    3418 Cannot open <tablename>. Another user has the table open using a different network control file or locking style.
    3624 Could not read the record; currently locked by another user.
    3667 A different operation is preventing this operation from being executed.


    I've found confirmation on some of these, but I would like to be sure I don't add more than I need and end up missing an error that may indicate a serious problem with the database, rather than just a table/record lock that hasn't been lifted yet.

    BTW, here's the code for the DAO error trapping I'm thinking of using. Let me know what you think, and thanks so much for your input and help.
    VB Code:
    1. Public Function DAOErrorRetry(ByRef ErrorCount As Integer) As Boolean
    2.     If ErrorCount <= 5 Then
    3.         If Err.Number = 3008 Or Err.Number = 3009 Or Err.Number = 3158 Or Err.Number = 3186 _
    4.                 Or Err.Number = 3187 Or Err.Number = 3188 Or Err.Number = 3197 _
    5.                 Or Err.Number = 3260 Or Err.Number = 3261 Or Err.Number = 3262 _
    6.                 Or Err.Number = 3211 Or Err.Number = 3212 Or Err.Number = 3218 _
    7.                 Or Err.Number = 3254 Or Err.Number = 3330 Or Err.Number = 3412 _
    8.                 Or Err.Number = 3413 Or Err.Number = 3414 Or Err.Number = 3418 _
    9.                 Or Err.Number = 3624 Or Err.Number = 3667 Then
    10.             Sleep 500
    11.             ErrorCount = ErrorCount + 1
    12.            
    13.             Err.Clear
    14.             DAOErrorHandler = True
    15.         Else
    16.             DAOErrorHandler = False
    17.         End If
    18.     Else
    19.         DAOErrorHandler = False
    20.     End If
    21. End Function
    Last edited by G_Hosa_Phat; Oct 13th, 2011 at 03:33 PM.

  2. #2
    Frenzied Member
    Join Date
    May 2006
    Location
    some place in the cloud
    Posts
    1,886

    Re: VB6 DAO Error Handling

    Post the code where you open the db & recordsets
    Post some code where you use the : AddNew or Edit or Delete and Update
    Post some code where you use the : On Error GoTo xxx
    JG


    ... If your problem is fixed don't forget to mark your threads as resolved using the Thread Tools menu ...

  3. #3

    Thread Starter
    Member G_Hosa_Phat's Avatar
    Join Date
    May 2008
    Location
    Oklahoma City, OK
    Posts
    44

    Re: VB6 DAO Error Handling

    Okie doke. Here's a quick example of what I'm doing in code to open, pull data from and save data into the database (Please note that I haven't actually tested this specific code, so there may be typos. I just wrote it up in notepad since I don't currently have access to my development environment. Even so, this is the same basic operation I currently use in my application, with the addition of my "new" DAO error handling function listed above):

    VB Code:
    1. '-----------------------------------------------------------------
    2. ' GLOBAL VARIABLE DECLARATION
    3. '-----------------------------------------------------------------
    4. Public dbEmployee As Database
    5. Public tblEmployee As Recordset
    6.  
    7. '-----------------------------------------------------------------
    8. '-----------------------------------------------------------------
    9. Public Sub InitDB()
    10.     ' ****************************************************************
    11.     ' ** Dim the intErrorCount variable at the top of each routine  **
    12.     ' ** and not globally to prevent a count of errors from another **
    13.     ' ** routine from accidentally being passed into the error      **
    14.     ' ** error handling for this one.                               **
    15.     ' ****************************************************************
    16.     Dim intErrorCount As Integer
    17.  
    18.     On Error GoTo InitDBError
    19.  
    20.     If Len(AppInfo.DataPath) = 0 Then Err.Raise -8000
    21.    
    22.     intErrorCount = 0
    23.  
    24.     ' ****************************************************************
    25.     ' ** Open the database and the retrieve the table data for use. **
    26.     ' ****************************************************************
    27.     Set dbEmployee = DBEngine.OpenDatabase(AppInfo.DataPath, False, False)
    28.     Set tblEmployee = dbEmployee.OpenRecordset("Employee", dbOpenDynaset)
    29.  
    30.     Exit Sub
    31. InitDBError:
    32.     ' ****************************************************************
    33.     ' ** If the application was unable to determine the path to the **
    34.     ' ** Access database, prompt the user for the location of the   **
    35.     ' ** .mdb file.                                                 **
    36.     ' ****************************************************************
    37.     If Err.Number = -8000 Then
    38.         With frmMain.dlgMain
    39.             .InitDir = AppInfo.ApplicationPath
    40.             .Filter = "*.mdb"
    41.             .ShowOpen
    42.  
    43.             If Len(.FileName) = 0 Then
    44.                 MsgBox "You did not select a database for the application." & vbcrlf & vbcrlf & _
    45.                        "Application terminating.", vbOKOnly + vbCritical, "NO DATABASE SELECTED"
    46.                 End
    47.             Else
    48.                 AppInfo.DataPath = .FileName
    49.             End If
    50.         End With
    51.        
    52.         Resume Next
    53.     ' ****************************************************************
    54.     ' ** If any other error occurred while trying to connect to or  **
    55.     ' ** retrieve data from the Access database, display an error   **
    56.     ' ** and terminate execution of the application.                **
    57.     ' ****************************************************************
    58.     Else
    59.         If Not DAOErrorRetry(intErrorCount) Then
    60.             MsgBox "An error occurred while connecting to the database." & vbcrlf & vbcrlf & _
    61.                    "Error Number: " & Err.Number & vbcrlf & _
    62.                    "Error Source: " & Err.Source & vbcrlf & _
    63.                    "Error Description " & Err.Description & vbcrlf & vbcrlf & _
    64.                    "Application terminating.", vbOKOnly + vbCritical, "DATABASE CONNECTION FAILED"
    65.             Err.Clear
    66.             End
    67.         Else
    68.             intErrorCount = 0
    69.             Resume
    70.         End If
    71.     End If
    72. End Sub
    73.  
    74. '-----------------------------------------------------------------
    75. '-----------------------------------------------------------------
    76. Private Sub SaveRecord()
    77.     Dim intErrorCount As Integer
    78.  
    79.     On Error GoTo SaveRecordError
    80.    
    81.     intErrorCount = 0
    82.    
    83.     With tblEmployee
    84.         .FindFirst "EmpID = '" & frmMain.txtMain(0).Text & "'"
    85.        
    86.         If Not tblEmployee.NoMatch Then
    87.             .Edit
    88.         Else
    89.             .AddNew
    90.         End If
    91.        
    92.         !FirstName = Trim(frmMain.txtMain(1).Text)
    93.         !LastName = Trim(frmMain.txtMain(2).Text)
    94.         !Address1 = Trim(frmMain.txtMain(2).Text)
    95.         !Address2 = Trim(frmMain.txtMain(2).Text)
    96.         !City = Trim(frmMain.txtMain(2).Text)
    97.         !State = Trim(frmMain.txtMain(2).Text)
    98.         !ZIPCode = Trim(frmMain.txtMain(2).Text)
    99.         .Update
    100.     End With
    101.    
    102.     Exit Sub
    103. SaveRecordError:
    104.     If Not DAOErrorRetry(intErrorCount) Then
    105.         MsgBox "An error occurred while attempting to update the employee record." & vbcrlf & vbcrlf & _
    106.                "Error Number: " & Err.Number & vbcrlf & _
    107.                "Error Source: " & Err.Source & vbcrlf & _
    108.                "Error Description " & Err.Description & vbcrlf & vbcrlf & _
    109.                "Your changes to this employee were not saved." & vbcrlf & vbcrlf & _
    110.                "Please contact the IT HelpDesk for assistance.", vbOKOnly + vbCritical, "UPDATE RECORD FAILED"
    111.         Err.Clear
    112.         End
    113.     Else
    114.         intErrorCount = 0
    115.         Resume
    116.     End If
    117. End Sub
    118.  
    119. '-----------------------------------------------------------------
    120. '-----------------------------------------------------------------
    121. Private Sub DeleteRecord()
    122.     Dim intErrorCount As Integer
    123.  
    124.     On Error GoTo DeleteRecordError
    125.    
    126.     intErrorCount = 0
    127.    
    128.     With tblEmployee
    129.         .FindFirst "EmpID = '" & frmMain.txtMain(0).Text & "'"
    130.        
    131.         If Not tblEmployee.NoMatch Then
    132.             .Delete
    133.         Else
    134.             MsgBox "The record for employee number " & frmMain.txtMain(0).Text & " could not be found in the database." & vbcrlf & _
    135.                    "The record may have already been deleted."  & vbcrlf & vbcrlf & _
    136.                    "If you continue to see this message, please contact the IT HelpDesk for assistance.", _
    137.                    vbOKOnly + vbInformation, "NO RECORD FOUND."
    138.         End If
    139.     End With
    140.    
    141.     Exit Sub
    142. DeleteRecordError:
    143.     If Not DAOErrorRetry(intErrorCount) Then
    144.         MsgBox "An error occurred while attempting to delete the employee record from the database." & vbcrlf & vbcrlf & _
    145.                "Error Number: " & Err.Number & vbcrlf & _
    146.                "Error Source: " & Err.Source & vbcrlf & _
    147.                "Error Description " & Err.Description & vbcrlf & vbcrlf & _
    148.                "Please contact the IT HelpDesk for assistance.", vbOKOnly + vbCritical, "DELETE RECORD FAILED"
    149.         Err.Clear
    150.         End
    151.     Else
    152.         intErrorCount = 0
    153.         Resume
    154.     End If
    155. End Sub
    Last edited by G_Hosa_Phat; Oct 14th, 2011 at 10:47 AM.

  4. #4

    Thread Starter
    Member G_Hosa_Phat's Avatar
    Join Date
    May 2008
    Location
    Oklahoma City, OK
    Posts
    44

    Re: VB6 DAO Error Handling

    Well, so far my testing of this seems to work normally, but my question remains: Is my list of "acceptable" error messages okay, or is it TOO thorough? Like I said, I want to appropriately handle the errors as they arise, but I don't necessarily need for the user to have to deal with them. Any thoughts, comments or suggestions would be greatly apprecitated.

  5. #5
    Frenzied Member
    Join Date
    May 2006
    Location
    some place in the cloud
    Posts
    1,886

    Re: VB6 DAO Error Handling

    Reviewing some of my working projects that are installed in many clients, some use DAO some use ADO, and no errors since installation, I can tell you the next:
    Check for errors only the instructions where an error can arise, speaking of record locking then if you protect only the .Update and .Delete methods it will be ok
    Do not forget to 'turn off' the error checking with 'On Error GoTo 0' after the last instruction that you need to check, it can give you undesired results if you don't do this way.
    In the error handler routine, always 'Resume xxx' to exit from it
    Code:
    '
    'other code goes here
    '
    
    On Error GoTo ErrHandler
    .Update        or       .Delete
    On Error GoTo 0
    '
    'other code goes here
    '
    JG


    ... If your problem is fixed don't forget to mark your threads as resolved using the Thread Tools menu ...

  6. #6

    Thread Starter
    Member G_Hosa_Phat's Avatar
    Join Date
    May 2008
    Location
    Oklahoma City, OK
    Posts
    44

    Re: VB6 DAO Error Handling

    @JG - Thanks for the info. I'm looking around at some other pieces of this, and I may have a more effective solution. I still have some work to do to figure it out, but I'll post back when I have it tested a bit.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width