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

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

我应该怎么做才能确保它不会发生?使用"出错时转到"操作是否足够?为什么全局变量会被擦除?

如注释中所述,单击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单步执行一次,然后将带您回到导致错误的行。

请注意,它仅适用于 in 过程;如果错误被冒泡,它将返回到错误冒泡之前调用的过程,但不会返回到过程中的行。

或者,如果您不喜欢所有额外的工作,您可以考虑购买诸如 vbWatchDog 之类的插件,它对错误处理有很大帮助。

即便如此,这些也无助于解决根本问题——全球国家是脆弱的,可以被摧毁......有停止按钮,甚至End可供您使用。您希望尽可能避免使用 global 并限定它们的作用域或将它们填充到类实例中,以便在重复代码块时,它可以在该范围内重建状态。在全球状态下,您拥有的东西越少越好。

相关内容

最新更新