我正在升级一个中等复杂的Excel电子表格,该电子表格可以验证用户输入,否则该电子表格很容易损坏。此验证的一部分涉及确保不删除某些具有电子表格运行所需数据的单元格。为此,我有子模块
Private Sub Worksheet_Change(ByVal target As Range)
Dim errMsg As String
On Error GoTo turnAutomationOn:
Call turnOffExcelFeatures
Worksheets(WORKSHEET_NAME).UsedRange 'gets rid of ghost cells
' check critical data and forumlae have not been disturbed or deleted
If errMsg <> "" Then
Call outputErrorMessage(errMsg) ' definitely works
Call undoLastAction()
Exit Sub
End If
' process change made
turnAutomationOn:
Call turnOnExcelFeatures
End Sub
其中函数turnOffExcelFeatures()
,turnOnExcelFeatures()
和undoLastAction()
被定义为
' Increase performance by turning of certian Excel features
' WARNING: Make sure to call turnOnExcelFeatures() before calling function/sub ends!
Public Function turnOffExcelFeatures()
Application.ScreenUpdating = False
Application.DisplayStatusBar = False
Application.Calculation = xlCalculationManual
Application.EnableEvents = False
ActiveSheet.DisplayPageBreaks = False
End Function
' Turns Excel features back on that are turned off by turnOffExcelFeatures()
Public Function turnOnExcelFeatures()
Application.ScreenUpdating = True
Application.DisplayStatusBar = True
Application.Calculation = xlCalculationAutomatic
ActiveSheet.DisplayPageBreaks = True
Application.EnableEvents = True
End Function
Public Function undoLastAction()
On Error Resume Next ' in case Application.Undo fails due to empty undo stack
Dim enableEventsStatus As Boolean
With Application
enableEventsStatus = .EnableEvents
.EnableEvents = False
.Undo
.EnableEvents = enableEventsStatus
End With
End Function
通常来说,此代码可以正常工作。但是,在插入行时,undoLastAction()
函数被第二次调用。这使脚本停止在.Undo
行,Excel在该行输出运行时错误'1004'。我猜这是因为Worksheet_change()
子程序的第一次运行会清除撤消堆栈。奇怪的是,这仅在插入新行时发生;更改单元格值,插入列,删除列和删除行没有相同的问题。
尝试断点后,我可以确认Worksheet_change()
子在插入新行时仅仅运行了多次。
考虑到我使用EnableEvents
变量的设置,我不明白为什么插入新行会导致工作表更改事件发生。我尝试通过Ctrl + F搜索EnableEvents
,但只能在turnOffExcelFeatures()
和turnOnExcelFeatures()
函数中找到它。此外,On Error Resume Next
中的undoLastAction()
似乎没有任何作用。
有什么想法吗?