Can you create custom events in VBA? Trying out Class, WithEvents, and RaiseEvent with minimal code

VBA・Officeカテゴリを表すパンダのイラスト VBA / Office

About this article
This article was created using an automated generation workflow utilizing generative AI. Based on the official VBA language references for Event, RaiseEvent, and WithEvents, it is structured so that you can observe the flow of a custom event being "raised and received" using minimal code.

Verification Status: 📘 Official information confirmed, Excel hardware execution not verified

VBA is not limited to receiving Worksheet Click or Change events. You can declare your own Event in a Class Module, raise it with RaiseEvent, and build a small event-driven flow received by WithEvents.

Success criteria for this exercise

When you increment the Counter value by 1, the following sequence should appear in the Immediate Window for success.

[START] AddOne
[EVENT] Changed = 1
[SUCCESS] event received

VBA event syntax can be checked in the Microsoft Learn language reference.

Get it running first: Class Module

Add a Class Module and name it Counter.

Option Explicit

Public Event Changed(ByVal NewValue As Long)

Private mValue As Long

Public Sub AddOne()
    mValue = mValue + 1
    RaiseEvent Changed(mValue)
End Sub

Event Changed is the event declaration, and RaiseEvent Changed(...) is where the event is raised.

The receiving Class Module

Add another Class Module and name it CounterObserver.

Option Explicit

Public WithEvents Target As Counter

Private Sub Target_Changed(ByVal NewValue As Long)
    Debug.Print "[EVENT] Changed = " & NewValue
End Sub

WithEventsVariables with the Target_Changed attribute can receive events exposed by that object. The handler name follows the format "variableName_eventName", such as

Wiring from a Standard Module

Option Explicit

Private mCounter As Counter
Private mObserver As CounterObserver

Public Sub RunEventDemo()
    Debug.Print "[START] AddOne"

    Set mCounter = New Counter
    Set mObserver = New CounterObserver
    Set mObserver.Target = mCounter

    mCounter.AddOne

    Debug.Print "[SUCCESS] event received"
End Sub
sequenceDiagram
    participant M as Standard Module
    participant C as Counter
    participant O as CounterObserver
    M->>C: AddOne
    C->>C: mValue = mValue + 1
    C-->>O: RaiseEvent Changed(1)
    O-->>M: Debug.Print [EVENT]

Look here

In a regular function call, the caller explicitly specifies "who to call next." With events, the Counter side simply notifies that "Changed has occurred," and the subscribed side reacts.

Understanding this pattern on a small scale helps when reading event-driven code in GUIs, COM events, asynchronous HTTP, and more.

Try changing one part

AddOneCall

mCounter.AddOne
mCounter.AddOne

Changed = 1Changed = 2 twice. Observe whether the event is received twice along with

. The key is mapping the event count to state changes.

If you use this in production

  • Events are convenient, but they can sometimes make the control flow harder to follow.

  • Make the names clear regarding who is the publisher and who is the subscriber.

  • Avoid keeping objects only as local variables and destroying them prematurely.

  • Consider whether changing state again inside an event could cause re-entrancy issues.

  • Do not swallow errors.

Do not rely too heavily on the exact order of events.

Initially, visualizing the firing order with Debug.Print makes it easier to understand.

Microsoft Learn — WithEvents

ConclusionEventRaiseEventWithEventsYou can create custom events in VBA as well by using

Document information

Article title
Can you create custom events in VBA? Trying out Class, WithEvents, and RaiseEvent with minimal code
Published
Updated
Source
https://papanda925.com/?p=15360&lang=en

License: Text and original figures for which this site holds the relevant rights are available under CC BY 4.0 , unless otherwise noted. This article may include content created or edited with generative AI. If code has a separate license notice or a linked GitHub repository license, that license takes precedence for the code. Quotations, third-party materials, images, and trademarks are excluded from this license. Usage policy

Copied title and URL