Excel vba:打开工作簿时分配全局变量;如果发生错误,将被擦除

时间:2018-09-06 13:57:52

标签: excel vba excel-vba

我有一个工作簿,其中声明了全局变量:

Public var1 As Long
Public var2 As Long
Public var3 As Long
...
Public varN As Long

我还具有一个工作簿打开子项,该子项在打开工作簿时将值分配给全局变量:

Private Sub Workbook_open()
    Application.Calculation = xlCalculationAutomatic

    Call calculateRows
    Call assignVariables


    ThisWorkbook.Worksheets("Filling").Protect "somepass", UserInterfaceOnly:=True
    MsgBox ("DONE Workbook_open")
End Sub

工作正常。但是,我还有一个工作表选择更改子项:

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
...
End Sub

和工作表更改子:

Private Sub Worksheet_Change(ByVal Target As Range)
...
End Sub

都包含可能会导致错误的代码。无论发生什么错误,它总是擦除我的全局变量的值,这只会导致进一步的错误,并且基本上会完全关闭工作簿,因为所有工作表选择/更改子项都大量使用这些全局变量。

我应该怎么做才能确保它不会发生?使用“出现错误时转到”操作是否足够?为什么仍然要删除全局变量?

1 个答案:

答案 0 :(得分:5)

如注释中所述,单击End暂停执行将始终重置全局状态。哎呀,没有必要出错。点击“停止”按钮将具有相同的效果。

至少应该在输入过程中进行错误处理(例如,工作表事件处理程序是不错的选择,因为它们是Excel可以与您的VBA代码进行交互的入口点)。

如果您甚至希望使用错误处理程序也能找到有问题的错误,此模式可以帮助您:

Public Sub Example()
On Error GoTo ErrHandler

'Some code that might error

ExitProcedure:
On Error Resume Next
'Clean up
Exit Sub

ErrorHandler:

MsgBox "Oops"
Resume ExitProcedure
Resume 'for debugging

End Sub

请注意错误处理程序末尾无法访问的Resume。由于Resume ExitProcedure将始终首先执行,因此无法访问。因此,当您收到消息框时,可以使用ctrl+break进入代码,然后转到Resume ExitProcedure。然后,您可以将黄色箭头拖动到无法访问的Resume上,按F8键一次,然后将您带回到导致错误的行。

请注意,它仅适用于过程。如果错误被冒泡,它将使您返回到错误冒泡之前被调用的过程,而不是过程中的行。

或者,如果您不喜欢所有额外的工作,则可以考虑购买诸如vbWatchDog 之类的加载项,该加载项可大大帮助错误处理。

即使如此,那些方法也无法解决根本问题-全局状态非常脆弱,可以被破坏...您可以使用“停止”按钮甚至End。您希望避免使用尽可能多的global并将它们范围化或将它们填充在类实例中,以便当您重复代码块时,它可以在该范围内重建状态。在全局状态下拥有的东西越少越好。