我不想手艺特殊的错误处理程序在我的代码每次循环结构,所以我必须找到问题的办法用我的标准错误处理回路,让我能然后为它们写一个特殊的错误处理程序。
如果在循环中发生错误,我通常想知道导致错误的原因,而不是跳过它。为了找出这些错误,我和许多人一样将错误消息写入日志文件。但是,如果在循环中发生错误,写入日志文件是很危险的,因为每次循环迭代时都会触发错误,在我的情况下,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()来确保空值不能潜入。注意,我还将[loop]添加到第二个相同的错误,以便我知道首先在错误过程中查找循环。
不存在不是查询表的“列表对象”吗?我需要该工作表有一个查询表。 –
@Justin,如果是这样,为'ListObjects(1).QueryTable Is Nothing'添加一个测试 - 你的代码也没有这个测试。我的示例的主要观点是在取消引用第一个元素之前检查ListObjects集合是否具有任何元素。 – Joe