提问人:derek 提问时间:12/13/2012 最后编辑:Andrei Konstantinovderek 更新时间:12/30/2022 访问量:40058
为什么 MS Excel 在 Sub 过程中崩溃和关闭Worksheet_Change?
Why MS Excel crashes and closes during Worksheet_Change Sub procedure?
问:
当我在 Excel 工作表上运行 VBA 代码时,我遇到了 Excel 崩溃的问题。
我正在尝试在工作表更改上添加以下公式:
Private Sub Worksheet_Change(ByVal Target As Range)
Worksheets("testpage").Range("A1:A8").Formula = "=B1+C1"
End Sub
运行此代码时,我收到一条消息,说“excel 遇到了问题,需要关闭”,excel 关闭。
如果我在过程中运行代码,它工作正常并且不会崩溃Worksheet_Activate()
Private Sub Worksheet_Activate()
Worksheets("testpage").Range("A1:A8").Formula = "=B1+C1"
End Sub
但我真的需要它在手术中工作。Worksheet_Change()
有没有人在使用该事件时遇到过类似的崩溃,任何人都可以指出正确的方向来解决这个问题吗?Worksheet_Change()
答:
我建议在使用时这样做Worksheet_Change
您不需要工作表名称。在工作表代码模块中,非限定范围参照引用该工作表。也就是说,使用限定符更清楚。如果尝试使用其他工作表,请使用该工作表限定范围参考。
Me
每当使用事件时,如果要将数据写入任何单元格,请始终切换事件。这是必需的,以便代码不会重新触发 Change 事件,并进入可能的无限循环
Worksheet_Change
Off
每当关闭事件时,请使用错误处理将其重新打开,否则,如果出现错误,代码下次将不会运行。
试试这个
Private Sub Worksheet_Change(ByVal Target As Range)
On Error GoTo Whoa
Application.EnableEvents = False
Me.Range("A1:A8").Formula = "=B1+C1"
Letscontinue:
Application.EnableEvents = True
Exit Sub
Whoa:
MsgBox Err.Description
Resume Letscontinue
End Sub
在处理此事件时,您可能想知道的其他一些事情。
如果要确保代码在更改多个单元格时不会运行,请添加一个小检查
Private Sub Worksheet_Change(ByVal Target As Range)
'~~> For Excel 2003
If Target.Cells.Count > 1 Then Exit Sub
'
'~~> Rest of code
'
End Sub
这是在 Excel 2007 中引入的,因为返回一个值,由于单元格总数增加,该值可能会在 Excel 2007 中出错。CountLarge
Target.Cells.Count
Long
Private Sub Worksheet_Change(ByVal Target As Range)
'~~> For Excel 2007
If Target.Cells.CountLarge > 1 Then Exit Sub
'
'~~> Rest of code
'
End Sub
若要使用所有已更改的单元格,请使用此代码
Private Sub Worksheet_Change(ByVal Target As Range)
Dim aCell As Range
For Each aCell In Target.Cells
With aCell
'~~> Do Something
End With
Next
End Sub
要检测特定单元格的变化,请使用 。例如,如果在 Cell 中发生更改,则将触发以下代码Intersect
A1
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Me.Range("A1")) Is Nothing Then
MsgBox "Cell A1 was changed"
'~~> Your code here
End If
End Sub
若要检测特定范围集的变化,请再次使用。例如,如果 范围 发生更改,则将触发以下代码Intersect
A1:A10
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Me.Range("A1:A10")) Is Nothing Then
MsgBox "one or more Cells in A1:A10 range was changed"
'~~> Your code here
End If
End Sub
注意:如果您之前收到错误并且进行了上述更改,并且如果您的代码仍然不起作用,则事件可能尚未重置。在 中,键入并按 键。这会将其重置为 。如果您没有看到 ,请按快捷键 + 启动 .Immediate Window
Application.EnableEvents = True
ENTERTrue
Immediate Window
CtlGImmediate Window
评论
If Not Intersect(Target, Range("D1:D8")) Is Nothing Then
End If
Range()
Target.Parent.Range()
Range()
Range
Excel 崩溃了,而不是 VBA 函数。
事件未被禁用,调用堆栈由无限循环的 OnChange 事件填充。
有助于查找此类错误的一些建议:在事件的第一行设置断点,然后按 F8 逐步执行它。
这个解决方案也很好:
Option Explicit
Private Busy As Boolean
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Busy Then
Busy = True
Range("A1:A8").Formula = "=B1+C1"
Busy = False
End If
End Sub
评论