我不想为我的代码中的每个循环结构制作特殊的错误处理程序,因此我有一种方法可以使用我的标准错误处理程序来查找问题循环,这样我就可以为它们编写一个特殊的错误处理程序。
如果在循环中发生错误,我通常想知道导致错误的原因,而不是跳过它。为了找出这些错误,我像许多人一样将错误消息写入日志文件。但是,如果循环中发生错误,则写入日志文件是危险的,因为每次循环迭代都会触发错误,在我的情况下,80 000 次迭代并不少见。因此,我将一些代码放入我的错误记录函数中,以检测相同的错误并跳过将它们写入错误日志。
用于每个过程的标准错误处理程序如下所示。它记录了错误类型、发生错误的过程以及过程接收到的任何参数(在本例中为 FileType)。
procerr:
Call NewErrorLog(Err.number, Err.Description, "GetOutputFileType", FileType)
Resume exitproc
我写入表的错误记录功能(我在 ms-access 中)如下。它使用静态变量来保留错误数据的先前值并将它们与当前版本进行比较。记录第一个错误,然后如果我是用户,则第二个相同的错误会将应用程序推入调试模式,或者如果处于其他用户模式,则退出应用程序。
Public Function NewErrorLog(ErrCode As Variant, ErrDesc As Variant, Optional Source As Variant = "", Optional ErrData As Variant = Null) As Boolean
On Error GoTo errLogError
'Records errors from application code
Dim dbs As Database
Dim rst As Recordset
Dim ErrorLogID As Long
Dim StackInfo As String
Dim MustQuit As Boolean
Dim i As Long
Static ErrCodeOld As Long
Static SourceOld As String
Static ErrDataOld As String
'Detects errors that occur in loops and records only the first two.
If Nz(ErrCode, 0) = ErrCodeOld And Nz(Source, "") = SourceOld And Nz(ErrData, "") = ErrDataOld Then
NewErrorLog = True
MsgBox "Error has occured in a loop: " & Nz(ErrCode, 0) & Space(1) & Nz(ErrDesc, "") & ": " & Nz(Source, "") & "[" & Nz(ErrData, "") & "]", vbExclamation, Appname
If Not gDeveloping Then 'Allow debugging
Stop
Exit Function
Else
ErrDesc = "[loop]" & Nz(ErrDesc, "") 'Flag this error as coming from a loop
MsgBox "Error has been logged, now Quiting", vbInformation, Appname
MustQuit = True 'will Quit after error has been logged
End If
Else
'Save current values to static variables
ErrCodeOld = Nz(ErrCode, 0)
SourceOld = Nz(Source, "")
ErrDataOld = Nz(ErrData, "")
End If
'From FMS tools pushstack/popstack - tells me the names of the calling procedures
For i = 1 To UBound(mCallStack)
If Len(mCallStack(i)) > 0 Then StackInfo = StackInfo & "\" & mCallStack(i)
Next
'Open error table
Set dbs = CurrentDb()
Set rst = dbs.OpenRecordset("tbl_ErrLog", dbOpenTable)
'Write the error to the error table
With rst
.AddNew
!ErrSource = Source
!ErrTime = Now()
!ErrCode = ErrCode
!ErrDesc = ErrDesc
!ErrData = ErrData
!StackTrace = StackInfo
.Update
.BookMark = .LastModified
ErrorLogID = !ErrLogID
End With
rst.Close: Set rst = Nothing
dbs.Close: Set dbs = Nothing
DoCmd.Hourglass False
DoCmd.Echo True
DoEvents
If MustQuit = True Then DoCmd.Quit
exitLogError:
Exit Function
errLogError:
MsgBox "An error occured whilst logging the details of another error " & vbNewLine & _
"Send details to Developer: " & Err.number & ", " & Err.Description, vbCritical, "Please e-mail this message to developer"
Resume exitLogError
End Function
请注意,错误记录器必须是应用程序中最可靠的功能,因为应用程序无法正常处理错误记录器中的错误。出于这个原因,我使用 NZ() 来确保 null 不会潜入。请注意,我还将 [loop] 添加到第二个相同的错误中,以便我知道首先查看错误过程中的循环。