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
Variables declared with WithEvents can receive events exposed by that object. The handler name follows the format "variableName_eventName", such as Target_Changed.
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
Try calling mCounter.AddOne multiple times in succession:
mCounter.AddOne mCounter.AddOne
You will see Changed = 1 and then Changed = 2 printed in the Immediate Window, verifying that the event is received twice.
Production considerations
If you use custom events in production, keep the following points in mind:
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, and do not rely too heavily on the exact order of events.
Official Information and References
To summarize, you can create custom events in VBA as well by using Event, RaiseEvent, and WithEvents together.
この記事の更新履歴
この記事は、生成AIを活用した自動レビュー・更新フローにより内容を見直し、必要な修正を反映しています。
2026年9月23日
- 変更途切れていたWithEventsの説明文と変数名の解説部分を修正しました。
- 変更途切れていたAddOne呼び出しの変更テスト部分の文章を修正しました。
- 変更不自然になっていた見出しの構成と結びの文章を修正しました。

