Không thể bẫy lỗi cụ thể ODBC trong OnError thuộc tính biểu mẫu (KB 206175)

Lưu ý: Chúng tôi muốn cung cấp cho bạn nội dung trợ giúp mới nhất ở chính ngôn ngữ của bạn, nhanh nhất có thể. Trang này được dịch tự động nên có thể chứa các lỗi về ngữ pháp hoặc nội dung không chính xác. Mục đích của chúng tôi là khiến nội dung này trở nên hữu ích với bạn. Vui lòng cho chúng tôi biết ở cuối trang này rằng thông tin có hữu ích với bạn không? Dưới đây là bài viết bằng Tiếng Anh để bạn tham khảo dễ hơn.

Nếu bạn đặt thuộc tính OnError biểu mẫu truy nhập một thủ tục sự kiện, bạn không thể truy xuất mô tả lỗi ODBC trong thủ tục đó, và bạn cũng không thể bẫy lỗi ODBC cụ thể. Khi xảy ra lỗi ODBC, thông tin chỉ được chuyển qua thủ tục sự kiện lỗi là số một chung lỗi, chẳng hạn như 3146, tương ứng với thông báo lỗi: ODBC, cuộc gọi không thành công.

Nguyên nhân

Thông báo lỗi ODBC thường bao gồm hai cấu phần. Các thành phần đầu tiên là lỗi 3146, mô tả có là:

Cuộc gọi ODBC không thành công

Thông tin cụ thể của máy chủ lỗi được chứa trong cấu phần thứ hai, từ đó bạn có thể truy xuất một số lỗi và mô tả chẳng hạn như:

[Microsoft] [Trình điều khiển ODBC SQL Server] [SQL Server] < thông báo lỗi cụ thể của máy chủ > (#< lỗi số >)

Nếu bạn đặt thuộc tính OnError biểu mẫu một thủ tục sự kiện, bạn có thể bẫy số cấu phần đầu tiên của lỗi, nhưng bạn không thể bẫy số cấu phần thứ hai. Thông tin máy chủ cụ thể trong phần thứ hai của ODBC lỗi sẽ xuất hiện trên màn hình sau khi mã đã hoàn tất chạy, trừ khi bạn đưa vào dòng sau đây trong sự kiện thủ tục:

Phản hồi = acDataErrContinue

Giải pháp

Lưu ý: Microsoft cung cấp ví dụ lập trình để minh họa chỉ, mà không cần bảo hành được thể hiện hoặc ngụ ý. Điều này bao gồm, nhưng không giới hạn, bảo đảm bán hoặc cho một mục đích cụ thể. Bài viết này giả định rằng bạn đã quen thuộc với ngôn ngữ lập trình được chứng minh và với công cụ được dùng để tạo và để gỡ lỗi thủ tục. Microsoft hỗ trợ kỹ sư có thể giúp giải thích các chức năng của một thủ tục cụ thể, nhưng chúng sẽ không sửa đổi các ví dụ này để cung cấp thêm chức năng hoặc xây dựng các thủ tục để đáp ứng yêu cầu cụ thể của bạn.

Bạn có thể tạo Microsoft Visual Basic cho ứng dụng thủ tục sử dụng các đối tượng truy nhập dữ liệu (DAO) để cập nhật một RecordsetClone dựa trên biểu mẫu. Điều này cho phép bạn bẫy bất kỳ thông báo lỗi mà bạn nhận được.

DAO chứa một tuyển tập lỗi bạn có thể dùng để bẫy thông tin máy chủ cụ thể trong phần thứ hai của lỗi ODBC. Khi xảy ra lỗi ODBC, các thành phần đầu tiên được lưu trữ trong thành phần đầu tiên của tuyển tập lỗi và cấu phần thứ hai được lưu trữ trong thành phần thứ hai.

Ví dụ trong bài viết này dùng sự kiện BeforeUpdate thay vì sự kiện lỗi để bẫy lỗi ODBC cụ thể. Để tạo một hàm bẫy lỗi ODBC cụ thể khi xảy ra sự kiện BeforeUpdate biểu mẫu, hãy làm theo các bước sau đây:

  1. Tạo cơ sở dữ liệu trên máy tính trống.

  2. Nối kết đến dbo_Accounts bảng trong cơ sở dữ liệu mẫu AdventureWorks trong Microsoft SQL Server.

  3. Sử dụng trình hướng dẫn biểu mẫu - các bố trí cột để tạo biểu mẫu dựa trên bảng tài khoản.

  4. Lưu biểu mẫu dưới dạng frmAccounts.

  5. Tạo một mô-đun mới, sau đó nhập dòng sau đây trong phần khai báo nếu dòng đó không sẵn có:

    Tùy chọn rõ ràng

  6. Nhập hoặc dán thủ tục sau đây vào mô-đun:

    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. Lưu mô-đun có tên duy nhất và đóng cửa sổ mô-đun.

  8. Đặt thuộc tính BeforeUpdate của biểu mẫu frmAccounts thủ tục sự kiện sau đây:

    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. Trên menu gỡ lỗi , bấm biên soạn < tên của cơ sở dữ liệu >

  10. Nếu không có lỗi xảy ra, hãy lưu biểu mẫu.

  11. Mở biểu mẫu frmAccounts, và sau đó thêm một bản ghi mới hoặc sửa một bản ghi.

    Khi bạn thực hiện thay đổi với bản ghi, bản ghi được lưu khi bạn di chuyển đến một bản ghi khác. Nếu lỗi ODBC xảy ra, bạn thấy thông báo tùy chỉnh dựa trên lỗi cụ thể của máy chủ, và chung "ODBC--cuộc gọi không thành công" thư bị kẹt.

Phát triển kỹ năng Office của bạn
Khám phá nội dung đào tạo
Sở hữu tính năng mới đầu tiên
Tham gia Người dùng nội bộ Office

Thông tin này có hữu ích không?

Cảm ơn phản hồi của bạn!

Cảm ơn bạn đã phản hồi! Để trợ giúp tốt hơn, có lẽ chúng tôi sẽ kết nối bạn với một trong những nhân viên hỗ trợ Office của chúng tôi.

×