サーチ…


構文

  • ソースモジュール[Public] Event [identifier]([argument_list])

  • ハンドラモジュールDim|Private|Public WithEvents [identifier] As [type]

備考

  • イベントはPublicのみ可能です。クラスモジュールのメンバー(イベントを含む)は、デフォルトでは暗黙的にPublicので、修飾子はオプションです。

  • WithEvents変数は、 PrivateでもPublicでもWithEventsませんが、 Friendはありません。 WithEventsは変数を宣言するキーワードではなく、変数宣言構文の修飾語キーワードの部分であるため、修飾子は必須です。したがって、アクセス修飾子が存在しない場合は、 Dimキーワードを使用する必要があります。

ソースとハンドラ

イベントとは何ですか?

VBAはイベントドリブンです。ホストアプリケーションまたはホスト文書によって生成されたイベントに応答してVBAコードが実行されます。イベントの理解はVBAを理解する上で基本的です。

APIは多くの場合、さまざまな状態に対応していくつかのイベントを発生させるオブジェクトを公開します。たとえば、 Excel.Applicationオブジェクトは、新しいワークブックが作成、オープン、アクティブ化、またはクローズされるたびにイベントを発生させます。またはワークシートが計算されるたびに。またはファイルが保存される直前。または直後。フォーム上のボタンは、ユーザーがクリックするとClickイベントを発生させ、ユーザーフォーム自体はアクティブ化された直後のイベントと閉じられる直前のイベントを発生させます。

APIの観点からは、イベントは拡張ポイントです。クライアントコードでは、これらのイベントを処理するコードを実装しこれらのイベントが発生するたびにカスタムコードを実行することができます。つまり、ワークシートの選択内容が変更されるたびにカスタムコードを自動的に実行できます。 - ワークシート上で選択が変更されたときに発生するイベントを処理します。

イベントを公開するオブジェクトはイベントソースです。イベントを処理するメソッドはハンドラです。


ハンドラー

VBAドキュメントモジュール( ThisDocumentThisWorkbookSheet1など)とUserFormモジュールは、いくつかのイベントを公​​開する特別なインターフェイスを実装するクラスモジュールです。これらのインターフェイスは、コードペインの上部にある左側のドロップダウンで参照できます。

ThisWorkbookモジュールはWorkbookイベントを実装します。

右側のドロップダウンでは、左側のドロップダウンで選択されたインターフェイスのメンバーが一覧表示されます。

ワークシート・モジュールは、ワークシート・イベントを処理できます。

アイテムが右側のリストで選択されると、VBEは自動的にイベントハンドラスタブを生成します。ハンドラが存在する場合は、そこをナビゲートします。

ModuleスコープのWithEvents変数は、任意のモジュールで定義できます。

Private WithEvents Foo As Workbook
Private WithEvents Bar As Worksheet

それぞれのWithEvents宣言は、左側のドロップダウンから選択できるようになります。右側のドロップダウンでイベントが選択されると、VBEはWithEventsオブジェクトの名前とイベント名をアンダースコアで結合したイベントハンドラスタブを生成します。

Private WithEvents Foo As Workbook
Private WithEvents Bar As Worksheet

Private Sub Foo_Open()

End Sub

Private Sub Bar_SelectionChange(ByVal Target As Range)

End Sub

少なくとも1つのイベントを公開する型だけがWithEventsで使用でき、 WithEvents宣言にはNewキーワードでその場で参照を割り当てることができません。このコードは違法です:

Private WithEvents Foo As New Workbook 'illegal

オブジェクト参照はSet明示的にSet必要があります。クラスモジュールでは、 Class_Initializeハンドラの中で、そのクラスのインスタンスが存在する限り、そのオブジェクトのイベントをクラスが処理するため、そのための良い場所がよくあります。


ソース

任意のクラスモジュール(またはドキュメントモジュール、またはユーザーフォーム)は、イベントソースになります。 Eventキーワードを使用して、 Eventシグネチャをモジュールの宣言セクションで定義します。

Public Event SomethingHappened(ByVal something As String)

イベントの署名によって、イベントの発生方法と、イベントハンドラの外観が決まります。

イベントは、定義されているクラス内でのみ発生させることができます。クライアントコードではイベントを処理できます。イベントはRaiseEventキーワードで生成されます。イベントの引数はその時点で提供されます:

Public Sub DoSomething()
    RaiseEvent SomethingHappened("hello")
End Sub

SomethingHappenedイベントを処理するコードがなければ、 DoSomethingプロシージャを実行するとイベントは発生しますが、何も起こりません。イベントソースがSomethingという名前のクラスの上記のコードであると仮定すると、 ThisWorkbookこのコードは、 test.DoSomethingが呼び出されるたびに "hello"というメッセージボックスを表示します。

Private WithEvents test As Something

Private Sub Workbook_Open()
    Set test = New Something
    test.DoSomething
End Sub

Private Sub test_SomethingHappened(ByVal bar As String)
'this procedure runs whenever 'test' raises the 'SomethingHappened' event
    MsgBox bar
End Sub

データをイベントソースに戻す

参照渡しのパラメータの使用

イベントは、呼び出し元に返されることを意図したByRefパラメータを定義することができます。

Public Event BeforeSomething(ByRef cancel As Boolean)
Public Event AfterSomething()

Public Sub DoSomething()
    Dim cancel As Boolean
    RaiseEvent BeforeSomething(cancel)
    If cancel Then Exit Sub

    'todo: actually do something

    RaiseEvent AfterSomething
End Sub

場合BeforeSomethingイベントは、その設定ハンドラ持っcancelにパラメータをTrue 、実行はハンドラから戻ったときに、 cancelとなりTrueAfterSomething提起されることはありません。

Private WithEvents foo As Something

Private Sub foo_BeforeSomething(ByRef cancel As Boolean)
    cancel = MsgBox("Cancel?", vbYesNo) = vbYes
End Sub

Private Sub foo_AfterSomething()
    MsgBox "Didn't cancel!"
End Sub

foo.DoSomethingが実行されるとき、 fooオブジェクト参照がどこかに割り当てられていると仮定すると、メッセージボックスはキャンセルするかどうかをfoo.DoSomethingメッセージを表示し、 Noが選択されたときだけ2番目のメッセージボックスに "did not cancel"というメッセージが表示されます。


可変オブジェクトの使用

また、可変オブジェクトByValコピーを渡し、ハンドラにそのオブジェクトのプロパティを変更させることもできます。呼び出し元は変更されたプロパティ値を読み取り、それに応じて動作することができます。

'class module ReturnBoolean
Option Explicit
Private encapsulated As Boolean

Public Property Get ReturnValue() As Boolean
'Attribute ReturnValue.VB_UserMemId = 0
    ReturnValue = encapsulated
End Property

Public Property Let ReturnValue(ByVal value As Boolean)
    encapsulated = value
End Property

Variant型と組み合わせると、これは呼び出し元に値を返すためにむしろ明らかでない方法を作成するために使用できます:

Public Event SomeEvent(ByVal foo As Variant)

Public Sub DoSomething()
    Dim result As ReturnBoolean
    result = New ReturnBoolean

    RaiseEvent SomeEvent(result)

    If result Then ' If result.ReturnValue Then
        'handler changed the value to True
    Else
        'handler didn't modify the value
    End If
End Sub

ハンドラは次のようになります。

Private Sub source_SomeEvent(ByVal foo As Variant) 'foo is actually a ReturnBoolean object
    foo = True 'True is actually assigned to foo.ReturnValue, the class' default member
End Sub


Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow