Ir al contenido principal

macros en controles de formulario

Un lector me consulta sobre la forma de asignar distintas macros a un "control de formulario", en una hoja de cálculos. Y aquí vale aclarar, para todos aquellos que no lo sepan, que en Excel disponemos de dos tipos de controles: los ActiveX (que son idénticos a los que utilizamos en los formularios de un proyecto VBA) y los controles de formularios, que colocamos únicamente en una planilla. (cabe mencionar que los ActiveX, al margen de integrar el entorno de VBA, pueden ser también incorporados a una hoja).
las dos barras de herramientas: formularios y cuadro de controles

Sobre la segunda no hablaremos mucho, ya que son idénticos a los controles que utilizamos en los formularios de VBA, solo que aquí también tenemos la opción de incorporarlos a una planilla de cálculos, teniendo acceso a todas sus propiedades, métodos y eventos.
aquí vemos una típica scrollbar, insertada en una hoja, y con su respectiva ventana de propiedades.

Pero los controles de formulario son muchos mas precarios, en términos de programación. Al colocar un combobox, listbox, botón, etc, etc solo se nos permitirá asignarle una macro. Generalmente son usados para definirles un rango de entrada y que muestre lo que previamente escribimos en un par de celdas. No poseen ventana de propiedades y, por ejemplo, resulta imposible programar sobre sus eventos.... excepto uno, el cual veremos a continuación.

Coloquemos un cuadro de lista (listbox) en cualquier hoja. En el rango E1:E5 ingresaremos datos. Ahora damos click derecho sobre el listbox y seleccionamos "Formato de Control", apareciendo en pantalla el siguiente formulario:
nos vamos a la pestaña "Control"

1) Rango de entrada: debemos especificar en que rango de la hoja están los datos que se cargarán en el control.
2) Vincular con la celda: aquí indicamos una celda que nos devolverá el número de índice del ítem seleccionado por el usuario.
3) Tipo de selección: dejamos simple y así permitir solamente selecciones únicas.
4) Sombreado 3D: un detalle meramente estético, pero queda bien. =)

Lo completamos de la siguiente forma:

Y obtendremos este resultado:
todos los valores del rango indicado se encuentran dentro del control. pueden observar como seleccioné el cuarto elemento y en G1 (celda vinculada) obtengo la posición de ese elemento dentro de la matriz.

Y esa celda, G1, será la que me salva y así poder evacuar la duda de mi lector. Como hacemos para que se ejecuten distintas macros según el item seleccionado por el usuario? Recordemos que este tipo de controles no posee eventos y con VBA me resulta imposible determinar que elemento se seleccionó. Sí es viable asignarle solo una macro... y listo, ahí se acabó la historia.

Pero vamos por mas. Damos click derecho sobre el listbox y luego elegimos "Asignar Macro", lo que nos hará aparecer en pantalla este formulario:
yep... no tengo ninguna macro, pero podemos ver que si existe un evento que podemos aprovechar: AlCambiar (change)

Si ahora presionamos el botón "nuevo" nos iremos directamente a la ventana de código de VBA, con el Sub ya escrito para poder comenzar a codificar en el:
un solo evento... mucho mas pobre que un ActiveX común, pero nos alcanzará para asignar múltiples macros que se ejecuten de acuerdo al item seleccionado.

Cada vez que el usuario haga click sobre un elemento del listbox se producirá el evento AlCambiar, pero recordemos que también G1 cambiará su valor y es allí donde combinamos ambas situaciones, las cuales nos generan un estado ideal para este trabajo. Menos charla... y mas código:
Modificamos los datos en E1:E5 (para hacer este proyecto un poco mas interesante), ocultamos las columnas con los registros y obtenemos este listbox:
un par de comandos sencillos que servirán para trabajar

Sub Cuadrodelista4_AlCambiar()
'cada vez que el usuario haga click sobre
'nuestro control cambiará el valor de G1.
'en función del elemento seleccionado
'(del cual obtengo su nro de índice)
'aplico una macro determinada:
Select Case Range("G1").Value
    Case Is = 1
        'muestro la hora
        MsgBox "es la hora " & Format(Time, "hh:mm:ss")
    Case Is = 2
        'cierro el libro sin guardar cambios
        ActiveWorkbook.Close xlDoNotSaveChanges
    Case Is = 3
        'coloreo de rojo la celda A1
        Range("a1").Interior.ColorIndex = 3
    Case Is = 4
        'muestro la fecha del sistema
        MsgBox "la fecha del sistema es " & Format(Date, "dd/mm/yyyy")
    Case Is = 5
        'elimino la hoja3(ojo... que exista o tira error)
        Application.DisplayAlerts = False
        Sheets("Hoja3").Delete
        Application.DisplayAlerts = True
End Select
End Sub

Con un simple Select Case... analizo el valor presente en G1, el cual cambia cada vez que el usuario hace click sobre un item distinto. Y así me es posible ejecutar distintas macros sobre un mismo control, el cual carece de las propiedades, métodos y eventos de los controles que usamos en nuestros formularios de VBA.
Espero, estimado lector, que te sea de utilidad. Y muchas gracias por tus palabras.

Comentarios

Entradas populares de este blog

macros: como enviar mails desde Excel (vba)

Un gran amigo "on-line", Johan Moreno, de Colombia , me hizo llegar la inquietud de cómo enviar mails desde Excel . Si bien contaba con algunas líneas de código sobre el particular, decidí retomar mi ejemplo y adaptarlo mejor a las circunstancias. Hace unos minutos termino de remitirle un correo con la solución a Johan... desde Excel y con un archivo adjunto, mismo que transcribo a continuación para ayudar a todos con esta tarea. Veamos primero las dos formas principales de enviar mails: mediante Outlook o nuestro Web Mail ( yahoo, gmail, hotmail, etc, etc ) No soy usuario de Outlook en lo absoluto: no confío en los agujeros de seguridad que continuamente aparecen y, por otro lado, t eniendo a mi alcance una herramienta tan poderosa (y gratuita) como Gmail, la cual ahora también permite sincronizar los mensaje con la Pc para verlos offline (deben activarlo en "google labs") ... no creo que me haga usuario ni hoy ni mañana. Igualmente mas adelante daré una solució

funciones: convertir numeros a letras con excel

En realidad hace tiempo que vienen consultándome sobre esto... quizás cinco o seis años . Debe ser una de las funciones mas buscadas de Excel, por lejos: la posibilidad de escribir: 1.534,63 y que en una celda aparezca magicamente "un mil quinientos treinta y cuatro c/15/100". Aquí les dejo una solución, basada en funciones , sin utilizar macros, la cual preparé exclusivamente para este Blog. A pesar de los millones de usuarios que requieren esta herramienta, no viene incorporada en Excel, debemos armarla nosotros mismos .  Luego de la imagen irá la explicación de como llegué a lograr esto, dado que es un proceso medianamente complejo , que utiliza tres o cuatro funciones básicas y requiere de varios pasos. así quedará nuestra planilla y siempre devolverá en letras el valor que ingresemos en A1 [+/-] Ver el resto / Ocultar Desde ya aclaro: esta no es " la forma " de hacerlo, simplemente es una mas, evitando el uso de macros. Sobre esta base, comencemos: 1) El núme

sopa de letras en excel

Un lector me comenta que pudo visualizar varias sopas de letras en YouTube, realizadas con Excel. Inmediatamente me dirigí a dicho sitio y busqué información al respecto. Los ejemplos son buenos y si, efectivamente, podemos armar una muy buena "sopa de letras", salvo que (digamos) es un trabajo bastante manual, cosa que intento evitar a toda costa en mis proyectos. Obviamente que la tarea de automatización incluye Macros, lo cual me insume tiempo, pero queda mucho mejor. Vamos primero a explicar muy brevemente la forma de realizar esta juego "a la clásica", para luego pasar a un desarrollo mucho mas complejo, pero también automatizado y realista. la clásica grilla de una sopa de letras [+/-] Ver el resto / Ocultar Bien, analicemos un poco la imagen superior: 1) es una grilla de 20 filas x 20 columnas, aunque bien podríamos hacerla del tamaño que quisiéramos. 2) Cada celda tiene una letra, que fue generada  mediante la anidación de dos funciones. 3) Vean ahora la ba