Kan ikke fange opp bestemte ODBC-feil i OnError-egenskapen for et skjema (KB 206175)

Obs!: Vi ønsker å gi deg det nyeste hjelpeinnholdet så raskt som mulig, på ditt eget språk. Denne siden er oversatt gjennom automatisering og kan inneholde grammatiske feil eller unøyaktigheter. Formålet vårt er at innholdet skal være nyttig for deg. Kan du fortelle oss om informasjonen var nyttig for deg nederst på denne siden? Her er den engelske artikkelen for enkel referanse.

Hvis du angir egenskapen OnError for en Access-skjema til en hendelsesprosedyre, du kan ikke hente beskrivelsen av en ODBC-feil i denne prosedyren og du kan også fange opp en bestemt ODBC-feil. Når en ODBC-feilen oppstår, er den eneste informasjonen som sendes til hendelsesprosedyre feil antall en generell feil, for eksempel 3146, som tilsvarer feilmeldingen: ODBC-anrop mislyktes.

Årsak

ODBC-feilmeldinger består vanligvis av to komponenter. Den første delen er feil 3146, som har beskrivelsen er:

ODBC-kall mislyktes

Server-spesifikke feilinformasjon finnes i den andre delen, som du kan bruke til å hente et feilnummer og en beskrivelse for eksempel:

[Microsoft] [ODBC-Driver SQL Server] [SQL Server] < Server-spesifikke feilmelding > (#< feilnummer >)

Hvis du angir egenskapen OnError for et skjema til en hendelsesprosedyre, kan du fange opp nummeret på den første delen av feilen, men du kan ikke fange opp hvor mange andre komponenten. Server-spesifikk informasjon i den andre delen av ODBC-feilen vises på skjermen når koden ferdig, med mindre du inkluderer følgende linje i prosedyren:

Svar = acDataErrContinue

Oppløsning

Obs!: Microsoft tilbyr programming eksempler kun uten garanti enten direkte eller indirekte. Dette inkluderer, men er ikke begrenset til, implisitte garantier om salgbarhet eller trening for et bestemt formål. Denne artikkelen forutsetter at du er kjent med programmeringsspråket som er og verktøyene som brukes til å opprette og feilsøke prosedyrer. Microsoft-teknikere kan hjelpe deg med å forklare funksjonaliteten til en bestemt prosedyre, men de endrer ikke disse eksemplene for å gi forbedret funksjonalitet eller lage prosedyrer som dekker dine spesifikke krav.

Du kan opprette en Microsoft Visual Basic for Applications-prosedyre som bruker datatilgangsobjekter (DAO) til å oppdatere RecordsetClone som er basert på skjemaet. Dette lar deg til å fange opp en feilmelding om at du mottar.

DAO inneholder en feil samling som du kan bruke til å fange opp server-spesifikk informasjon i den andre delen av ODBC-feilen. Når en ODBC-feilen oppstår, den første delen er lagret i det første elementet i samlingen feil, og den andre delen er lagret i det andre elementet.

I eksemplet i denne artikkelen brukes hendelsen BeforeUpdate i stedet for hendelsen feil til å fange opp bestemte ODBC-feil. Hvis du vil opprette en funksjon som overlapper bestemte ODBC-feil når hendelsen FørOppdatering av et skjema, gjør du følgende:

  1. Opprette en tom skrivebordsdatabase.

  2. Kobling til tabellen dbo_Accounts i eksempeldatabasen AdventureWorks i Microsoft SQL Server.

  3. Bruke skjemaveiviseren - kolonne oppsett til å opprette et nytt skjema basert på tabellen kontoer.

  4. Lagre skjemaet som frmAccounts.

  5. Opprette en ny modul, og deretter skriver du inn følgende i delen deklarasjoner hvis linjen ikke allerede er det:

    Alternativet eksplisitt

  6. Skriv eller Lim inn følgende prosedyre i modulen:

    Public Function SaveRecODBC(SRO_form As Form) As Boolean
    ' ***************************************************************
    ' Function: SaveRecODBC
    ' Purpose: Updates a form based on a linked ODBC table
    ' and traps any ODBC errors.
    ' Arguments: SRO_Form, which refers to the form.
    ' Returns: True if successful or False if an error occurs.
    ' ***************************************************************
    On Error GoTo SaveRecODBCErr
    Dim fld As Field, ctl As Control
    Dim errStored As Error
    Dim rc As DAO.Recordset
    
    ' Check to see if the record has changed.
    If SRO_form.Dirty Then
        Set rc = SRO_form.Recordset.Clone
        If SRO_form.NewRecord Then
            rc.AddNew
            For Each ctl In SRO_form.Controls
                ' Check to see if it is the type of control
                ' that has a ControlSource.
                If ctl.ControlType = acTextBox Or _
                    ctl.ControlType = acComboBox Or _
                    ctl.ControlType = acListBox Or _
                    ctl.ControlType = acCheckBox Then
                    ' Verify that a value exists in the ControlSource.
                    If ctl.Properties("ControlSource") <> "" Then
                        ' Loop through the fields collection in the
                        ' RecordsetClone. If you find a field name
                        ' that matches the ControlSource, update the
                        ' field. If not, skip the field. This is
                        ' necessary to account for calculated controls.
                        For Each fld In rc.Fields
                            ' Find the field and verify
                            ' that it is not Null.
                            ' If it is Null, don't add it.
                            If fld.Name = ctl.Properties("ControlSource") _
                            And Not IsNull(ctl) Then
                                fld.Value = ctl
                                ' Exit the For loop
                                ' if you have a match.
                                Exit For
                            End If
                        Next fld
                    End If ' End If ctl.Properties("ControlSource")
                End If ' End If ctl.controltype
            Next ctl
            rc.Update
        Else
            ' This is not a new record.
            ' Set the bookmark to synchronize the record in the
            ' RecordsetClone with the record in the form.
            rc.Bookmark = SRO_form.Bookmark
            rc.Edit
            For Each ctl In SRO_form.Controls
                ' Check to see if it is the type of control
                ' that has a ControlSource.
                If ctl.ControlType = acTextBox Or _
                    ctl.ControlType = acComboBox Or _
                    ctl.ControlType = acListBox Or _
                    ctl.ControlType = acCheckBox Then
                    ' Verify that a value exists in the
                    ' ControlSource.
                    If ctl.Properties("ControlSource") <> "" Then
                        ' Loop through the fields collection in the
                        ' RecordsetClone. If you find a field name
                        ' that matches the ControlSource, update the
                        ' field. If not, skip the field. This is
                        ' necessary to account for calcualted controls.
                        For Each fld In rc.Fields
                            ' Find the field and make sure that the
                            ' value has changed. If it has not
                            ' changed, do not perform the update.
                            If fld.Name = ctl.Properties("ControlSource") _
                                And fld.Value <> ctl And _
                                Not IsNull(fld.Value <> ctl) Then
                                fld.Value = ctl
                                ' Exit the For loop if you have a match.
                                Exit For
                            End If
                        Next fld
                    End If ' End If ctl.Properties("ControlSource")
                End If ' End If ctl.controltype
            Next ctl
            rc.Update
        End If ' End If SRO_form.NewRecord
    End If ' End If SRO_form.Dirty
    ' If function has executed successfully to this point then
    ' set its value to True and exit.
    SaveRecODBC = True
    
    Exit_SaveRecODBCErr:
        Exit Function
    
    SaveRecODBCErr:
    ' The function failed because of an ODBC error.
    ' Below are a list of some of the known error numbers.
    ' If you are not receiving an error in this list,
    ' add that error to the Select Case statement.
    For Each errStored In DBEngine.Errors
        Select Case errStored.Number
            Case 3146 ' No action -- standard ODBC--Call failed error.
            Case 2627 ' Error caused by duplicate value in primary key.
                MsgBox "You tried to enter a duplicate value in the Primary Key."
            Case 3621 ' No action -- standard ODBC command aborted error.
            Case 547 ' Foreign key constraint error.
                MsgBox "You violated a foreign key constraint."
            Case Else ' An error not accounted for in the Select Case ' statement.
                On Error GoTo 0
                Resume
        End Select
    Next errStored
    SaveRecODBC = False
    Resume Exit_SaveRecODBCErr
    
    End Function
    
  7. Lagre modulen med et unikt navn, og lukk modulvinduet.

  8. Angi egenskapen BeforeUpdate av skjemaet frmAccounts følgende hendelsesprosedyre:

    Private Sub Form_BeforeUpdate(Cancel As Integer)
    ' If you can save the changes to the record undo the changes on the form.
    If SaveRecODBC(Me) Then Me.Undo
    ' If this is a new record go to the last record on the form.
    If Me.NewRecord Then
        RunCommand acCmdRecordsGoToLast
    Else
        ' If you can't update the record, cancel the BeforeUpdate event.
        Cancel = -1
    End If
    End Sub
    
  9. Klikk kompilere < navnet på databasen >feilsøking-menyen

  10. Hvis det oppstår ingen feil, kan du lagre skjemaet.

  11. Åpne skjemaet frmAccounts og legge til en ny post eller redigere en oppføring.

    Når du gjør en endring i en oppføring, lagres posten når du flytter til en annen oppføring. Hvis det oppstår en ODBC-feil, vises den egendefinerte meldingen som er basert på server-spesifikke feilen, og den generelle "ODBC: samtalen mislyktes" melding er fanget.

Bli bedre på Office
Utforsk opplæring
Vær først ute med de nye funksjonene
Bli med i Office Insiders

Var denne informasjonen nyttig?

Takk for tilbakemeldingen!

Takk for tilbakemeldingen! Det høres ut som det kan være lurt å sette deg i kontakt med én av våre Office-kundestøtteagenter.

×