|
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
|