Subject: Handling the no duplicates index error
Posted By: Enoch Post Date: 1/18/2006 1:53:49 PM
I know how to handle errors and provide custom error messages for errors generated within a sub or function.  However, if the error is thrown by a no duplicates index, I don't know where or how to catch the error in order to provide a more user friendly error message.

Thanks in advance for your help

Enoch
Reply By: Bob Bedell Reply Date: 1/18/2006 2:42:40 PM
Don't know exactly how you're doing the insert, but the Jet error you're interested in is 3022.

Sub DuplicateValueError(strNewValue As String)

   On Error GoTo Err_Handler

    Dim db As DAO.Database
    Dim rst As DAO.Recordset
    
    Set db = CurrentDb
    Set rst = db.OpenRecordset("tblRecords", dbOpenDynaset)

   With rst
      .AddNew
      !Field1 = strNewValue
      .Update  '<--- Error 3022 thrown here.
   End With

   rst.Close
   db.Close
   Set rst = Nothing
   Set db = Nothing
   Exit Sub
    
Exit_Here:
   rst.Close
   db.Close
   Set rst = Nothing
   Set db = Nothing
   Exit Sub
    
Err_Handler:
    
   If Err.Number = 3022 Then
      strMsg = "Error occurred when you called rst.Update." & vbCrLf & vbCrLf
      strMsg = strMsg & "Please enter a unique value for this field."
    
      MsgBox "Error Number: " & Err.Number & vbCrLf & vbCrLf & strMsg, _
            vbCritical + vbOKOnly, "Duplicate Value Error"
   Else
      MsgBox "Error No: " & Err.Number & "; Description: " & Err.Description
   End If
    
   Resume Exit_Here

End Sub


HTH,

Bob

Reply By: Bob Bedell Reply Date: 1/18/2006 3:02:04 PM
On a stylistic note, if I know the error code I'm trapping for, I like to use a constant just to make the code more self-documenting:

Private Const ERR_DUPLICATE_VALUE = 3022

Sub DuplicateValueError(strNewValue As String)

   On Error GoTo Err_Handler

    Dim db As DAO.Database
    Dim rst As DAO.Recordset
    
    Set db = CurrentDb
    Set rst = db.OpenRecordset("tblRecords", dbOpenDynaset)

   With rst
      .AddNew
      !Field1 = strNewValue
      .Update  '<--- Error 3022 thrown here.
   End With

   rst.Close
   db.Close
   Set rst = Nothing
   Set db = Nothing
   Exit Sub
    
Exit_Here:
   rst.Close
   db.Close
   Set rst = Nothing
   Set db = Nothing
   Exit Sub
    
Err_Handler:
    
   If Err.Number = ERR_DUPLICATE_VALUE Then
      strMsg = "Error occurred when you called rst.Update." & vbCrLf & vbCrLf
      strMsg = strMsg & "Please enter a unique value for this field."
    
      MsgBox "Error Number: " & Err.Number & vbCrLf & vbCrLf & strMsg, _
            vbCritical + vbOKOnly, "Duplicate Value Error"
   Else
      MsgBox "Error No: " & Err.Number & "; Description: " & Err.Description
   End If
    
   Resume Exit_Here

End Sub

Reply By: Bob Bedell Reply Date: 1/18/2006 3:12:21 PM
Then again it occurs to me that maybe your talking about trapping the error at the Form level, in which case you would use the Form's error event:

Private Sub Form_Error(DataErr As Integer, Response As Integer)

   Select Case DataErr
      Case 3022
           MsgBox "You added a record which duplicates an existing value."
           Response = acDataErrContinue
      Case Else
           Response = acDataErrDisplay
   End Select

End Sub

Bob

Reply By: Bob Bedell Reply Date: 1/18/2006 3:29:57 PM
Then set focus back to the offending control:


Private Sub Form_Error(DataErr As Integer, Response As Integer)
    
    Const ERR_DUPLICATE_INDEX_VALUE = 3022
    Dim strMsg As String

    If DataErr = ERR_DUPLICATE_INDEX_VALUE Then
        strMsg = "This record cannot be added to the database." & vbCrLf
        strMsg = strMsg & "It would create a duplicate record." & vbCrLf & vbCrLf
        strMsg = strMsg & "Changes were uncuccessful."

        MsgBox "Error Number: " & DataErr & vbCrLf & vbCrLf & strMsg, _
            vbCritical + vbOKOnly, "Duplicate Record."

        'Set focus to the offending control
        Me.txtText1.SetFocus
               
        Response = acDataErrContinue 'prevent Access from displaying its own error message
    Else
        Response = acDataErrDisplay 'cause Access to display its own error message
    End If

End Sub


Bob

Reply By: Enoch Reply Date: 1/18/2006 3:41:08 PM
Thanks, that's just what I needed.


Enoch
Reply By: Enoch Reply Date: 1/18/2006 3:57:58 PM
It was within a form, sorry I wasn't more specific, Thanks for writing out both answers though.
I didn't realize there was a built in event to just handle errors in forms.


Enoch
Reply By: Bob Bedell Reply Date: 1/18/2006 5:25:08 PM
No problem, Enoch. You did mention you already knew procedure error handling, so I figured you must have meant the form level stuff. Glad you found what you needed.

Best,

Bob

Reply By: Penn White Reply Date: 3/22/2006 9:14:31 PM
Could someone please explain why this error (3022) is being generated at all.  I am getting the same error but see no reason for it.  Isn't .addnew supposed to create a new, unique record with a new, unique primary key (indexed, no duplicates, autonumber)?  If so, then where is the error coming from?

I have been battling this for days and making no neadway.  I'm afraid I may have a corrupt table or something.  There are over 1000 records in the table (more or less in sequential numeric order) but the new PK ID is in the 500's.

Any help greatly appreciated.

Penn
Reply By: Bob Bedell Reply Date: 3/22/2006 10:28:17 PM
quote:

Isn't .addnew supposed to create a new, unique record with a new, unique primary key (indexed, no duplicates, autonumber)?



Yes it is. If you have two fields in a table named ID(autonumber) and Field1 and run:

 rst.AddNew
 rst!Field1 = "NewData"
 rst.Update

The ID field will be automatically incremented with a new unique ID. You can retrive the new ID by immediately running (after the update):

Dim rst As ADODB.Recordset
Dim intNewAutoNumber As Integer
Set rst = New ADODB.Recordset
rst.Open "SELECT @@IDENTITY", CurrentProject.Connection
intNewAutoNumber = rst.Fields(0)

Sounds to me like your table is toast. Can you import the records you have into a new table:


INSERT INTO Table2 ( ID, Field1 )
SELECT Table1.ID, Table1.Field1
FROM Table1;


That sort of thing...

HTH,

Bob

Reply By: Penn White Reply Date: 3/23/2006 6:53:56 AM
Bob,

Thank you for your help.  

There is only one 'no duplicates, autonumbder' field in the table.

I can insert the records into a new table but this table is relational to another that looks to this table for data through the PKID field number.  If I change those numbers, how do I re-establish the links to the other table?  

I did what was suggested here: http://support.microsoft.com/kb/304561/EN-US/ but the primary key got put into a number field and apparently in order to get another autonumber field, I have to add a new field and can't use the old one.  

I haven't tried using insert but I'm thinking the same thing will happen since Access won't let me turn a field with data in it into an autonumber field.

Penn

Reply By: Penn White Reply Date: 3/23/2006 7:20:47 AM
Hold on!!!  I just ran the insert and the autonumbers are retained and I can add new records!!  Hallelujah!!  I think this will do it.  Thank you very, very much!

Penn

Reply By: Bob Bedell Reply Date: 3/23/2006 7:34:24 AM
LOL And there was much rejoicing...

Glad you got it going, Penn.

Bob


Reply By: Penn White Reply Date: 3/23/2006 8:03:34 AM
BTW, I'm using ACC03, DAO (*.mdb) and this also works to retrieve the ID number.  You have to be sure to set the variable (NewID) before updating.

  Dim rst as DAO.ReocrdSet
  Dim NewID as long
  Set rst = CurrentDb.OpenRecordset("Table2")
  With rst
    .AddNew
    !Field1 = "NewField1Text"
    NewID = !ID
    .Update
    .Close
  End With
  Set rst = Nothing


Reply By: Bob Bedell Reply Date: 3/23/2006 6:49:52 PM
Hi Penn,

The identical code works in ADO, too. Just had @@IDENTITY in mind from some Access "stored procedure" (using the phrase very loosely) experiments I've been playing with for a while.

Bob

Reply By: Loralee Reply Date: 4/7/2006 12:17:49 AM
Penn,
So do I understand using the SQL Insert allowed your autonumber PK to migrate into the new table in an autonumber field?  

(I gotta little project ahead of me......  One of my main tables went belly up today).

Loralee





Reply By: Penn White Reply Date: 4/7/2006 4:53:45 AM
Loralee,

I believe the short answer to your question is, "Yes".

The new table used the same autonumbers as the original one except where there were errors in the records.  I lost at least one record which I just heard about yesterday, actually. I don't think many others were lost, if any, because I would have heard about it.

The advantage to the insert was to respect the original autonumbers because they were used to link to another table.

Does that help and am I making sense to you?  If not, just let me know.

Penn

Reply By: Penn White Reply Date: 4/7/2006 5:02:04 AM
Loralee,

Just posted a response but I don't know where it went.  Apparently not here, at least, but this may show up twice.  Anyway, I'll try again...

I believe the short answer to your question is, "Yes".

Using the insert, the PK autonumber field in the new table respected (i.e. had the same numbers) as the old table with the exception of damaged records.  I just found out yesterday, actually, that one record had been lost.  I don't think there were many others, if any, because I think I would have heard about it.  But I have no real way of figuring it out.

The advantage to keeping the same PK autonumbers was that they are used as link numbers to another table.

If I'm not making myself clear or if that doesn't anwer your question, please let me know.

Penn


Reply By: Penn White Reply Date: 4/7/2006 7:07:42 AM
Hi Loralee,

Hopefully the third time's the charm.  I've posted this response twice before and it hasn't shown up yet.

I believe the short answer to your question is "Yes".

The advantage of insert is that the new table keeps the same PK autonumber numbers as the old table with the exception of any damaged records.  I just found out yesterday, actually, that one of the records had been deleted.  I doubt there are any more because I think I would have heard.

Keeping the same PK autonumbers was important to me because those numbers are used as link identifiers for another table.

If this isn't clear or if you have more questions, you might try my email (pennwhite_remove@hotmail.com (take out _remove) since this forum doesn't seem to be working. I've sent a message to tech support but haven't gotten any response yet.

Penn


Go to topic 30936

Return to index page 320
Return to index page 319
Return to index page 318
Return to index page 317
Return to index page 316
Return to index page 315
Return to index page 314
Return to index page 313
Return to index page 312
Return to index page 311