44

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()ことはありますか?また、この問題を修正するために正しい方向を示すことはできますか?

4

3 に答える 3

81

使用するときにこれをお勧めしますWorksheet_Change

  1. シート名は必要ありません。シートコードモジュールでは、修飾されていない範囲参照はそのシートを参照します。Meとはいえ、修飾子を使用する方が明確です。別のシートを使用しようとしている場合は、そのシートで範囲参照を修飾します。

  2. イベントを操作しているときはいつでも、セルにデータを書き込んでいる場合はWorksheet_Change常にイベントを切り替えてください。Offこれは、コードがChangeイベントを再トリガーせず、無限のループに陥らないようにするために必要です。

  3. イベントをオフにするときはいつでも、エラー処理を使用してオンに戻します。そうしないと、エラーが発生した場合、コードは次回実行されません。

これを試して

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

The CountLarge was introduced in Excel 2007 onward because Target.Cells.Count returns an Long value which can error out in Excel 2007 becuase of increased total cells count.

Private Sub Worksheet_Change(ByVal Target As Range)
    '~~> For Excel 2007
    If Target.Cells.CountLarge > 1 Then Exit Sub
    '
    '~~> Rest of code
    '
End Sub

To work with all the cells that were changed use this code

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

To detect change in a particular cell, use Intersect. For example, if a change happens in Cell A1, then the below code will fire

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

To detect change in a particular set of range, use Intersect again. For example, if a change happens in range A1:A10, then the below code will fire

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
于 2012-12-13T14:11:54.980 に答える
14

VBA関数ではなく、Excelがクラッシュしていました。
イベントは無効にならず、コールスタックはOnChangeイベントの無限ループで埋められました。
このタイプのエラーを見つけるのに役立つちょっとしたアドバイス:イベントの最初の行にブレークポイントを設定し、F8キーを押して段階的に実行します。

于 2013-01-08T06:28:43.710 に答える
0

また、この解決策は良いです:

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
于 2018-08-17T17:52:54.023 に答える