我有一个声明了全局变量的工作簿:
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
两者都包含可能导致错误的代码。无论发生什么错误,它总是会删除我的全局变量的值,这只会导致进一步的错误,并且基本上完全关闭工作簿,因为所有工作表选择/更改子都大量使用这些全局变量。
我应该怎么做才能确保它不会发生?使用“On Error GoTo”操作就足够了吗?为什么全局变量无论如何都会被删除?
最佳答案
如评论中所述,点击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 并将它们限定为范围或将它们填充到类实例中,以便当您重复代码块时,它可以在该范围内重建状态。你在全局状态下拥有的东西越少越好。
关于vba - Excel vba : global variables are assigned when workbook is opened; get erased if an error occurs,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52205786/