• Function bẩy lỗi
  • Function bẩy lỗi

    mrsiro > 04-05-18, 11:46 AM

    Chào anh chị, để hiển thị lỗi khi sử dụng chương trình mình hay sử dụng 
    On error go to err

    Exit:
     Exit sub
    Err:
         errnumber errdescripton
        resume exit


    Nhưng mỗi event đều phải khai báo lập đi lập lại cú pháp như vậy.

    Có cách nào khai báo 1 function error, lúc này tại các event cần thiết chỉ cần call function error đó lên để dùng không cần phải viết từng dòng ở từng event.
  • RE: Function bẩy lỗi

    tranthanhan1962 > 04-05-18, 01:36 PM

    Đây là cú pháp xử lý lỗi bất kỳ trong code và có thể được đặt trong bất kỳ sub hoặc function nào. Cú pháp đầy đủ:
    Mã:
    Function ABC() /Sub BDE()
       ' Bật hệ thống xử lý lỗi.
       On Error GoTo Bị_lỗi /Hoặc ErrorOPQ/ErrorXYZ
              Lệnh 1
              Lệnh 2
              Lệnh 3
              .......
              Lệnh n
    Exit_Bị_lỗi /Hoặc ErrorOPQ/ErrorXYZ:
       Exit Function/Sub
    Error_Bị_lỗi /Hoặc ErrorOPQ/ErrorXYZ:
              Lệnh 1
              Lệnh 2
              Lệnh 3
              .......
              Lệnh n
    End Function
    Trường hợp ngắn gọn:
    Mã:
    Function ABC() /Sub BDE()
       ' Bật hệ thống xử lý lỗi.
       On Error GoTo Bị_lỗi
              Lệnh 1
              Lệnh 2
              Lệnh 3
              .......
              Lệnh n
    Bị_lỗi:
              Lệnh 1
              Lệnh 2
              Lệnh 3
              .......
              Lệnh n
    End Function
    Có nghĩa là tham số Bị_lỗi cho phép mã chương trình khi chạy đếu đâu bị bất kỳ lỗi gì nó  chũng đều phát hiện và bị dừng xử lý đế mã lệnh kế tiếp và truyền thẳng đến Bị_lỗi: để thực hiện các lệnh của Bị_lỗi: .
    Thực ra người ta xử dụng bẩy lỗi bất kỳ này trong trường hợp dự phòng khi phòng hờ có lỗi xảy ra mà code thủ chưa biết hoặc không biết lỗi gì (phòng ngừa hoặc dốt  007 )
    Giả sử trên form bạn có 3 texbox A, B, C. Khi bạn nhập số vào cho A và B thì C sẽ có giá trị = A/B. Lúc này bạn sẽ viết  các event cho B như sau:
    Mã:
    Private Sub B_AfterUpdate()
       C.Value = A.Value / B.Value
    End Sub
    Nhưng lúc này sẽ xảy ra trường hợp lỗi.
    1/Nếu A chứa text sẽ bị lỗi
    2/Nếu B=0 sẽ bị lỗi
    3/Xảy ra trường hợp nào đó bị lỗi mà mình chưa nghĩ ra.
    Nếu bạn xác định tất cả các trường hợp lỗi bạn có thể dùng if hoặc Select Case để xử lý. Nhưng ở đây nếu xảy ra một trường hợp lỗi nào khác thì sao? Suy nghĩ cho bằng được tất cả các trường hợp rồi viết tiếp  040 . Không cần chỉ cần phang đoạn code này vào là xong:
    Mã:
    Private Sub B_AfterUpdate()
       On Error GoTo Bị_lỗi
       C.Value = A.Value / B.Value
    Bị_lỗi:
       MsgBox "Đã bị lỗi"
       Exit Sub
    End Sub
    Vì vậy! Đây là một bẩy lỗi bất kỳ. Và tất nhiên khi bạn muốn đưa nó vào bất kỳ event, sub, function nào thì bạn cứ đưa vào. Mẫu của Microsoft đầy đủ thì có vẻ dài dòng nhưng khi sử dụng thực tế thì cực kỳ đơn giản

    On Error GoTo Bị_lỗi
    ......
    Bị_lỗi:
    ......
  • RE: Function bẩy lỗi

    mrsiro > 04-05-18, 05:42 PM

    Nếu mà có function thì code nhìn đẹp hơn, chứ 1 form mà cứ chèn on error các thứ nhìn nó rối bù. 005 005
  • RE: Function bẩy lỗi

    tranthanhan1962 > 04-05-18, 06:25 PM

    Chỉ cần 2 dòng code là xử lý xong. Quan trong là chạy tốt cứ khi viết code xong có ai nhìn
  • RE: Function bẩy lỗi

    ongke0711 > 05-05-18, 01:09 AM

    (04-05-18, 05:42 PM)mrsiro Đã viết: Nếu mà có function thì code nhìn đẹp hơn, chứ 1 form mà cứ chèn on error các thứ nhìn nó rối bù. 005 005

    Cú pháp bẫy lỗi chi tiết của VBA Access chỉ có 1 format là: (bỏ qua các bẫy lỗi "On Error Resume Next", "On Error Goto 0",  "On Error Goto 1")
        
        On Error Goto [label]   -> [Label]: có thể là "ErrHandler", "BayLoi", "EH" hay gì đó... tùy bạn đặt tên.

    Bạn không thể đưa Function vô vị trí [Label] để cho gọn đc vì sai cú pháp.
    Nếu muốn thiết kế function thì chỉ có thiết kế cho phần [Label] này thôi và nó cũng không đẹp hơn bao nhiêu, có thể gọn hơn chút nhưng đổi lại sẽ mất đi sự bẫy lỗi đặc thù cho từng event. Giống như code demo của anh tranthanhan1962, dùng Select Case để bẫy từng trường hợp mà nhưng case này khác nhau tùy theo từng nút lệnh, từng event.

    Ví dụ: 
         Select Case Err.Number
            Case 3021   —> Không có record. Dùng khi di chuyển record.
            Case  3022  —> Trùng mã PK. Dùng khi thêm mới record.
            Case  3044  —> Sai đường dẫn. Dùng chi chọn file.
         End Select
    Ứng với mỗi Case sẽ có code xử lý khác nhau tùy theo cái form, cái event đang chạy. Nếu chỉ thuần túy dùng Function chung chung để báo lỗi thì chẳng giúp ích người sử dụng là mấy khi gặp nhưng lỗi này.
  • RE: Function bẩy lỗi

    yamakashi2003 > 01-11-20, 10:48 AM

    (04-05-18, 01:36 PM)tranthanhan1962 Đã viết: Đây là cú pháp xử lý lỗi bất kỳ trong code và có thể được đặt trong bất kỳ sub hoặc function nào. Cú pháp đầy đủ:
    . Không cần chỉ cần phang đoạn code này vào là xong:
    Mã:
    Private Sub B_AfterUpdate()
       On Error GoTo Bị_lỗi
       C.Value = A.Value / B.Value
    Bị_lỗi:
       MsgBox "Đã bị lỗi"
       Exit Sub
    End Sub
    Vì vậy! Đây là một bẩy lỗi bất kỳ. Và tất nhiên khi bạn muốn đưa nó vào bất kỳ event, sub, function nào thì bạn cứ đưa vào. Mẫu của Microsoft đầy đủ thì có vẻ dài dòng nhưng khi sử dụng thực tế thì cực kỳ đơn giản

    On Error GoTo Bị_lỗi
    ......
    Bị_lỗi:
    ......
    Bác ơi cho em hỏi sao em chạy đoạn code này, không có lỗi gì cả mà nó vẫn hiện thông báo msgbox "đã bị lỗi" vậy ạ
    Private Sub Command36_Click()

    On Error GoTo loi
    n = 10 / 2
    MsgBox n

    loi:
    MsgBox "Ðã b? l?i"
    Exit Sub

    End Sub
  • RE: Function bẩy lỗi

    ongke0711 > 01-11-20, 02:28 PM

    (01-11-20, 10:48 AM)yamakashi2003 Đã viết: Bác ơi cho em hỏi sao em chạy đoạn code này, không có lỗi gì cả mà nó vẫn hiện thông báo msgbox "đã bị lỗi" vậy ạ
    Private Sub Command36_Click()

      On Error GoTo loi
      n = 10 / 2
      MsgBox n
     
    loi:
      MsgBox "Ðã b? l?i"
      Exit Sub

    End Sub

    Nguyên lý là code chạy từ trên xuống dưới, nếu không có lệnh gì giữa chừng để nhảy ra thì nó sẽ thực thi các dòng lệnh kế tiếp bên dưới.
    Code trên chỗ Label "loi:" không phải là lệnh dừng, nhảy, thoát nên nó tiếp tục chạy xuống dòng dưới "Msgbox ..." để thực thi tiếp. Do đó thông thường thì phải viết thêm dòng lệnh Exit Sub/Function cuối khối lệnh của bạn. Hoặc viết theo chuẩn như các ví dụ ở các bài trước.

    Viết lại:

    Mã PHP:
    Private Sub Command36_Click()

    On Error GoTo loi
      n 
    10 2
      MsgBox n
      
    Exit Sub

    loi
    :
      MsgBox "Ðã b? l?i"

    End Sub 

    hoặc

    Mã PHP:
    Private Sub Command36_Click()

      On Error GoTo loi
      n 
    10 2
      MsgBox n
      
    loi_exit
    :
       'Các dòng code xử lý trước khi thoát như: rs.Close, blnRet=False,...
       Exit Sub

    loi:
      MsgBox "Ðã b? l?i"
      Resume loi_exit

    End Sub