Giúp mình viết code bẫy lỗi "On error go to.."

Liên hệ QC

anhthuan

Thành viên hoạt động
Tham gia
10/12/06
Bài viết
106
Được thích
264
Dear All,

Mình có một sự kiện như sau:

private sub combobox1_afterupdate()
on error goto baoloi
............
baoloi:
msgbox "Khong co trong danh muc"
end sub

Mục đích của code trên là khi combox1 cho giá trị đúng thì OK, còn khi cho giá trị không nằm trong Rowsource thì hien msgbox để thông báo. Tuy nhiên vấn đề của mình là khi chạy code này, combox1 cho giá trị đúng thì msgbox vẫn hiện lên. Mình không hiểu code có bị sai không nữa.
Các bạn chỉ giúp mình với
Cám ơn rất nhiều
 
anhthuan đã viết:
Mình có một sự kiện như sau:

private sub combobox1_afterupdate()
on error goto baoloi
............
baoloi:
msgbox "Khong co trong danh muc"
end sub

Mục đích của code trên là khi combox1 cho giá trị đúng thì OK, còn khi cho giá trị không nằm trong Rowsource thì hien msgbox để thông báo. Tuy nhiên vấn đề của mình là khi chạy code này, combox1 cho giá trị đúng thì msgbox vẫn hiện lên. Mình không hiểu code có bị sai không nữa.

Thường khi ta đã test hết các trường hợp mà ta nghĩ ra và giải quyết xong rồi thì mới dùng bẫy lỗi on error để dành cho các trường hợp còn lại. Bạn muốn test xem sai chỗ nào thì phải bỏ bẫy lỗi đi, chạy thử cho trường hợp có giá trị đúng mà chương trình không hiểu xem bạn sai tại đoạn code nào. Thân.
 
Upvote 0
anhthuan đã viết:
Dear All,

Mình có một sự kiện như sau:

private sub combobox1_afterupdate()
on error goto baoloi
............
baoloi:
msgbox "Khong co trong danh muc"
end sub

Mục đích của code trên là khi combox1 cho giá trị đúng thì OK, còn khi cho giá trị không nằm trong Rowsource thì hien msgbox để thông báo. Tuy nhiên vấn đề của mình là khi chạy code này, combox1 cho giá trị đúng thì msgbox vẫn hiện lên. Mình không hiểu code có bị sai không nữa.
Các bạn chỉ giúp mình với
Cám ơn rất nhiều

Bạn thử nhé !!!

PHP:
Private Sub combobox1_afterupdate()
    On Error GoTo baoloi
        '............
        
    Exit Sub
baoloi:
    MsgBox "Khong co trong danh muc"
End Sub

Thân!
 
Upvote 0
Professional function format

Mã:
Private Function Test() As Boolean
'******************************************************************************
'*                                                                            *
'* Name:    Test                                                              *
'*                                                                            *
'* Purpose: Test only                                                         *
'*                                                                            *
'* Returns: True if OK                                                        *
'*                                                                            *
'******************************************************************************

On Error GoTo PROC_ERROR

  '// Assume function fails
  Test = False
  
  '// Your code here...
  '//...

  If Not YourFunction() Then GoTo PROC_DONE  '// This is a sample that show how to call another function which return True or False
  '// Continue your code....
  '// ...
  
  '// All's well - return True
  
  Test = True
  
PROC_DONE:
  '// Release resource here
  Exit Function

PROC_ERROR:
  Call Process_Error(MODULE_NAME, "Test")   '// This is the function that process the Error (may be raise the error msgbox)
  Resume PROC_DONE
End Function
 
Lần chỉnh sửa cuối:
Upvote 0
smbsolutions đã viết:
Professional function format
Bác có thể nói cụ thể hơn về cái code này không ạ ???
Kiểm tra sự không logic (chứ không phải cú pháp) của code à bác ???

Thân!
 
Upvote 0
cái Process_Error nó được code như thế nào vậy bác?

P/s: à, em hiểu như thế này:
một sub nào đó, nhận module và tên sub rồi hiện lên thông báo rằng sub đó ở module đó bị lỗi trong quá trình thi hành. Phải vậy không bác.
 
Lần chỉnh sửa cuối:
Upvote 0
Mr Okebab đã viết:
Bác có thể nói cụ thể hơn về cái code này không ạ ???
Kiểm tra sự không logic (chứ không phải cú pháp) của code à bác ???

Thân!

À, đó là tớ guideline cách viết code mà theo tớ là khá "đẹp" chứ ko phải fix cái code ở bài 1. Để tớ ví dụ cho Bab 1 đoạn code thực tế và tương đối đẹp nhé:

Mã:
Private Function SaveData() As Boolean
'******************************************************************************
'*                                                                            *
'* Name:    SaveData                                                          *
'*                                                                            *
'* Purpose: Save Detail and Master                                            *
'*                                                                            *
'* Returns: True ( SaveMaster = True AND SaveDetail = True  )                 *
'*                                                                            *
'******************************************************************************
On Error GoTo SaveData_Error

  '// Assume function fails
  SaveData = False
  
  '// Validation
  If Not IsValid Then GoTo SaveData_Done
      
  '// Save Master And Detail
  If Not SaveMaster() Then GoTo SaveData_Done
  If Not SaveDetail() Then
    If mMode = fEditFormOnAdding Then Call DeleteMaster: GoTo SaveData_Done
  End If
  
  '// Prepare refresh parent list form
  RefreshParent
  
  '// All's well - return True
  SaveData = True
  
SaveData_Done:
  Exit Function

SaveData_Error:
  Call Process_Error(MODULE_NAME, "SaveData")
  Resume SaveData_Done
End Function
@SoiBien: Process_Error(...) là tùy theo cách mà mỗi người viết thôi. Tớ thì hay viết đơn giản thế này Copy this code to a module named: ErrorUI.bas

Mã:
Option Explicit
'******************************************************************************
'*                                                                            *
'* Name:    Error.bas                                                         *
'*                                                                            *
'* Purpose: Used to process / handle all application errors.                  *
'*                                                                            *
'*----------------------------------------------------------------------------*
'* Modification Log                                                           *
'* t 07-Jan-2002 Generated by VBeXpress 2000.                               *
'*                                                                            *
'******************************************************************************
Private Const MODULE_NAME = "Error"

Public Const VALIDATION = "Validation"

Public Sub Process_Error(ByVal vstrModuleName As String, _
                         ByVal vstrProcName As String)
'******************************************************************************
'*                                                                             *
'* Name:    Process_Error                                                     *
'*                                                                            *
'* Purpose: All errors are reported here. This procedure could be used to     *
'*          write error logs, send e-mail to support personel informing them  *
'*          of application errors, etc.                                       *
'*                                                                            *
'*          Process_Error should be coded so that it will NEVER fail.         *
'*          Otherwise the error will not be reported. Also, it should not     *
'*          contain any error handling code. Otherwise the 'Err' object will  *
'*          be cleared and we won't be able get the error number or the error *
'*          description.                                                      *
'*                                                                            *
'******************************************************************************
Dim strMsg As String


  '// Could be a validation message
  If Err.Source = VALIDATION Then
    Beep
    MsgBox "Mã lỗi: " & Err.Number & vbCrLf & _
                      "Mô tả lỗi:" & Err.Description & vbCrLf & _
                      "Nguồn gây lỗi: " & Err.Source, vbExclamation, "ERROR"
  Else

    '// Setup message string
    '//strMsg = "An error has occurred in the application in module" & vbCrLf & _
             " '" & vstrModuleName & "' at procedure '" & vstrProcName & "'." & vbCrLf & vbCrLf & _
             "Error Number: " & CStr(Err.Number) & vbCrLf & vbCrLf & Err.Description & vbCrLf & vbCrLf & _
             "Please contact your system's administrator."

    '// If splash screen open, close it. Otherwise, we won't be able to see the message
    '// Note: Once we have the error number and description, it is ok to call other
    '// procedures and clear the error object.
    
'>>    If blnFormOpen("frmSplash") Then
'>>      Unload frmSplash
'>>      DoEvents
'>>    End If

    '// Inform user.
        If Err.Number > 5000 Then
            strMsg = Err.Description
            MsgBox strMsg, vbExclamation, MSG_HDR_ERR_USER
        Else
            strMsg = "Lỗi xảy ra trong ứng dụng ở module" & vbCrLf & _
                 " '" & vstrModuleName & "' tại thủ tục '" & vstrProcName & "'." & vbCrLf & vbCrLf & _
                 "Mã lỗi: " & CStr(Err.Number) & vbCrLf & vbCrLf & Err.Description & vbCrLf & vbCrLf & _
                 "Hãy ghi lại các thông số về lỗi và thông báo cho người quản trị hệ thống hoặc liên lạc trực tiếp với tác giả."
            
            MsgBox strMsg, vbCritical, MSG_HDR_ERR_APP
        End If
        Beep
  End If


  '// Add code to log errors, e-mail support, etc.

End Sub
Hầu hết tất cả những code trong chương trình tớ đều viết cùng 1 style và viết y chang như nhau (style này tớ áp dụng 1 add-ins tương đối nổi tiếng, và đại đa số là do máy sinh ra). Chính vì thế, sau 5 năm tớ đọc lại code vẫn còn nhớ nguyên si từng dòng lệnh có ý nghĩa như thế nào. Và tính thống nhất (consistency) được thể hiện trong tất cả các dự án (chứ ko chỉ trong 1 dự án hay trong 1 phần mềm cụ thể)

Thêm 1 guideline nữa là các bạn hãy cực kỳ cẩn thận khi viết code ở các event của controls vì rất có thể trùng lắp (chạy rất nhiều lần mà ko biết) và ko phải cái gì cũng nhét tá lả vào ..._AfterUpdate() hay vào ..._Change() được đâu.

Các bạn cũng luôn luôn nhớ là debug kỹ càng bằng cách sử dụng F9 (Bookmark), F8 (step by line), Shift F8 (by block step), Debug.Print v.v... để hiểu kỹ các events cùng các giá trị được thiết lập như thế nào trong chương trình của bạn.

Nhìn cái đoạn code nằm trong ..._AfterUpdate() ở trên (ở bài trên cùng gây ra lỗi mà bạn ko hiểu là lỗi gì đó) thì tớ cứ thấy có cảm giác cực kỳ bất an với chương trình của bạn mặc dù chưa nhìn thấy nó như thế nào. Nếu có viết thì hãy "vứt" cái đoạn code bên trong đó ra thành 1 thủ tục hay hàm nào đó để cho "đẹp". Đừng có viết code quá dài (hạn chế càng nhiều càng tốt) trong events của các controls.

Mã:
Private Sub kscFields_Click(Index As Integer)
  MakeDirty enuMaster, True
  
  If blnIsLoadingForm Then Exit Sub
  If Index = CST_FLD_MASTER_STOREID Then
    If kscFields(CST_FLD_MASTER_STOREID).ListIndex <> -1 Then
      kscDetailItem(CST_FLD_DETAIL_STOREID).ListIndex = kscFields(CST_FLD_MASTER_STOREID).ListIndex
    Else
      kscDetailItem(CST_FLD_DETAIL_STOREID).ListIndex = ItemDataToListIndex(kscDetailItem(CST_FLD_DETAIL_STOREID), CST_DEF_STORE_VALUE)  '// Default Store
    End If
  End If
  
End Sub
Ở đoạn code trên, các bạn chú ý các dòng như:

If blnIsLoadingForm Then Exit Sub '// Tức là ko chạy even này nếu form is loading. Điều này để tránh chạy lặp nếu .ListIndex <> -1 khi thiết lập ở 1 chỗ khác nếu có.

Hoặc If kscFields(CST_FLD_MASTER_STOREID).ListIndex <> -1 Then '// Chỉ thực hiện những đoạn lệnh tiếp theo khi ListIndex <> -1 (Đây là cái thường xuyên gây ra lỗi hoặc việc "chạy bất thường ko theo dự đoán" ở các chương trình mà mình thấy)

Tóm lại, khi viết mỗi 1 dòng code, bạn phải liên tục để ý những trường hợp khác xảy ra thì sẽ thế nào. Nếu có thói quen như vậy, chương trình của bạn sẽ hạn chế được rất nhiều lỗi "không thể chấp nhận được".
 
Lần chỉnh sửa cuối:
Upvote 0
Sorry mọi người, FF browser của tớ hnay lại có vấn đề nên ko post bài cho đẹp được (code nó cứ thành 1 dòng). Thỉnh thoảng tớ cứ bị cãi lỗi này. Tiếc quá! :(
 
Lần chỉnh sửa cuối:
Upvote 0
cố dịch lại code của bác Smb cho mọi người cùng tham khảo
Mã:
[COLOR=darkblue]Private[/COLOR] [COLOR=darkblue]Function[/COLOR] SaveData() [COLOR=darkblue]As[/COLOR] [COLOR=darkblue]Boolean[/COLOR]
[COLOR=green]'************************************************[/COLOR]
[COLOR=green]'*                                                                       *[/COLOR]
[COLOR=green]'* Name:    SaveData                                                     *[/COLOR]
[COLOR=green]'*                                                                       *[/COLOR]
[COLOR=green]'* Purpose: Save Detail and Master                                       *[/COLOR]
[COLOR=green]'*                                                                       *[/COLOR]
[COLOR=green]'* Returns: True ( SaveMaster = True ANDSaveDetail=True  )     *[/COLOR]
[COLOR=green]'*                                                                       *[/COLOR]
[COLOR=green]'**************************************************[/COLOR]
[COLOR=darkblue]On[/COLOR] [COLOR=darkblue]Error[/COLOR] [COLOR=darkblue]GoTo[/COLOR] SaveData_Error
[COLOR=darkblue]Dim[/COLOR] lngNumberOfTransactions [COLOR=darkblue]As[/COLOR] [COLOR=darkblue]Long[/COLOR]
[COLOR=green]'// Assume function fails[/COLOR]
SaveData = [COLOR=darkblue]False[/COLOR]
[COLOR=green]'// Validation before saving[/COLOR]
[COLOR=darkblue]If[/COLOR] [COLOR=darkblue]Not[/COLOR] IsValid [COLOR=darkblue]Then[/COLOR] [COLOR=darkblue]GoTo[/COLOR] SaveData_Done
[COLOR=green]'// Save Master And Detail[/COLOR]
[COLOR=darkblue]If[/COLOR] [COLOR=darkblue]Not[/COLOR] SaveMaster() [COLOR=darkblue]Then[/COLOR] [COLOR=darkblue]GoTo[/COLOR] SaveData_Done
[COLOR=darkblue]If[/COLOR] [COLOR=darkblue]Not[/COLOR] SaveDetail() [COLOR=darkblue]Then[/COLOR]
[COLOR=darkblue]If[/COLOR] mMode = fEditFormOnAdding [COLOR=darkblue]Then[/COLOR]
[COLOR=darkblue]Call[/COLOR] DeleteMaster:
[COLOR=darkblue]GoTo[/COLOR] SaveData_Done
[COLOR=darkblue]End[/COLOR] [COLOR=darkblue]If[/COLOR]
[COLOR=green]'// Prepare refresh parent list form   RefreshParent[/COLOR]
[COLOR=green]'// All's well - return True[/COLOR]
SaveData = True
SaveData_Done:
[COLOR=darkblue]Exit[/COLOR] [COLOR=darkblue]Function[/COLOR]
SaveData_Error:
[COLOR=darkblue]Call[/COLOR] Process_Error(MODULE_NAME, "SaveData")
[COLOR=darkblue]Resume[/COLOR] SaveData_Done
[COLOR=darkblue]End[/COLOR] [COLOR=darkblue]Function[/COLOR]

Mã:
[COLOR=darkblue]Option[/COLOR] [COLOR=darkblue]Explicit[/COLOR]    [COLOR=green]'******************************************************************************[/COLOR]
[COLOR=green]'*                                                                            *[/COLOR]
[COLOR=green]'* Name:    Error.bas                                                         *[/COLOR]
[COLOR=green]'*                                                                            *[/COLOR]
[COLOR=green]'* Purpose: Used to process / handle all application errors.                  *[/COLOR]
[COLOR=green]'*                                                                            *[/COLOR]
[COLOR=green]'*----------------------------------------------------------------------------*[/COLOR]
[COLOR=green]'* Modification Log                                                           *[/COLOR]
[COLOR=green]'* t 07-Jan-2002   Generated by VBeXpress 2000.                               *[/COLOR]
[COLOR=green]'*                                                                            *[/COLOR]
[COLOR=green]'******************************************************************************[/COLOR]
[COLOR=darkblue]Private[/COLOR] [COLOR=darkblue]Const[/COLOR] MODULE_NAME = "Error"
[COLOR=darkblue]Public[/COLOR]  [COLOR=darkblue]Const[/COLOR] VALIDATION = "Validation"
[COLOR=darkblue]Public[/COLOR] [COLOR=darkblue]Sub[/COLOR] Process_Error([COLOR=darkblue]ByVal[/COLOR] vstrModuleName [COLOR=darkblue]As[/COLOR] [COLOR=darkblue]String[/COLOR], [COLOR=darkblue]ByVal[/COLOR] vstrProcName [COLOR=darkblue]As[/COLOR] [COLOR=darkblue]String[/COLOR])
[COLOR=darkblue]End[/COLOR] [COLOR=darkblue]Sub[/COLOR]
[COLOR=green]'******************************************************************************[/COLOR]
[COLOR=green]'*                                                                            *[/COLOR]
[COLOR=green]'* Name:    Process_Error                                                     *[/COLOR]
[COLOR=green]'*                                                                            *[/COLOR]
[COLOR=green]'* Purpose: All errors are reported here. This procedure could be used to     *[/COLOR]
[COLOR=green]'*          write error logs, send e-mail to support personel informing them  *[/COLOR]
[COLOR=green]'*          of application errors, etc.                                       *[/COLOR]
[COLOR=green]'*                                                                            *[/COLOR]
[COLOR=green]'*          Process_Error should be coded so that it will NEVER fail.         *[/COLOR]
[COLOR=green]'*          Otherwise the error will not be reported. Also, it should not     *[/COLOR]
[COLOR=green]'*          contain any error handling code. Otherwise the 'Err' object will  *[/COLOR]
[COLOR=green]'*          be cleared and we won't be able get the error number or the error *[/COLOR]
[COLOR=green]'*          description.                                                      *[/COLOR]
[COLOR=green]'*                                                                            *[/COLOR]
[COLOR=green]'******************************************************************************[/COLOR]
[COLOR=darkblue]Dim[/COLOR] strMsg [COLOR=darkblue]As[/COLOR] [COLOR=darkblue]String[/COLOR]     [COLOR=green]'// Could be a validation message[/COLOR]
[COLOR=darkblue]If[/COLOR] Err.Source = Validation [COLOR=darkblue]Then[/COLOR]
    Beep
    MsgBox "M· lçi: " & Err.Number & vbCrLf & _
           "M« t¶ lçi:" & Err.Description & vbCrLf & _
           "Nguån g©y lçi: " & Err.Source, vbExclamation, "ERROR"
[COLOR=darkblue]Else[/COLOR]      [COLOR=green]'// Setup message string[/COLOR]
    [COLOR=green]'//strMsg = "An error has occurred in the application in module" & vbCrLf & _
     " '" & vstrModuleName & "' at procedure '" & vstrProcName & "'." & vbCrLf & vbCrLf & _
     "Error Number: " & CStr(Err.Number) & vbCrLf & vbCrLf & Err.Description & vbCrLf & vbCrLf & _
     "Please contact your system's administrator."[/COLOR]
    [COLOR=green]'// If splash screen open, close it. Otherwise, we won't be able to see the message[/COLOR]
    [COLOR=green]'// Note: Once we have the error number and description, it is ok to call other[/COLOR]
    [COLOR=green]'// procedures and clear the error object.[/COLOR]
    [COLOR=green]'// Inform user.[/COLOR]
    [COLOR=darkblue]If[/COLOR] Err.Number > 5000 [COLOR=darkblue]Then[/COLOR]
        strMsg = Err.Description
        MsgBox strMsg, vbExclamation, MSG_HDR_ERR_USER
    [COLOR=darkblue]Else[/COLOR]
        strMsg = "Lçi x¶y ra trong øng dông ë module" & vbCrLf & _
                 " '" & vstrModuleName & "' t¹i thñ tôc '" & vstrProcName & "'." & vbCrLf & vbCrLf & _
                 "M· lçi: " & CStr(Err.Number) & vbCrLf & vbCrLf & Err.Description & vbCrLf & vbCrLf & _
                 "H·y ghi l¹i c¸c th«ng sè vÒ lçi vµ th«ng b¸o cho ng&shy;êi qu¶n trÞ hÖ thèng hoÆc liªn l¹c trùc tiÕp víi t¸c gi¶."
        MsgBox strMsg, vbCritical, MSG_HDR_ERR_APP
    [COLOR=darkblue]End[/COLOR] [COLOR=darkblue]If[/COLOR]
    Beep
[COLOR=darkblue]End[/COLOR] [COLOR=darkblue]If[/COLOR]    
[COLOR=green]'// Add code to log errors, e-mail support, etc.[/COLOR]
[COLOR=darkblue]End[/COLOR] [COLOR=darkblue]Sub[/COLOR]

Mã:
[color=darkblue]Private[/color] [color=darkblue]Sub[/color] kscFields_Click(Index [color=darkblue]As[/color] [color=darkblue]Integer[/color])
    MakeDirty enuMaster, [color=darkblue]True[/color]
    [color=darkblue]If[/color] blnIsLoadingForm [color=darkblue]Then[/color] [color=darkblue]Exit[/color] [color=darkblue]Sub[/color]
    [color=darkblue]If[/color] Index = CST_FLD_MASTER_STOREID [color=darkblue]Then[/color]
        [color=darkblue]If[/color] kscFields(CST_FLD_MASTER_STOREID).ListIndex - 1 [color=darkblue]Then[/color]
            kscDetailItem(CST_FLD_DETAIL_STOREID).ListIndex = kscFields(CST_FLD_MASTER_STOREID).ListIndex
        [color=darkblue]Else[/color]
            kscDetailItem(CST_FLD_DETAIL_STOREID).ListIndex = ItemDataToListIndex(kscDetailItem(CST_FLD_DETAIL_STOREID), CST_DEF_STORE_VALUE)
            [color=green]'// Temp[/color]
        [color=darkblue]End[/color] [color=darkblue]If[/color]
    [color=darkblue]End[/color] [color=darkblue]If[/color]
End [color=darkblue]Sub[/color]
 
Lần chỉnh sửa cuối:
Upvote 0
Web KT

Bài viết mới nhất

Back
Top Bottom