Buscar..


Mejores prácticas

Un UserForm es un módulo de clase con un diseñador y una instancia predeterminada . Se puede acceder al diseñador presionando Shift + F7 mientras se ve el código subyacente , y se puede acceder al código subyacente presionando la tecla F7 mientras se ve el diseñador .


Trabaja con una nueva instancia cada vez.

Al ser un módulo de clase , un formulario es, por lo tanto, un modelo para un objeto . Debido a que un formulario puede contener el estado y los datos, es una mejor práctica trabajar con una nueva instancia de la clase, en lugar de con la predeterminada / global:

With New UserForm1
    .Show vbModal
    If Not .IsCancelled Then
        '...
    End If
End With

En lugar de:

UserForm1.Show vbModal
If Not UserForm1.IsCancelled Then
    '...
End If

Trabajar con la instancia predeterminada puede provocar errores sutiles cuando el formulario se cierra con el botón rojo "X" y / o cuando se utiliza Unload Me en el código subyacente.


Implementar la lógica en otro lugar.

Un formulario no debe ocuparse de nada más que de la presentación : un botón El controlador de Click que se conecta a una base de datos y ejecuta una consulta parametrizada basada en la entrada del usuario, está haciendo muchas cosas .

En su lugar, implemente la lógica aplicativa en el código que es responsable de mostrar el formulario, o incluso mejor, en módulos y procedimientos dedicados.

Escriba el código de tal manera que UserForm solo sea responsable de saber cómo mostrar y recopilar datos: de dónde provienen los datos, o qué sucede con los datos después, no es motivo de preocupación.


La persona que llama no debe ser molestada con los controles.

Cree un modelo bien definido para el formulario con el que trabajar, ya sea en su propio módulo de clase dedicado o encapsulado dentro del propio código subyacente del formulario: exponga el modelo con procedimientos de Property Get y haga que el código del cliente trabaje con estos: esto hace que la forma una abstracción sobre los controles y sus detalles esenciales, exponiendo solo los datos relevantes al código del cliente.

Esto significa código que se ve así:

With New UserForm1
    .Show vbModal
    If Not .IsCancelled Then
        MsgBox .Message, vbInformation
    End If
End With

En lugar de esto:

With New UserForm1
    .Show vbModal
    If Not .IsCancelled Then
        MsgBox .txtMessage.Text, vbInformation
    End If
End With

Manejar el evento QueryClose.

Por lo general, los formularios tienen un botón Cerrar , y las indicaciones / diálogos tienen los botones Aceptar y Cancelar ; el usuario puede cerrar el formulario utilizando el cuadro de control del formulario (el botón rojo "X"), que destruye la instancia del formulario de forma predeterminada (otra buena razón para trabajar con una nueva instancia cada vez ).

With New UserForm1
    .Show vbModal
    If Not .IsCancelled Then 'if QueryClose isn't handled, this can raise a runtime error.
        '...
    End With
End With

La forma más sencilla de controlar el evento QueryClose es establecer el parámetro Cancel en True y luego ocultar el formulario en lugar de cerrarlo :

Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
    Cancel = True
    Me.Hide
End Sub

De esa manera, el botón "X" nunca destruirá la instancia, y la persona que llama puede acceder de forma segura a todos los miembros públicos.


Ocultar, no cerrar.

El código que crea un objeto debe ser responsable de destruirlo: no es responsabilidad del formulario descargarse y terminarse.

Evite usar Unload Me en el código subyacente de un formulario. Call Me.Hide en Me.Hide lugar, para que el código de llamada aún pueda usar el objeto que creó cuando se cierra el formulario.


Nombre las cosas.

Use la ventana de herramientas de propiedades ( F4 ) para nombrar cuidadosamente cada control en un formulario. El nombre de un control se usa en el código subyacente, por lo que, a menos que esté usando una herramienta de refactorización que pueda manejar esto, cambiar el nombre de un control romperá el código , por lo que es mucho más fácil hacer las cosas bien en primer lugar, que intentarlo para descifrar exactamente cuál de los 20 cuadros de texto significa TextBox12 .

Tradicionalmente, los controles de UserForm se nombran con prefijos de estilo húngaro:

  • lblUserName para un control Label que indica un nombre de usuario.
  • txtUserName para un control TextBox donde el usuario puede ingresar un nombre de usuario.
  • cboUserName para un control ComboBox donde el usuario puede ingresar o elegir un nombre de usuario.
  • lstUserName para un control ListBox donde el usuario puede elegir un nombre de usuario.
  • btnOk o cmdOk para un control de Button etiqueta "Ok".

El problema es que cuando, por ejemplo, la IU se rediseña y un ComboBox cambia a un ListBox , el nombre debe cambiar para reflejar el nuevo tipo de control: es mejor nombrar los controles por lo que representan, en lugar de después de su tipo de control, para desacoplarlos. Código de la interfaz de usuario tanto como sea posible.

  • UserNameLabel para una etiqueta de solo lectura que indica un nombre de usuario.
  • UserNameInput para un control donde el usuario puede ingresar o elegir un nombre de usuario.
  • OkButton para un botón de comando etiquetado "Ok".

Cualquiera que sea el estilo elegido, cualquier cosa es mejor que dejar que todos los controles tengan sus nombres predeterminados. La consistencia en el estilo de nombre también es ideal.

Manejo de consultas cerrar

El evento QueryClose se QueryClose cada vez que se cierra un formulario, ya sea a través de la acción del usuario o mediante programación. El parámetro CloseMode contiene un valor de enumeración VbQueryClose que indica cómo se cerró el formulario:

Constante Descripción Valor
vbFormControlMenu El formulario se está cerrando en respuesta a la acción del usuario. 0
vbFormCode El formulario se está cerrando en respuesta a una declaración de Unload 1
vbAppWindows Sesión de Windows está terminando 2
vbAppTaskManager El Administrador de tareas de Windows está cerrando la aplicación host 3
vbFormMDIForm No soportado en VBA 4

Para una mejor legibilidad, es mejor usar estas constantes en lugar de usar su valor directamente.


Un formulario de usuario cancelable

Dada una forma con un botón Cancelar

alguna forma de muestra

El código subyacente del formulario podría verse así:

Option Explicit
Private Type TView
    IsCancelled As Boolean
    SomeOtherSetting As Boolean
    'other properties skipped for brievety
End Type
Private this As TView

Public Property Get IsCancelled() As Boolean
    IsCancelled = this.IsCancelled
End Property

Public Property Get SomeOtherSetting() As Boolean
    SomeOtherSetting = this.SomeOtherSetting
End Property

'...more properties...

Private Sub SomeOtherSettingInput_Change()
    this.SomeOtherSetting = CBool(SomeOtherSettingInput.Value)
End Sub

Private Sub OkButton_Click()
    Me.Hide
End Sub

Private Sub CancelButton_Click()
    this.IsCancelled = True
    Me.Hide
End Sub

Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
    If CloseMode = VbQueryClose.vbFormControlMenu Then
        Cancel = True
        this.IsCancelled = True
        Me.Hide
    End If
End Sub

El código de llamada podría mostrar el formulario y saber si fue cancelado:

Public Sub DoSomething()
    With New UserForm1
        .Show vbModal
        If .IsCancelled Then Exit Sub
        If .SomeOtherSetting Then
            'setting is enabled
        Else
            'setting is disabled
        End If
    End With
End Sub

La propiedad IsCancelled devuelve True cuando se hace clic en el botón Cancelar , o cuando el usuario cierra el formulario utilizando el cuadro de control .



Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow