Buscar..


Sintaxis

  • Módulo de origen : [Public] Event [identifier]([argument_list])

  • Módulo de controlador : Dim|Private|Public WithEvents [identifier] As [type]

Observaciones

  • Un evento solo puede ser Public . El modificador es opcional porque los miembros del módulo de clase (incluidos los eventos) son implícitamente Public de forma predeterminada.

  • Una variable WithEvents puede ser Private o Public , pero no Friend . El modificador es obligatorio porque WithEvents no es una palabra clave que declara una variable, sino una palabra clave modificadora que forma parte de la sintaxis de declaración de la variable. Por lo tanto, la palabra clave Dim debe usarse si no está presente un modificador de acceso.

Fuentes y manejadores

¿Qué son los eventos?

VBA se basa en eventos : el código VBA se ejecuta en respuesta a los eventos generados por la aplicación host o el documento host. La comprensión de los eventos es fundamental para comprender VBA.

Las API a menudo exponen objetos que generan una serie de eventos en respuesta a varios estados. Por ejemplo, un objeto Excel.Application genera un evento cada vez que se crea, abre, activa o cierra un nuevo libro de trabajo. O cuando se calcula una hoja de cálculo. O justo antes de guardar un archivo. O inmediatamente después. Un botón en un formulario genera un evento Click cuando el usuario hace clic en él, el formulario del usuario genera un evento justo después de que se activa y otro justo antes de que se cierre.

Desde la perspectiva de la API, los eventos son puntos de extensión : el código del cliente puede elegir implementar un código que maneje estos eventos y ejecutar código personalizado cada vez que se activen: así es como puede ejecutar su código personalizado automáticamente cada vez que la selección cambia en cualquier hoja de trabajo - manejando el evento que se activa cuando la selección cambia en cualquier hoja de cálculo.

Un objeto que expone eventos es un origen de eventos . Un método que maneja un evento es un manejador .


Manipuladores

Los módulos de documentos VBA (por ejemplo, ThisDocument , ThisWorkbook , Sheet1 , etc.) y los módulos UserForm son módulos de clase que implementan interfaces especiales que exponen una serie de eventos . Puede navegar por estas interfaces en el menú desplegable del lado izquierdo en la parte superior del panel de código:

El módulo ThisWorkbook implementa eventos de Workbook.

El menú desplegable del lado derecho muestra los miembros de la interfaz seleccionada en el menú desplegable del lado izquierdo:

Los módulos de la hoja de trabajo pueden manejar los eventos de la hoja de trabajo.

El VBE genera automáticamente un apéndice de controlador de eventos cuando se selecciona un elemento en la lista del lado derecho, o navega allí si existe el controlador.

Puede definir una variable WithEvents ámbito de módulo en cualquier módulo:

Private WithEvents Foo As Workbook
Private WithEvents Bar As Worksheet

Cada declaración WithEvents está disponible para seleccionar desde el menú desplegable del lado izquierdo. Cuando se selecciona un evento en el menú desplegable del lado derecho, el VBE genera un apéndice de controlador de eventos con el nombre del objeto WithEvents y el nombre del evento, unido con un guión bajo:

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

Solo los tipos que exponen al menos un evento pueden usarse con WithEvents , y las declaraciones WithEvents no pueden ser asignadas una referencia en el momento con la palabra clave New . Este código es ilegal:

Private WithEvents Foo As New Workbook 'illegal

La referencia del objeto se debe Set explícitamente; en un módulo de clase, un buen lugar para hacerlo es a menudo en el controlador Class_Initialize , porque entonces la clase maneja los eventos de ese objeto mientras exista su instancia.


Fuentes

Cualquier módulo de clase (o módulo de documento o formulario de usuario) puede ser un origen de evento. Use la palabra clave Event para definir la firma del evento, en la sección de declaraciones del módulo:

Public Event SomethingHappened(ByVal something As String)

La firma del evento determina cómo se genera el evento y cómo se verán los controladores de eventos.

Los eventos solo se pueden generar dentro de la clase en la que están definidos, el código del cliente solo puede manejarlos . Los eventos se RaiseEvent con la palabra clave RaiseEvent ; Los argumentos del evento se proporcionan en ese punto:

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

Sin el código que maneja el evento SomethingHappened , la ejecución del procedimiento DoSomething aún DoSomething el evento, pero no ocurrirá nada. Suponiendo que el origen del evento es el código anterior en una clase llamada Something , este código en ThisWorkbook mostraría un cuadro de mensaje que dice "hola" cada vez que se realiza una test.DoSomething .

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

Pasar datos de nuevo al origen del evento

Usando parámetros pasados ​​por referencia

Un evento puede definir un parámetro ByRef destinado a ser devuelto al llamante:

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

Si el evento BeforeSomething tiene un controlador que establece su parámetro de cancel en True , entonces, cuando la ejecución vuelva del controlador, la cancel será True y AfterSomething nunca se generará.

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

Suponiendo que la referencia de objeto foo se asigna en algún lugar, cuando foo.DoSomething ejecuta, un cuadro de mensaje le foo.DoSomething si desea cancelar, y un segundo cuadro de mensaje dice "no cancelar" solo cuando se seleccionó No.


Utilizando objetos mutables

También puede pasar una copia de un objeto mutable ByVal y dejar que los controladores modifiquen las propiedades de ese objeto; la persona que llama puede leer los valores de propiedad modificados y actuar en consecuencia.

'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

Combinado con el tipo Variant , esto se puede usar para crear formas no obvias de devolver un valor a la persona que llama:

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

El manejador se vería así:

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
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow