수색…


통사론

  • 소스 모듈 : [Public] Event [identifier]([argument_list])

  • 처리기 모듈 : Dim|Private|Public WithEvents [identifier] As [type]

비고

  • 이벤트는 Public 될 수 있습니다. 클래스 모듈 구성원 (이벤트 포함)은 암시 적으로 기본적으로 Public 이므로 변경자는 선택 사항입니다.

  • WithEvents 변수는 Private 또는 Public 일 수 있지만 Friend 아닙니다. WithEvents 는 변수를 선언하는 키워드가 아니고 변수 선언 구문의 수정 자 키워드 부분이므로 필수입니다. 따라서 액세스 한정자가 없으면 Dim 키워드를 사용해야합니다.

소스와 핸들러

이벤트 란 무엇입니까?

VBA는 이벤트 주도형입니다 . VBA 코드는 호스트 응용 프로그램이나 호스트 문서에서 발생하는 이벤트에 응답하여 실행됩니다. 이벤트를 이해하는 것이 VBA를 이해하는 기본입니다.

API는 다양한 상태에 대응하여 많은 이벤트를 발생 시키는 객체를 노출합니다. 예를 들어 Excel.Application 개체는 새 통합 문서를 만들거나 열거 나 활성화하거나 닫을 때마다 이벤트를 발생시킵니다. 또는 워크 시트가 계산 될 때마다 또는 파일이 저장되기 직전입니다. 또는 즉시. 양식의 단추는 사용자가 클릭 할 때 Click 이벤트를 발생시키고, 사용자 양식 자체는 활성화 된 직후 이벤트를 발생시키고, 닫히기 직전에 이벤트를 발생시킵니다.

API 관점에서 볼 때 이벤트는 확장 점입니다 . 클라이언트 코드 이러한 이벤트를 처리 하는 코드를 구현하고 이러한 이벤트가 발생할 때마다 사용자 정의 코드를 실행할 수 있습니다. 즉, 워크 시트에서 선택 항목이 변경 될 때마다 자동으로 사용자 정의 코드를 실행할 수 있습니다 - 워크 시트에서 선택 사항이 변경 될 때 해고되는 이벤트를 처리합니다.

이벤트를 노출하는 객체는 이벤트 소스 입니다. 이벤트를 처리하는 메소드는 핸들러 입니다.


핸들러

VBA 문서 모듈 (예 : ThisDocument , ThisWorkbook , Sheet1 등) 및 UserForm 모듈은 여러 이벤트 를 노출하는 특수 인터페이스를 구현 하는 클래스 모듈 입니다. 코드 창 상단의 왼쪽 드롭 다운에서 이러한 인터페이스를 탐색 할 수 있습니다.

ThisWorkbook 모듈은 통합 문서 이벤트를 구현합니다.

오른쪽 드롭 다운에는 왼쪽 드롭 다운에서 선택한 인터페이스의 멤버가 나열됩니다.

워크 시트 모듈은 워크 시트 이벤트를 처리 할 수 ​​있습니다.

항목이 오른쪽 목록에서 선택되면 VBE는 자동으로 이벤트 처리기 스텁을 생성하고 처리기가 있으면 탐색합니다.

모든 모듈에서 모듈 범위의 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

적어도 하나의 이벤트를 노출하는 유형 만 WithEvents 와 함께 사용할 수 있으며 WithEvents 선언에는 New 키워드로 현장에서 참조를 할당 할 수 없습니다. 이 코드는 불법입니다.

Private WithEvents Foo As New Workbook 'illegal

객체 참조는 명시 적으로 Set 이어야합니다. 클래스 모듈에서 Class_Initialize 핸들러를 사용하는 것이 좋습니다. 클래스가 인스턴스가 존재하는 동안 해당 객체의 이벤트를 처리하기 때문입니다.


출처

모든 클래스 모듈 (또는 문서 모듈 또는 사용자 양식)은 이벤트 소스가 될 수 있습니다. Event 키워드를 사용하여 모듈의 선언 섹션 에서 이벤트에 대한 서명 을 정의합니다.

Public Event SomethingHappened(ByVal something As String)

이벤트의 서명은 이벤트 발생 방법과 이벤트 핸들러의 모양을 결정합니다.

단지 그것들을 처리 할 수있는 클라이언트 코드 - 이벤트는 그들 만이 정의하고있는 클래스 내에서 제기 될 수있다. 이벤트는 RaiseEvent 키워드로 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 설정하는 핸들러가있는 경우 처리기에서 실행이 반환되면 cancelTrue 되고 AfterSomething 은 절대로 발생하지 않습니다.

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 를 선택한 경우에만 두 번째 메시지 상자에 "취소하지 않았습니다"라는 메시지가 표시됩니다.


변경 가능한 객체 사용

또한 가변 개체 인 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