Excel VBA全局error handling

有没有办法做全球error handling?

我可以在工作簿代码中join一些代码来捕获所有模块中发生的任何错误吗?

我可以在每个模块中放置相同的error handling程序,但我正在寻找更一般的东西。

我问,因为我有工作表名称存储为像这样的Sheets(QuoteName)全局variables。 如果有错误,那么这些全局variables将会丢失。 我有一个macros将重命名全局variables,但我把它放在Workbook_BeforeSave

我希望它去到全局error handling程序,并重命名全局variables,如果我得到一个下标超出范围错误Sheets(QuoteName)

正如Sid在评论中已经提到的,没有中央的error handling程序。

最佳做法是从本地error handling程序调用中央error handling例程。 看看伟大的MZ-Tools :它可以通过按下一个button( CtrlE )来定义一个默认的error handling程序。 你可以自定义这个error handling程序 – 它也可以包含模块和/或子名称!

另外,请在Daily Dose of Excel上查看这篇文章。 这是Dick Kusleika在本书中提出的error handling程序的OO版本(我可以强烈推荐)。

这里有一些代码我扔在一起来处理访问中的问题

它把错误检查在所有潜艇,但不是function。 子必须有父表单(ACCESS),或者,您必须手动input表单名称。 继续超过一条线的潜艇将被无情地打击。

这两个子必须位于模块的底部。

  • globalerror是你的错误pipe理程序
  • CleaVBA_click更改您的VBA代码,将行号添加到一切

globalerror看着一个布尔全局errortracking ,看它是否logging一切或只有错误

有一个表错误跟踪,必须创build,否则只是从1990年至2160年注释掉

在运行时,它会删除,然后将行号添加到项目中的所有内容,所以您的错误消息可以包含一行#

不知道它是否适用于我编码的东西以外的任何东西。

一定要运行和testing你的VBA的副本,因为它真正地重写了项目中的每一行代码,如果我搞砸了,而你没有备份,那么你的项目就被打破了。

  Public Sub globalerror(Name As String, number As Integer, Description As String, source As String) 1970 Dim db As DAO.Database 1980 Dim rst As DAO.Recordset 1990 If errortracking Or (Err.number <> 0) Then 2000 Set db = CurrentDb 2010 Set rst = db.OpenRecordset("ErrorTracking") 2020 rst.AddNew 2030 rst.Fields("FormModule") = Name 2040 rst.Fields("ErrorNumber") = number 2050 rst.Fields("Description") = Description 2060 rst.Fields("Source") = source 2070 rst.Fields("timestamp") = Now() 2080 rst.Fields("Line") = Erl 2100 rst.Update 2110 rst.Close 2120 db.Close 2130 End If 2140 If Err.number = 0 Then 2150 Exit Sub 2160 End If 2170 MsgBox "ERROR" & vbCrLf & "Location: " & Name & vbCrLf & "Line: " & Erl & vbCrLf & "Number: " & number & vbCrLf & "Description: " & Description & vbCrLf & source & vbCrLf & Now() & vbCrLf & vbCrLf & "custom message" 2180 End Sub Private Sub CleanVBA_Click() Dim linekill As Integer Dim component As Object Dim index As Integer Dim str As String Dim str2a As String Dim linenumber As Integer Dim doline As Boolean Dim skipline As Boolean Dim selectflag As Boolean Dim numstring() As String skipline = False selectflag = False tabcounter = 0 For Each component In Application.VBE.ActiveVBProject.VBComponents linekill = component.CodeModule.CountOfLines linenumber = 0 For i = 1 To linekill str = component.CodeModule.Lines(i, 1) doline = True If Right(Trim(str), 1) = "_" Then doline = False skipline = True End If If Len(Trim(str)) = 0 Then doline = False End If If InStr(Trim(str), "'") = 1 Then doline = False End If If selectflag Then doline = False End If If InStr(str, "Select Case") > 0 Then selectflag = True End If If InStr(str, "End Select") > 0 Then selectflag = False End If If InStr(str, "Global ") > 0 Then doline = False End If If InStr(str, "Sub ") > 0 Then doline = False End If If InStr(str, "Option ") > 0 Then doline = False End If If InStr(str, "Function ") > 0 Then doline = False End If If (InStr(str, "Sub ") > 0) Then If InStr(component.CodeModule.Lines(i + 1, 1), "On Error GoTo error") <> 0 Then GoTo skipsub End If str2a = component.CodeModule.Name index = InStr(str, "Sub ") ' sub str = Right(str, Len(str) - index - 3) ' sub ' index = InStr(str, "Function ") ' function ' str = Right(str, Len(str) - index - 8) 'function index = InStr(str, "(") str = Left(str, index - 1) varReturn = SysCmd(acSysCmdSetStatus, "Editing: " & str2a & " : " & str) DoEvents If (str = "CleanVBA_Click") Then MsgBox "skipping self" GoTo selfie End If If str = "globalerror" Then MsgBox "skipping globalerror" GoTo skipsub End If component.CodeModule.InsertLines i + 1, "On Error GoTo error" i = i + 1 linekill = linekill + 1 component.CodeModule.InsertLines i + 1, "error:" i = i + 1 linekill = linekill + 1 component.CodeModule.InsertLines i + 1, "Call globalerror(Me.Form.Name & """ & "-" & str & """, Err.number, Err.description, Err.source)" i = i + 1 linekill = linekill + 1 component.CodeModule.InsertLines i + 1, " " i = i + 1 linekill = linekill + 1 If (str = "MashVBA_Click") Then MsgBox "skipping self" MsgBox component.CodeModule.Name & " " & str GoTo selfie End If Else If skipline Then If doline Then skipline = False End If doline = False End If If doline Then linenumber = linenumber + 10 numstring = Split(Trim(str), " ") If Len(numstring(0)) >= 2 Then If IsNumeric(numstring(0)) Then str = Replace(str, numstring(0), "") End If End If component.CodeModule.ReplaceLine i, linenumber & " " & str End If End If skipsub: Next i selfie: Next varReturn = SysCmd(acSysCmdSetStatus, " ") MsgBox "Finished" End Sub