Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Aprende Introduction to UserForms | Interacción con el Usuario
Excel VBA para Automatización Empresarial

Introduction to UserForms

Desliza para mostrar el menú

Note
Nota

Los UserForms tienen funcionalidad limitada o ausente en Excel para Mac: el IDE de VBA en Mac carece de soporte completo para el diseño de UserForms en muchas versiones, lo que puede causar este tipo de comportamiento inexplicable.

MsgBox e InputBox cubren preguntas simples de sí/no y respuestas de una sola línea, pero agregar un cliente realmente requiere varios campos a la vez: un nombre de empresa, un contacto, una ciudad, un estado. Para eso sirve un UserForm: una pequeña ventana personalizada con sus propias etiquetas, cuadros de texto, listas desplegables y botones, creada dentro del VBE y controlada completamente por tu código.

Creación de un formulario

En el VBE, haz clic derecho en tu proyecto en el Explorador de proyectos y elige Insertar → UserForm. Aparecerá una superficie de diseño en blanco, junto con una caja de herramientas flotante con controles que puedes arrastrar sobre ella.

Figura 5.3

Etiquetas, cuadros de texto, cuadros combinados y botones

Cada control que arrastras al formulario recibe un nombre predeterminado como TextBox1 o CommandButton1: funcional, pero sin sentido cuando un formulario tiene seis o siete controles. El hábito más importante en esta sección es visible en la ventana de Propiedades: renombrar cada control inmediatamente después de agregarlo, usando un prefijo corto que identifique su tipo (txt para TextBox, cbo para ComboBox, cmd para CommandButton, opt para OptionButton, chk para CheckBox, lst para ListBox) seguido de un nombre descriptivo. txtCompanyName se entiende claramente en el código dentro de tres semanas; TextBox1 no.

Las etiquetas son los textos simples y no interactivos ("Company Name:") — el usuario puede verlos pero nunca escribir en ellos ni hacer clic. Los cuadros de texto son donde se escribe texto libremente. Los cuadros combinados presentan una lista desplegable de opciones, que es exactamente para lo que sirven cboCity y cboStatus: restringir City y Status a una lista conocida en lugar de permitir que el usuario escriba libremente "chicago", "Chicago,IL" y "CHI" para lo mismo en diferentes registros.

Flujo de creación de formularios

Escritura de código detrás del formulario

Haz doble clic en cualquier control en la superficie de diseño para ir directamente a su código: VBA crea automáticamente un procedimiento de evento llamado ControlName_EventName, y escribir código dentro de él significa que ese código se ejecuta cada vez que ocurre ese evento específico en ese control específico. El evento predeterminado de un botón es Click:

Private Sub UserForm_Initialize()
    ' runs once, automatically, when the form is first shown
    cboCity.AddItem "Chicago"
    cboCity.AddItem "Boston"
    cboCity.AddItem "Austin"
    cboCity.AddItem "Seattle"
    cboCity.AddItem "Denver"
 
    cboStatus.AddItem "Active"
    cboStatus.AddItem "Inactive"
    cboStatus.AddItem "Prospect"
End Sub
 
Private Sub cmdCancel_Click()
    Unload Me
End Sub

UserForm_Initialize es un procedimiento de evento especial que se ejecuta automáticamente en el momento en que se carga el formulario, antes de que el usuario vea algo, lo que lo convierte en el lugar adecuado para llenar los ComboBoxes con .AddItem en lugar de escribir las opciones manualmente en la ventana de Propiedades, especialmente cuando esas opciones pueden cambiar o provenir de una hoja de cálculo. Unload Me dentro de cmdCancel_Click cierra el formulario por completo; Me siempre se refiere al formulario en el que se está ejecutando el código, por lo que esta línea funciona sin modificaciones sin importar cómo renombres el formulario más adelante.

Ejemplo práctico: guardar un nuevo cliente

Este es el procedimiento detrás del botón Guardar, el que realmente escribe una nueva fila en tblCustomers:

Private Sub cmdSave_Click()
    Dim tbl As ListObject
    Dim newRow As ListRow
 
    Set tbl = ThisWorkbook.Worksheets("Customers").ListObjects("tblCustomers")
    Set newRow = tbl.ListRows.Add
 
    newRow.Range(1, 1).Value = "C" & Format(tbl.ListRows.Count + 1, "000")
    newRow.Range(1, 2).Value = txtCompanyName.Value
    newRow.Range(1, 3).Value = txtContact.Value
    newRow.Range(1, 4).Value = txtEmail.Value
    newRow.Range(1, 5).Value = cboCity.Value
    newRow.Range(1, 6).Value = cboStatus.Value
 
    MsgBox txtCompanyName.Value & " was added successfully."
    Unload Me
End Sub
Revisión línea por línea
expand arrow
  • La línea tbl = ThisWorkbook.Worksheets("Customers").ListObjects("tblCustomers") accede desde el formulario hasta el libro de trabajo: un UserForm es simplemente otro fragmento de código, por lo que todo lo relacionado con ListObjects se aplica sin cambios;
  • tbl.ListRows.Add agrega una nueva fila genuina dentro del límite de la tabla en lugar de escribir manualmente después de la última celda utilizada;
  • txtCompanyName.Value, cboCity.Value y los demás leen lo que el usuario ha escrito o seleccionado actualmente en ese control específico: .Value es común a casi todos los tipos de controles, por lo que el mismo patrón funciona tanto para TextBoxes como para ComboBoxes;
  • La línea que genera el ID de cliente es un marcador de posición simplificado para este ejercicio; la generación real de IDs debería comprobar si hay huecos o IDs reutilizados, lo cual esta línea no hace;
  • Unload Me al final cierra el formulario solo después de que la fila ha sido escrita; cerrarlo antes haría que txtCompanyName.Value y los demás valores de los controles no se pudieran leer, ya que los controles dejan de existir una vez que el formulario se descarga.
Note
Nota

La etiqueta "Company Name" del formulario es simplemente un título más amigable para la columna Customer de la tabla; el código escribe txtCompanyName.Value en esa columna sin importar el texto de la etiqueta, ya que para VBA solo importa el nombre del TextBox, no su título en pantalla.

Note
Nota

Customer ID no aparece en el formulario porque se genera automáticamente mediante código ("C0" & (tbl.ListRows.Count + 100)), en lugar de ser ingresado por el usuario; esto refleja cómo los sistemas reales asignan números automáticamente a los nuevos registros en vez de depender de que una persona elija un ID único.

Tarea

  1. Insertar un nuevo UserForm, nombrarlo frmAddCustomer y agregar tres TextBoxes (txtCompanyName, txtContact, txtEmail) y dos ComboBoxes (cboCity, cboStatus), cada uno con su respectiva etiqueta.
  2. Agregar dos CommandButtons, cmdSave y cmdCancel, y escribir los procedimientos UserForm_Initialize y cmdCancel_Click exactamente como se muestra.
  3. Escribir cmdSave_Click como se indica, luego agregar un botón temporal en otra parte del libro con el código frmAddCustomer.Show para probar la apertura del formulario.
  4. Completar el formulario para un sexto cliente ficticio y hacer clic en Save; confirmar que aparece una nueva fila en tblCustomers con los valores ingresados.
Sugerencia
expand arrow

1. Creación del formulario

  • Insertar → UserForm en el VBE, luego cambiar el nombre desde el campo (Name) en la ventana de Propiedades a frmAddCustomer — no desde el campo Caption, que solo cambia el texto de la barra de título.
  • Arrastrar un par de Label + TextBox para cada uno de Company Name, Contact y Email; un par de Label + ComboBox para City y Status.
  • Cambiar el nombre de cada control inmediatamente después de agregarlo — este es el hábito que se enfatizó en el capítulo. Los Labels no necesitan nombres aptos para código ya que nunca se referencian en el código, pero cada TextBox/ComboBox/Button sí.

2. UserForm_Initialize y cmdCancel_Click

  • Hacer doble clic en el fondo en blanco del formulario (no en un control) para acceder a UserForm_Initialize — hacer doble clic en cmdCancel te lleva directamente a cmdCancel_Click.
  • Ambos procedimientos se proporcionaron exactamente en el capítulo — escríbelos sin cambios.

3. Prueba con un botón temporal

  • Este botón no necesita estar en el formulario — colócalo en cualquier hoja mediante Desarrollador → Insertar → Botón (Control de formulario), o simplemente ejecuta una línea Sub desde el VBE en lugar de agregar un botón en la hoja.
  • frmAddCustomer.Show es todo el código necesario para mostrar el formulario.

4. Prueba de guardado completo

  • Completa todos los campos y selecciona valores en ambos desplegables antes de hacer clic en Guardar — una selección vacía en ComboBox escribiría una celda en blanco.
  • Verifica tblCustomers después para ver una nueva fila con un ID estilo C00x.
Solución
expand arrow
Private Sub UserForm_Initialize()
    ' runs once, automatically, when the form is first shown
    cboCity.AddItem "Chicago"
    cboCity.AddItem "Boston"
    cboCity.AddItem "Austin"
    cboCity.AddItem "Seattle"
    cboCity.AddItem "Denver"

    cboStatus.AddItem "Active"
    cboStatus.AddItem "Inactive"
    cboStatus.AddItem "Prospect"
End Sub

Private Sub cmdCancel_Click()
    Unload Me
End Sub

Private Sub cmdSave_Click()
    Dim tbl As ListObject
    Dim newRow As ListRow

    Set tbl = ThisWorkbook.Worksheets("Customers").ListObjects("tblCustomers")
    Set newRow = tbl.ListRows.Add

    newRow.Range(1, 1).Value = "C0" & (tbl.ListRows.Count + 100)
    newRow.Range(1, 2).Value = txtCompanyName.Value
    newRow.Range(1, 3).Value = txtContact.Value
    newRow.Range(1, 4).Value = txtEmail.Value
    newRow.Range(1, 5).Value = cboCity.Value
    newRow.Range(1, 6).Value = cboStatus.Value

    MsgBox txtCompanyName.Value & " was added successfully."
    Unload Me
End Sub

Para probarlo, ejecuta esto desde cualquier módulo estándar (no desde el propio código del UserForm):

Sub ShowAddCustomerForm()
    frmAddCustomer.Show
End Sub

Presiona F5 con el cursor dentro de ShowAddCustomerForm — el formulario debería abrirse, y al completarlo y hacer clic en Guardar, debería agregarse una nueva fila a tblCustomers.

Prueba del formulario
¿Todo estuvo claro?

¿Cómo podemos mejorarlo?

¡Gracias por tus comentarios!

Sección 5. Capítulo 2

Pregunte a AI

expand

Pregunte a AI

ChatGPT

Pregunte lo que quiera o pruebe una de las preguntas sugeridas para comenzar nuestra charla

Sección 5. Capítulo 2
some-alt