Introduction to UserForms
Desliza para mostrar el menú
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.
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.
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
- 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.Addagrega 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.Valuey los demás leen lo que el usuario ha escrito o seleccionado actualmente en ese control específico:.Valuees 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.Valuey 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.
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.
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
- Insertar un nuevo UserForm, nombrarlo
frmAddCustomery agregar tres TextBoxes (txtCompanyName,txtContact,txtEmail) y dos ComboBoxes (cboCity, cboStatus), cada uno con su respectiva etiqueta. - Agregar dos CommandButtons,
cmdSaveycmdCancel, y escribir los procedimientosUserForm_InitializeycmdCancel_Clickexactamente como se muestra. - Escribir
cmdSave_Clickcomo se indica, luego agregar un botón temporal en otra parte del libro con el códigofrmAddCustomer.Showpara probar la apertura del formulario. - 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.
1. Creación del formulario
- Insertar → UserForm en el VBE, luego cambiar el nombre desde el campo
(Name)en la ventana de Propiedades afrmAddCustomer— 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 encmdCancelte lleva directamente acmdCancel_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
Subdesde el VBE en lugar de agregar un botón en la hoja. frmAddCustomer.Showes 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
tblCustomersdespués para ver una nueva fila con un ID estiloC00x.
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.
¡Gracias por tus comentarios!
Pregunte a AI
Pregunte a AI
Pregunte lo que quiera o pruebe una de las preguntas sugeridas para comenzar nuestra charla