Table of Contents

5.4.2.20 RaiseEvent Statement

Note

This section describes the implementation of MS-VBAL §5.4.2.20 RaiseEvent Statement.

Syntax

AST node Instruction kind Notes
KeywordStatementNode (Token: RaiseEvent) Simple No dedicated node type; see RD-VBAL §3.4.2 Simple Statements. The first input is the event's name, a SimpleNameExpressionNode that is not evaluated; the rest are the event arguments.

Static Semantics

StatementStaticSemanticsEvaluator checks that:

  • the event is one the enclosing class module declares (RD-VBAL §5.2.4.3), reported as VBC09322 otherwise. A standard module declares no events, so a RaiseEvent written in one names none;
  • the arguments are compatible with the event's parameter list, reported as VBC09323: there are as many as it requires and no more than it has, and a ByVal argument can be Let-coerced to a parameter that is neither a class nor Object.

The event name is not a variable and is never resolved as one: it is not an undefined name under Option Explicit. Each argument is an expression like any other, and is evaluated by the expression rules.

The grammar of the statement is event-argument = expression: an argument cannot be written with ByVal. The keyword is valid only in the argument list of an external procedure's invocation (RD-VBAL §5.6.13.1), which a RaiseEvent never is, so it is a syntax error (VBC00001) at the parser, and not a compile error. The tree keeps it all the same, as a ByValArgumentExpressionNode.

Compatibility follows the static rules for each mapped parameter of procedure invocation (RD-VBAL §5.3.1.11):

Parameter Takes
ByVal, of a type that is neither a class nor Object An argument that can be Let-coerced to its type.
ByVal, a specific class or Object An object of a specific class or Object, or a Variant.
ByRef, of a type that is not a class, Object or Variant A variable of exactly its declared type.
ByRef, a specific class or Object An object of a specific class or Object.
ByRef, Variant An argument of any type.
Note

Interpretation. The static text asks for an exact type match of a ByRef parameter without saying what the argument is. The runtime semantics of the same section is that an argument that is a value (a literal, an operator's result) is Let-assigned to a new local variable, and only one that is a variable is referred to. The exact type is therefore required of a variable: RaiseEvent Bump(5) is valid for ByRef Count As Long, and RaiseEvent Bump(anInteger) is not. A member access that names a field is a variable too, and is taken for a value for now: it is not checked.

Runtime Semantics

RaiseEvent invokes the procedures that handle the event of the object whose code it is written in, which is Me. Which procedures those are is what the object's WithEvents variables' assignments have attached (RD-VBAL §5.4.3.9): the handlers of each variable that currently holds the object, named VariableName_EventName (RD-VBAL §5.3.1.8).

  • The handlers run in the order their variables were assigned. Assigning a WithEvents variable again moves it to the end of that order, so that the variable assigned most recently is the last to handle an event raised afterwards.
  • The arguments are evaluated once, whatever the number of handlers, and passed positionally with the rules of procedure invocation (RD-VBAL §5.3.1.11). A ByRef event parameter whose argument is a variable is aliased to it, so what one handler leaves in it is what the next handler starts with, and what the raiser finds in the variable afterwards.
  • An event nothing handles, and a source nothing is attached to, is not an error: RaiseEvent does nothing.
  • An error a handler leaves unhandled stops the invocations, and is the error of the RaiseEvent statement.

A ByRef parameter whose argument is not a variable (RaiseEvent Bump(5)) has no variable to leave a value in, so the raiser cannot see what a handler did to it. The handlers can: it is given a location of its own for the duration of the statement, so that what one handler leaves in the parameter is what the next starts with. The location is freed when the statement ends, and the next RaiseEvent starts from its argument again.


⏮️ RD-VBAL §5.4.2.19 Exit Property Statement | ⏭️ RD-VBAL §5.4.2.21 With Statement