为什么MS Excel在Worksheet_Change Sub过程中崩溃并关闭?

der*_*rek 38 excel vba

当我在Excel工作表上运行VBA代码时,我遇到了Excel崩溃的问题.
我正在尝试在工作表更改中添加以下公式:

Private Sub Worksheet_Change(ByVal Target As Range)
   Worksheets("testpage").Range("A1:A8").Formula = "=B1+C1"
End Sub
Run Code Online (Sandbox Code Playgroud)

运行此代码时,我收到一条消息" excel遇到问题并需要关闭 "并且excel关闭.

在此输入图像描述

如果我在Worksheet_Activate()过程中运行代码,它工作正常,不会崩溃

Private Sub Worksheet_Activate()
   Worksheets("testpage").Range("A1:A8").Formula = "=B1+C1"
End Sub
Run Code Online (Sandbox Code Playgroud)

但我真的需要它在Worksheet_Change()程序中工作.

有没有人在使用此Worksheet_Change()事件时遇到过类似的崩溃,有人能指出正确的方向来解决这个问题吗?

Sid*_*out 70

注意:我现在经常将人们引用到这个链接所以我会把它作为一站式帖子Worksheet_Change.每当我有时间的时候,我会为此添加新的内容,这样人们就可以从中受益.


我总是在使用时推荐这个 Worksheet_Change

  1. 您不需要工作表名称.据了解,代码将在当前工作表上运行,除非您尝试使用另一个工作表作为参考."testpage"是活动表名称还是不同的表?

  2. 每当你处理Worksheet_Change事件时.Off如果要将数据写入单元格,请务必切换事件.这是必需的,以便代码不会进入可能的无限循环

  3. 无论何时关闭事件,使用错误处理如果出现错误,代码将不会在下次运行.

试试这个

Private Sub Worksheet_Change(ByVal Target As Range)
    On Error GoTo Whoa

    Application.EnableEvents = False

    Range("A1:A8").Formula = "=B1+C1"

Letscontinue:
    Application.EnableEvents = True
    Exit Sub
Whoa:
    MsgBox Err.Description
    Resume Letscontinue
End Sub
Run Code Online (Sandbox Code Playgroud)

使用此活动时您可能想知道的其他几件事情.

如果要确保在更改多个单元格时代码不运行,请添加一个小检查

Private Sub Worksheet_Change(ByVal Target As Range)
    '~~> For Excel 2003
    If Target.Cells.Count > 1 Then Exit Sub

    '
    '~~> Rest of code
    '
End Sub
Run Code Online (Sandbox Code Playgroud)

CountLarge是在Excel 2007之后引入的,因为Target.Cells.Count返回的Integer值在Excel 2007中出错,因为行/列增加了.Target.Cells.CountLarge返回一个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
Run Code Online (Sandbox Code Playgroud)

要使用已更改的所有单元格,请使用此代码

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
Run Code Online (Sandbox Code Playgroud)

要检测特定单元格中的更改,请使用Intersect.例如,如果Cell中发生更改A1,则会触发以下代码

Private Sub Worksheet_Change(ByVal Target As Range)
    If Not Intersect(Target, Range("A1")) Is Nothing Then
        MsgBox "Cell A1 was changed"
        '~~> Your code here
    End If
End Sub
Run Code Online (Sandbox Code Playgroud)

要检测特定范围集中的更改,请Intersect再次使用.例如,如果更改发生在范围内A1:A10,则会触发以下代码

Private Sub Worksheet_Change(ByVal Target As Range)
    If Not Intersect(Target, Range("A1:A10")) Is Nothing Then
        MsgBox "Cell in A1:A10 range was changed"
        '~~> Your code here
    End If
End Sub
Run Code Online (Sandbox Code Playgroud)

  • +1.另一个好的做法是通过以下方式进一步限制其变化触发代码的区域:`如果不相交(目标,范围("D1:D8"))则Nothing Then` ...`End If`.在此示例中,只有在此范围内的单元格发生更改时,才会运行代码. (11认同)

ste*_*nci 13

Excel崩溃了,而不是VBA功能.
事件未被禁用,并且调用堆栈由无限循环的OnChange事件填充.
一个有助于发现此类错误的建议:在事件的第一行设置断点,然后按F8逐步执行.