3

環境

私の VBA コードは、ワークブック内のワークシートを頻繁に置き換えます。したがって、コードは最終的にプロセスで削除されるため、ワークシート モジュールでコードを直接使用することはできません。

ユーザー定義クラスを使用してイベントを処理します ( Chip Pearson の withevents 記事から強く影響を受けています) 。

Public WithEvents ws As Worksheet


Private Sub ws_Activate()
    If ActiveSheet.Name = FREEBOM_SHEET_NAME Then
        Call FREEBOM_Worksheet_Activate_Handler
    End If  'ActiveSheet.Name = FREEBOM_SHEET_NAME

End Sub

Private Sub ws_Change(ByVal Target As Range)
  'MsgBox Target.Parent.Name

  If Target.Parent.Name = FREEBOM_SHEET_NAME Then
      Call FREEBOM_Worksheet_Change_Handler(Target)
  End If 'Target.Parent.Name = FREEBOM_SHEET_NAME

  If Target.Parent.Name = BOM_SHEET_NAME Then
      Call BOM_Worksheet_Change_Handler(Target)
  End If 'Target.Parent.Name = BOM_SHEET_NAME

End Sub

ワークブックが開かれると、クラスがインスタンス化されます。

Private Sub Workbook_Open()

    Dim WSObj_FreeBOM As FreeBOM_CWorkSheetEventHandler
    Dim WSObj_BOM As FreeBOM_CWorkSheetEventHandler

    If Freebom_EventCollection Is Nothing Then
        Set Freebom_EventCollection = New Collection
    End If

    Set WSObj_FreeBOM = New FreeBOM_CWorkSheetEventHandler
    Set WSObj_FreeBOM.ws = Sheets(FREEBOM_SHEET_NAME)

    Set WSObj_BOM = New FreeBOM_CWorkSheetEventHandler
    Set WSObj_BOM.ws = Sheets(BOM_SHEET_NAME)

    Freebom_EventCollection.Add Item:=WSObj_FreeBOM, Key:=Sheets(FREEBOM_SHEET_NAME).Name
    Freebom_EventCollection.Add Item:=WSObj_BOM, Key:=Sheets(BOM_SHEET_NAME).Name
End Sub

この件について読んでいるときに、オブジェクトをパブリックコレクションにリンクすると(宣言は別のモジュールにあります(通常のモジュール-ワークシートモジュールではなく、クラスモジュールではありません)):Public Freebom_EventCollection As Collection 実行が現在の初期化関数のスコープを離れます。

問題の説明

ほとんどのシナリオでは、発生する ws_change イベントは 1 つだけです。その後、コードにイベント ハンドラーがないかのようにシートが動作します。ワークシート イベントだけでなく、何も発生していません。

私は見ましたが、最初の実行後にApplication.EnableEvents常に設定されています。True

また、ビルドインPrivate Sub Worksheet_Change(ByVal Target As Range)機能を使用するとうまくいきました。

私にとっては、おそらくクラスを使用しているという事実に関連しており、最初の実行後は存続していません。しかし、その後、私は自分が間違っていることを知りません。

この件についてお時間をいただき、ご協力いただきありがとうございます。

4

1 に答える 1

1

コレクションのモジュール レベルの Public インスタンスを通常のモジュール (ワークシート モジュールでもクラス モジュールでもない) で宣言する必要があります。そこにコレクションを管理するためのコードを配置して、ワークシート モジュールのイベント ハンドラーから呼び出しを行うこともできます。シートを削除するたびに、コレクションを再初期化する必要がある場合があります。これにより、プロジェクトの再コンパイルとリセットがトリガーされ、オブジェクトが終了する可能性があります。

コレクションを標準モジュールに追加したら、ウォッチ (VBE では SHIFT-F9) を追加して、そのライフ サイクルを監視できます。その後、何が起こっているかを正確に追跡できます。

于 2013-10-24T17:08:06.613 に答える