無法攔截 OnError 屬性的表單 (KB 206175) 中的特定 ODBC 錯誤

附註: 我們想要以您的語言,用最快的速度為您提供最新的說明內容。本頁面是經由自動翻譯而成,因此文中可能有文法錯誤或不準確之處。讓這些內容對您有所幫助是我們的目的。希望您能在本頁底部告訴我們這項資訊是否有幫助。此為英文文章出處,以供參考。

如果您的 Access 表單的 [OnError] 屬性設定事件程序時,您無法擷取 ODBC 錯誤的程序中的描述,也無法攔截特定 ODBC 錯誤。傳遞給錯誤事件程序的唯一資訊 ODBC 錯誤時,是一般錯誤,例如 3146,對應到錯誤訊息的數目: ODBC 呼叫失敗。

原因

ODBC 錯誤訊息通常包含兩個元件。第一個元件是的錯誤 3146,其說明:

ODBC 呼叫失敗

在第二個元件錯誤號碼],然後的描述,例如,您可以擷取包含的伺服器特定錯誤訊息:

[Microsoft][ODBC SQL Server 驅動程式][SQL Server] < 伺服器特定錯誤訊息 > (#< 錯誤號碼 >)

如果您設定OnError屬性表單的事件程序,您可以攔截的第一個元件的錯誤,但您無法攔截第二個元件的數目。ODBC 錯誤的第二部分中的伺服器特定資訊會出現在螢幕上的程式碼完畢後執行,除非您在事件中包含的下列行程序:

回應 = acDataErrContinue

解析度

附註: Microsoft 提供不明示或隱含的圖例、 程式設計的範例。這包含,,但不限於銷售或適合特定用途的隱含的擔保責任。本文假設您已熟悉示範所程式設計語言與用來建立並偵錯程序的工具。Microsoft 技術支援工程師可以協助說明特定的程序的功能,但不是會修改這些範例,以提供新增的功能,或建構程序,以符合您特定需求。

您可以建立 Microsoft Visual Basic for 使用資料存取物件 (DAO) 更新記錄集表單為基礎的應用程式程序。這個選項可讓您攔截您收到任何錯誤訊息。

DAO 包含錯誤集合的可用來攔截 ODBC 錯誤的第二部分中的伺服器特定資訊。ODBC 錯誤時,第一個元件已儲存的集合,第一個項目,並將第二個元件儲存在第二個項目。

本文中的範例會使用BeforeUpdate事件,而不是錯誤事件來攔截特定 ODBC 錯誤。若要建立表單的BeforeUpdate事件發生時,對特定 ODBC 錯誤的函數,請遵循下列步驟:

  1. 建立空白桌面資料庫。

  2. 連結至 Microsoft SQL Server 中的 [AdventureWorks] 樣本資料庫中 dbo_Accounts 資料表。

  3. 使用 [表單精靈]-[建立新帳戶資料表為基礎的表單的欄版面配置。

  4. 儲存表單為 frmAccounts。

  5. 建立新的模組,然後輸入 [宣告] 區段中的下列行,如果該列不是已有:

    Option Explicit

  6. 輸入或貼上下列程序的模組:

    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. 儲存模組具有唯一的名稱,並關閉 [模組] 視窗。

  8. FrmAccounts 表單BeforeUpdate屬性設定為下列事件程序:

    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. 按一下 [偵錯] 功能表上的 [編譯 < 資料庫的名稱 >

  10. 如果沒有發生錯誤,請儲存表單。

  11. 開啟 frmAccounts 表單,然後新增一筆新記錄或編輯記錄。

    當您變更記錄時,當您移動到不同的記錄時,會儲存記錄。如果發生 ODBC 錯誤,您會看到伺服器特定錯誤,為基礎的自訂訊息和一般 「 ODBC-呼叫失敗 」 的訊息會被。

增進您的 Office 技巧
探索訓練
優先取得新功能
加入 Office 測試人員

這項資訊有幫助嗎?

感謝您的意見反應!

感謝您的意見反應! 我們將協助您與其中一位 Office 支援專員連絡以深入了解您的意見。

×