Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Este curso va dirigido a aprender a programar en Visual Basic for Applications (VBA) para la
hoja de cálculo Microsoft Excel. El VBA es muy similar en el resto de herramientas de Microsoft
Office (Word, PowerPoint, etc), por lo que los conocimientos aquí adquiridos pueden aplicarse
en esos otros programas. Además el VBA es también muy similar al Visual Basic de verdad,
por lo que puede ser una puerta de acceso a la programación de aplicaciones (utilizando Visual
Basic) para personas sin conocimientos previos de programación.
Desde los primeros tiempos de las hojas de cálculo, con las míticas primeras versiones de
Lotus 1-2-3, existían macros (el nombre completo era macro-comandos), que servían para
automatizar tareas repetitivas. En aquellos tiempos las macros se limitaban básicamente a
simular pulsaciones del teclado el usuario, es decir, al ejecutar una macro era como si el
usuario estuviese pulsando las teclas que la macro "pulsaba", lo que a pesar de su sencillez
permitía hacer cosas interesantes. Con el tiempo las macros fueron evolucionando, pudiéndose
incluir en ellas sentencias que no se traducían en pulsaciones de teclas, aunque todo ello se
hacía introduciendo fórmulas en las celdas de la hoja de cálculo, lo que dejaba bastante que
desear.
Con la llegada de Excel 5.0, Microsoft introdujo las macros basadas en el popular Visual Basic,
creando lo que ha llamado Visual Basic for Applications, compartido por todas las aplicaciones
de Microsoft, y que añade a las mismas unas posibilidades enormes de personalización y
creación de soluciones a medida de las necesidades de cada usuario. De hecho, creo que el
nombre "macro" debería dejar de utilizarse en favor de otros conceptos más relacionados con
los lenguajes de programación (como rutinas, subrutinas y funciones), pero yo creo que se
mantiene por razones históricas.
Lo primero que tuve que decidir antes de escribir este curso sobre
programación en Excel fue hacia quién iba a ir dirigido: por un lado están todas
las personas que dominan uno o más lenguajes de programación, y con poco
esfuerzo pueden aprender los detalles específicos de Visual Basic for
Applications para Excel.
Por otro lado están todas aquellas personas que utilizan Excel simplemente
como una hoja de cálculo que hace operaciones aritméticas, que desaprovechan toda la
potencia de Excel. He decidido que este curso va a ir dirigido a estos últimos, porque creo que
es el perfil del usuario habitual de Excel, y aquellas personas que estén en el primer grupo
pueden también utilizar el curso, deteniéndose en las partes que expliquen cosas específicas
de Excel y saltándose otras como los conceptos generales de programación.
Una nota sobre versiones de Excel: la última versión de Excel es la de Office 97 (llamada Excel
97), aunque todavía existen muchos sitios en los que se utiliza la versión de Office 95 (Excel
95). Casi todo lo que vamos a hacer funciona en las dos versiones, y en los casos en los que
no sea así procuraré indicarlo.
El mejor método para aprender VBA es utilizar la opción de grabar macros de Excel: todo lo
que hagamos mientras Excel está grabando una macro se traduce en la instrucciones de VBA
necesarias para repetir nuestras acciones. Vamos a utilizar esa opción para crear nuestra
primera macro. Primero selecciona la opción "Herramientas, Grabar Macro", y escribe algo en
la celda A1. Luego selecciona la opción "Herramientas, Grabar macro..., Detener grabación"
para que Excel debe de grabar. Para ver la macro que acabamos de crear el método es distinto
en Excel 95 y Excel 97: en Excel 95, las macros se almacenan en módulos, que son como una
hoja más del libro, podemos ver una hoja llamada "Módulo1" en las pestañas que están en la
parte inferior. En Excel 97, para escribir macros se utiliza el Visual Basic Editor, y accedemos a
él mediante la opción Herramientas, Macros, Abrir Editor Visual Basic. En cualquiera de las dos
versiones veremos que Excel ha escrito algo parecido a esto:
Sub Macro1()
ActiveCell.Formula = "Mi primera macro"
Range("A2").Select
End Sub
Esta rutina escribe "Mi primera macro" en la celda activa y luego se desplaza a la celda inferior,
en este caso la celda A2 (esto ocurre porque Excel tiene por defecto la opción de que cuando
pulsas "Intro" el cursor se desplaza a la celda de abajo, y Excel también ha incluido eso en la
macro).
Vamos a ir poco a poco. La primera línea define una subrutina llamada Macro1 (es el nombre
que le ha puesto Excel, pero podemos cambiarlo a lo que nosotros queramos). Cada rutina que
escribamos debe empezar con Sub y terminar con una sentencia "End Sub".
Antes de explicar la segunda línea, una explicación sobre los "objetos": un objeto es una
variable de VBA que representa cualquier elemento de Excel. Por ejemplo, para representar un
rango de una hoja de cálculo se utiliza el objeto Range, o para representar una hoja de cálculo
se utiliza el objeto Worksheet. En nuestra macro estamos utilizando el objeto "ActiveCell", que
es un objeto de tipo Range que siempre apunta a la celda activa.
Los objetos tienen "propiedades" y "métodos". Una propiedad es un atributo del objeto que
define una característica del mismo. Por ejemplo, la propiedad "Row" del objeto "ActiveCell"
nos indica en qué fila de la hoja de cálculo está la celda activa. Para acceder a una propiedad
de un objeto se utiliza el nombre del objeto, un punto y el nombre de la propiedad (p.ej.
ActiveCell.Row). Unas propiedades muy utilizadas son las propiedades "Value" y "Formula" que
se aplican a todos los objetos Range. En nuestro ejemplo de macro, asignamos a la propiedad
"Formula" del objeto ActiveCell un texto, que es como si el usuario escribiera ese texto en esa
celda.
Los "métodos" son acciones que se pueden llevar a cabo sobre un objeto, son rutinas que se
aplican sobre el objeto. Para llamar a un método se utiliza el nombre del objeto, un punto y el
nombre del método. Por ejemplo, el método "ActiveCell.ClearContents" borra el contenido de la
celda activa (es decir, como si el usuario pulsa la tecla "Suprimir").
Volvamos a nuestra primera macro. La segunda línea asigna un valor a la propiedad " Formula"
del objeto ActiveCell. En realidad no es una formula sino una cadena, pero da lo mismo. Fíjate
en que en VBA siempre que escribamos una cadena de caracteres hay que encerrarla entre
comillas dobles ("), igual que en otros lenguajes. Si dentro de una cadena queremos poner
unas comillas dobles, sólo tenemos que escribirlas dos veces ("en esta cadena hay unas
comillas "" dobles")
La tercera línea llama al método Select del rango "A2" de la hoja activa. Fíjate en la forma de
obtener el objeto que representa a la celda "A2", utilizando Range("A2"). La última línea se
encarga de indicar dónde termina la rutina. Por cada Sub que escribamos obligatoriamente
tenemos que escribir un "End Sub".
Con la opción "Herramientas, Macro..." Excel te lista todas las macros disponibles y
puedes seleccionar la que quieras y ejecutarla.
Asignar una macro a una nueva opción del menú de Herramientas.
Asignar una "tecla rápida" a la macro, que se ejecutará cada vez que pulsemos esa
tecla.
Crear un botón y asignar a ese botón la rutina, de forma que ésta se ejecutará cada
vez que pulsemos el botón. Para crear un botón tenemos que mostrar la barra de
herramientas de "Diálogo" (pulsa con el botón derecho sobre cualquier barra de
herramientas, y en el menú que aparece selecciona "Diálogo" y verás que aparece la
nueva barra de herramientas).
En esa barra de herramientas hay un botón que sirve para colocar botones (valga la
redundancia) en nuestra hoja. Pulsa ese botón y crea el tuyo en cualquier parte de una
hoja de cálculo, con el tamaño que quieras. Luego pulsa sobre ese botón con el botón
derecho y del menú contextual selecciona la opción "Asignar macro". Verás una lista de
macros disponibles, selecciona la que acabamos de crear (Macro1). Ahora cada vez
que pulsemos el botón se ejecutará la macro Macro1.
Mientras estamos editando una hoja de módulos, un método muy práctico de ejecutar
las rutinas es situar el cursor dentro de una rutina y pulsar el botón de "Ejecutar
macro" de la barra de herramientas de Visual Basic. Hay que tener cuidado con este
método en Excel 95, porque en algunos casos puede dar errores: por ejemplo, con este
método nuestra primera macro no funciona porque "ActiveCell" no existe, ya que
estamos en una hoja de módulo, por lo que Excel nos dará un mensaje de error. En
Excel 97 este problema no ocurre porque no existen hojas de módulo, sino módulos
dentro del Visual Basic Editor.
Podemos utilizar cualquiera de estos métodos (y otros que ya veremos) para ejecutar nuestra
rutina, y comprobaremos que cada vez que la ejecutamos escribe un texto en la celda activa y
luego desplaza la selección a la celda de abajo.
Además de los objetos con sus métodos y propiedades Excel también tiene funciones. Para
llamar a una función simplemente hay que escribir su nombre y luego los parámetros
necesarios. Por ejemplo, vamos a hacer una pequeña macro que utilice la función MsgBox.
Esta función sirve para presentar cuadros de diálogo con mensajes para el usuario, aunque no
tenemos muchas opciones para diseñar el diálogo, sólo se puede elegir el tipo de icono entre
varios predefinidos (interrogación, exclamación, etc.) y unas cuantas opciones sobre los
botones del cuadro de diálogo (Aceptar, Cancelar, Sí, No...). A pesar de todo es muy útil para
presentar información al usuario, por ejemplo cuando se ha terminado un proceso con éxito,
cuando ha ocurrido un error, o para pedir información del tipo de "¿Estás seguro de que
quieres hacer....?", lo que hace que se una función bastante utilizada.
Pues nada, aquí tenemos una pequeña rutina que utiliza la función MsgBox:
Sub MiMacro()
MsgBox "Hola mundo", vbOkOnly + vbInformation,
"Mi segunda macro"
End Sub
Recuerda que para escribir la macro tienes que situarte en una hoja de módulo en Excel 95, o ir
al editor de VB en Excel 97, y dentro de él seleccionar un módulo. Por ejemplo, podemos
escribir esta macro debajo de la que hemos creado antes utilizando la "grabadora" de Excel.
Si ejecutamos esta macro, veremos que sale un cuadro de diálogo
con el título "Mi segunda macro" y con el texto "Hola mundo", además
de un icono que indica que es un cuadro de información, y el botón
aceptar.
Como habrás podido observar los argumentos van separados por comas. También se
pueden poner más parámetros para indicar qué fichero de ayuda queremos que se abra si el
usuario pulsa F1 mientras está viendo el cuadro de diálogo. Si quieres más información sobre
dichos parámetros, así como una lista de todas las opciones que puedes utilizar como segundo
parámetro (distintos botones e iconos) utiliza la ayuda de Excel, que es bastante completa. La
mejor forma de utilizar la ayuda es colocar el cursor sobre la instrucción sobre la que queremos
buscar la ayuda y pulsar F1. Si Excel encuentra esa palabra en el archivo de ayuda, nos
mostrará la página de ayuda sobre ella.
Sub Macro3()
If MsgBox("Pulsa Aceptar o Cancelar",
vbOKCancel) = vbOK Then
MsgBox ("Has pulsado Aceptar")
Else
MsgBox ("Has pulsado Cancelar")
End If
End Sub
Bueno, varias cosas nuevas. En primer lugar el "If - Then - Else - End If". Como su nombre
indica, esta instrucción (la ayuda de Excel los llama enunciados) se utiliza para evaluar
condiciones. Su forma general es: If <condición> Then .... Else .... End If
El usuario va a tener dos botones (Aceptar y Cancelar), y dependiendo de cuál de ellos pulse
obtendremos un valor u otro, representados por Excel mediante unas constantes: vbOk si el
usuario pulsa Aceptar, vbCancel si el usuario pulsa Cancelar, vbYes si el usuario pulsa Sí (que
en este ejemplo no existe pero podemos ponerlo), etc. Como siempre, en la ayuda de Excel
están todas los valores posibles que puede devolver MsgBox.
Bueno, entendido esto supongo que el resto de la macro es fácil de entender: lo que hace es
mostrar un mensaje con dos botones (Aceptar y Cancelar), y dependiendo de lo que el usuario
seleccione muestra otro mensaje informando al usuario de lo que ha pulsado. No es que sea
demasiado útil pero nos ha servido para aprender algo más.
Vamos hacer otra macro un poco más complicada, que utilice la función MsgBox y las
propiedades de los objetos que hemos aprendido antes:
Sub Macro4()
If MsgBox("Información sobre la celda activa: " & Chr(13) & _
"Fórmula: " & ActiveCell.Formula
& Chr(13) & _ "Valor: " & ActiveCell.Value _
& Chr(13) & Chr(13) & _ "Pulsa Aceptar para borrar el contenido de la
celda activa " _ & "y Cancelar para dejarla como está", _ vbOKCancel +
vbInformation, "Mi cuarta macro") = vbOK Then
ActiveCell.Value = ""
End If
End Sub
Bueno, hay varias cosas que explicar: con el caracter "_" al final de una línea queremos decirle
a Excel que la línea continúa, pero lo vamos a escribir debajo (por razones de legibilidad). Es
decir, es como si desde el "If" de la segunda línea hasta el "Then" de la séptima línea estuviese
todo en la misma línea, pero si lo pusiésemos en la misma línea sería bastante difícil de leer.
El carácter "&" se utiliza para concatenar dos cadenas de caracteres. Por ejemplo, la cadena
"Macedonia Magazine" es igual que la cadena "Macedonia " & "Magazine".
La función Chr() se utiliza para obtener el carácter representado por un código ASCII. No es
demasiado utilizada, tan sólo nos interesa saber que código ASCII número 13 representa el
cambio de línea, y en este caso lo utilizamos para empezar una nueva línea en el texto que
vamos a presentar en el cuadro de diálogo.
Fíjate cómo obtenemos información sobre la celda activa utilizando las propiedades Formula y
Value del objeto ActiveCell. Podemos observar que las propiedades Formula y Value son
distintas cuando las leemos (una tiene la fórmula, y la otra tiene el valor) mientras que para dar
un valor a la celda nos da lo mismo utilizar una u otra: la línea que dice ActiveCell.Value = ""
puede sustituirse por ActiveCell.Formula = "", obteniendo el mismo resultado.
Para ejecutar esta rutina, vamos a probar el método de asignar a una tecla esta macro. Para
ello vamos a Herramientas, Macro. De la lista de macros, seleccionamos ésta y pulsamos el
botón "Opciones...", que nos llevará a una ventana donde aparecen varias opciones para
nuestra macro. En este diálogo podemos decir a Excel que ponga la macro como una opción
del menu de Herramientas, y también como tecla rápida. Podemos poner por ejemplo la tecla
Ctrl-M. Ahora vamos a una hoja de cálculo, e introducimos en cualquier celda la fórmula
"=5+2". Si pulsamos ahora las teclas Ctrl-M ejecutaremos nuestra macro y veremos lo
siguiente:
Bueno, espero que haya quedado relativamente claro. Hasta ahora hemos aprendido lo que es
una macro o rutina, cómo ejecutarla, unos conceptos básicos sobre objetos y la instrucción "If-
Then-Else", una de las más utilizadas.
Vamos a avanzar un poco más, aprendiendo a utilizar otra instrucción muy útil, el bucle "For", y
a profundizar un poco en el uso del objeto Range, que es seguramente el más utilizado.
Después de haber hecho el típico programa "Hola mundo" (el primero que hemos hecho todos
cuando hemos aprendido un lenguaje de programación) vamos a hacer ahora otro clásico:
vamos a pedirle al usuario que nos de un número y le vamos a dar la tabla de multiplicar de ese
número.
Aquí va la rutina completa, y luego la explicamos:
Sub TablaMultiplicar()
Dim n, i As Integer
Dim s As String
Dim r As Range
Pulsa aquí para bajarte un fichero de Excel que contiene este ejemplo. Lo primero es la
declaración de variables. Una variable es un espacio de memoria que reservamos para
almacenar datos.
Con la sentencia "Dim n,i as Integer" estamos diciendo que queremos reservar memoria para
dos variables (n, i) de tipo entero, para almacenar números enteros. Igualmente en las
siguientes líneas reservamos memoria para una variable de cadena (string), que almacenará
cadenas de caracteres, y para una variable de tipo Range. En VBA no es obligatorio declarar
las variables antes de utilizarlas, a no ser que en cada módulo escribamos al principio "Options
Explicit", con lo que estaremos indicando a VBA que debe comprobar que todas las variables
que utilicemos estén previamente declaradas. No voy a entrar en la eterna polémica de si es
mejor declarar las variables o no hacerlo, pero personalmente creo que es mejor hacerlo, para
que el tipo de datos que almacena cada variable esté claro y para evitar errores al escribir los
nombres de variables que luego pueden ser difíciles de localizar.
Después de llamar a InputBox, comprobamos que variable "s" no está vacía, lo que significa
que el usuario ha escrito algo en el diálogo y luego ha pulsado Aceptar. Si "s" esta vacía, la
rutina termina sin hacer nada más.
Como siempre suele suceder, existe la posibilidad de que el usuario haya escrito un valor con
decimales o que haya escrito letras en lugar de números. En una macro más profesional
deberíamos comprobar esas posibilidades para asegurarnos de que nuestra macro no sufre
ningún error en caso de que el usuario introduzca algún dato inesperado, pero por ahora no
vamos a meternos en líos de esos.
La siguiente línea debería ser fácil de entender a estas alturas: damos un valor a la propiedad
"Value" del rango C2 de la hoja activa, al que accedemos utilizando "ActiveSheet.Range("C2")".
Una pequeña recomendación: siempre que hagas referencia a rangos de hojas de cálculo
desde VBA es recomendable utilizar nombres definidos de rango en lugar de referencias tipo
C2. Por ejemplo, podemos dar a la celda C2 el nombre "Título tabla" y acceder a ella utilizando
Range("Título tabla"). La ventaja de esto es que si luego queremos que en lugar de en la celda
C2 lo escriba en cualquier otra celda sólo tenemos que cambiar el nombre, sin tocar el código.
En la siguiente línea utilizamos el enunciado "Set" para que la variable r (de tipo Range) apunte
al rango C4 de la hoja activa.
Luego viene la sentencia "For - Next", que tiene varias formas, pero esta es la más sencilla: lo
que hacemos es que la variable "i" (como siempre, previamente declarada como de tipo entero)
tome los valores comprendidos entre el 0 y el 10 (ambos inclusive), y para cada uno de esos
valores se ejecute el código comprendido entre las líneas For y Next. Es decir, las dos líneas
que hay entre el For y el Next se van a ejecutar once veces: la primera vez que se ejecuten, la
variable i tendrá el valor 0; la segunda vez, i tendrá el valor 1; y la última vez i tendrá el valor
10. El bucle "For - Next" es muy utilizado, y en VBA funciona de forma muy parecida a
cualquier otro lenguaje de programación.
Las dos líneas que hay entre el For y el Next son prácticamente iguales. El método " Offset" es
un método que se aplica a los objetos de tipo Range (como nuestra variable "r") para desplazar
el rango al que apunta. El primer parámetro del método Offset es el número de filas que
queremos desplazar el rango (positivo hacia abajo, negativo hacia arriba), y el segundo
parámetro es el número de columnas que queremos desplazar el rango. Vamos a verlo con un
ejemplo: si nuestra variable "r" apunta al rango C4:
Las dos líneas de nuestra rutina lo que hacen es crear una tabla de dos columnas, poniendo en
la primera columna los números del 0 al 10 (es decir, los valores que va tomando i cada vez
que se ejecutan estas dos líneas) y en la segunda columna el resultado de multiplicar el valor
de i por el número que nos ha indicado anteriormente el usuario (n).
Antes de terminar con este ejemplo hay que dejar claro que la tabla de multiplicar puede
hacerse de forma mucho más sencilla y rápida sin utilizar macros, utilizando tan sólo funciones
de hoja de cálculo, pero nos ha servido como ejemplo sencillo para aprender algunas cosas
más sobre VBA.
Bueno, hasta aquí ha llegado la primera entrega de este curso. Con lo que hemos aprendido
hasta aquí se pueden hacer ya algunas cosas. Que a nadie le de miedo hacer todos los
experimentos que quiera, que es la mejor forma de aprender. También es muy útil consultar a
menudo la ayuda de Excel, que es bastante completa. Espero que alguno de los que habéis
llegado hasta aquí me escribáis diciéndome qué os ha parecido.
En este capítulo vamos a aprender un poco más sobre cómo hacer referencia a celdas, rangos,
hojas y libros. Supongo que todos estos conceptos están claros, que todo el mundo sabe lo que
es una celda o un rango, o la diferencia entre un libro y una hoja.
Excel2.xls
Todos los ejemplos de este capítulo están incluidos en este fichero:
(39kbs)
Bueno, para entrar en calor vamos a hacer una pequeña rutina que pida al usuario un valor y
luego sume ese valor a la celda activa.
Sub Sumar_A_Celda()
Dim i As Double
En este caso declaramos la variable como Double, por si acaso al usuario se le ocurre meter
un valor con decimales.
Siguiendo con nuestra rutina, primero presentamos al usuario un pequeño mensaje diciendo lo
que vamos a hacer. Esto está explicado en la entrega anterior, no creo que necesite nada más.
Si el usuario pulsa "Cancelar", salimos de la rutina y no hacemos nada.
En la siguiente línea obtenemos del usuario el valor que quiere sumar a la celda activa. La
función InputBox ya la hemos visto antes, obtiene del usuario una entrada, pero en formato de
cadena de caracteres. Como nosotros lo que queremos es un valor numérico, utilizamos la
función Val() para convertir la cadena de caracteres proveniente de InputBox en un número. Lo
ponemos todo en la misma línea, pero también se podía haber escrito en dos líneas:
Dim s as String
s = InputBox("Importe a sumar: ", "Sumar a celda activa")
i = Val(s)
Bueno, seguramente queda más claro que de la otra forma, pero normalmente se escribe de la
primera forma. Cada uno que lo escriba como quiera, tampoco tiene demasiada trascendencia.
Un pequeño ejemplo del uso del objeto Application: para mostrar y ocultar la barra de estado (la
que aparece en la parte de abajo, debajo de las etiquetas de las hojas), podemos usar el
siguiente código:
El objeto Application tiene un montón de propiedades y métodos, que están muy bien
explicados en la ayuda de Excel, y su uso es bastante sencillo.
Siguiendo con la última línea de la rutina, podrás comprobar que utilizamos la propiedad Value
de ActiveCell. Si hubiésemos utilizado la propiedad Formula en lugar de Value, la rutina tendría
que ser un poco distinta. Utilizando Value, estamos dando a la celda activa un valor
directamente, es decir, si miras el contenido de la celda verás que no hay ninguna fórmula; la
suma la ha hecho nuestra rutina, y ha puesto en la celda el resultado de dicha suma.
Sin embargo, si queremos que la fórmula de la suma quede en la celda debemos usar la
propiedad Formula. La propiedad Formula es una "cadena de carácteres", que incluye todo lo
que se escribiría normalmente en una celda de una hoja de cálculo para introducir una fórmula
(incluyendo el signo "=" al principio). Por ejemplo, si queremos que poner en la celda A2 una
fórmula que nos de el doble del valor de la celda A1, haremos:
Range("A2").Formula = "=A1*2"
Como es una cadena de caracteres, hay que rodearla con comillas dobles, y entre éstas
ponemos la fórmula tal como lo haríamos en la hoja de cálculo. Tras esta explicación, si
queremos cambiar nuestra rutina para introducir la fómula de suma en la celda, nuestro primer
intento sería escribir:
ActiveCell.Formula = ActiveCell.Formula + i
Si ejecutamos este código veremos que el resultado puede variar dependiendo de lo que
contenga la celda activa:
Si la celda activa contiene un número (no una fórmula), el resultado es el mismo que
antes. La razón es que como no hay ninguna fórmula ActiveCell.Formula devuelve un
número, igual que ActiveCell.Value. Luego le sumamos nuestro valor y asignamos el
valor resultante como fórmula de la celda.
Si la celda activa contiene una fórmula, el resultado es que la macro se para con un
error. Esto es debido a que ActiveCell.Fórmula nos devuelve una cadena de caracteres
(por ejemplo, la cadena "=A1*2"), y luego estamos intentando sumar un número (i) a
una cadena de caracteres, cosa que evidentemente no se puede hacer y Excel nos da
un error de tipos de datos incompatibles.
Para conseguir lo que realmente queremos (introducir una fórmula en la celda), debemos
asignar a ActiveCell.Formula una cadena de caracteres con una fórmula escrita correctamente.
Vamos a intentarlo:
El problema que se nos presenta ahora es que si en la celda activa no hay una celda, sino un
valor (por ejemplo, 2), nosotros asignaremos a ActiveCell.Formula la cadena "2+3" (si i tiene el
valor 3). ¿Veis el error? Evidentemente el error es que falta el signo "=" al principio de la
fórmula para decirle a Excel que es una fórmula. O sea que deberíamos añadir delante de la
fórmula un "=", lo que podemos hacer de la siguiente forma:
¿Cuál es el problema ahora? Pues que si la celda activa tiene una fórmula nos encontramos
con que nuestra fórmula definitiva tiene dos signos "=" al principio, uno el que ya tenía y otro el
que le hemos puesto nosotros. El resultado es que introducimos una fórmula incorrecta y Excel
nos vuelve a dar un error.
Bueno, creo que he montado un pequeño lío, pero en realidad no tiene ninguna dificultad. Lo
que hay que hacer es comprobar si en la celda activa hay una fórmula (esto se puede hacer
mirando si el primer carácter es el signo "=", utilizando por ejemplo la función Left). Si hay una
fórmula, sólo añadimos la parte del final, y si no hay una fórmula añadimos primero un signo "="
y luego la parte del final. Esto queda como ejercicio, y si no te sale me escribes y lo
comentamos.
Pues aparte de todo este lío ya lo hemos visto todo. Si ejecutas la rutina Sumar_A_Celda()
comprobarás que primero te pide un valor y luego suma ese valor a la celda activa. Por cierto,
que nadie piense que esta macro es ninguna maravilla, porque lo mismo que hace se puede
hacer más rápido utilizando "Pegado especial..", que además es capaz de restar, multiplicar y
dividir. Ya llegaremos a eso también, pero para ir aprendiendo un poco no nos viene mal.
Ahora vamos a avanzar otro paso: la rutina anterior sumaba un valor a la celda activa, y ahora
vamos a sumar ese valor a todo el rango que seleccione el usuario. Como siempre, aquí va la
rutina completa, luego la explicamos:
Sub Sumar_A_Rango()
Dim i As Double
Dim h As Object
Lo primero que hacemos es declarar las variables. La primera variable (i), es de tipo Double, al
igual que en la rutina anterior. La segunda variable (h) la declaramos como una variable de tipo
Object, para que apunte a cualquier tipo de objeto de Excel (una hoja, un rango, una celda,
etc.)
Las dos siguientes líneas son iguales que antes: primero presentamos un pequeño mensaje al
usuario, y luego obtenemos el valor y convertimos la cadena a un valor numérico.
En las tres siguientes líneas está todo lo nuevo. Vamos por pasos: Selection es una propiedad
del objeto Application, o sea que al escribir Selection Excel supone que estamos escribiendo
Application.Selection. Pues bien, la propiedad Selection nos devuelve el rango que está
seleccionado en la hoja activa, es decir, un objeto de tipo Range.
Con Selection obtenemos un objeto de tipo Range que apunta al rango seleccionado de la
hoja activa. Si accedemos a la propiedad Cells de ese objeto Range, obtendremos un
"conjunto" de todas las celdas de ese rango.
¿Que es un conjunto? Un conjunto es un objeto que contiene otros objetos, generalmente del
mismo tipo (la definición la he copiado de la ayuda de Windows). La propiedad Cells de un
objeto Range nos devuelve un conjunto que contiene todas las celdas de ese rango.
Luego viene una instrucción "For". En la entrega anterior vimos una instrucción For, pero un
poco distinta a esta. En ese caso lo que hacíamos era dar a una variable distintos valores,
desde el 1 hasta el 10, y para cada valor de la variable ejecutábamos unas instrucciones.
Análogamente, en esta ocasión vamos a dar a la variable "h" (de tipo Object) unos valores, y
para cada valor de "h" vamos a ejecutar una instrucción.
Para dar los distintos valores a "h" vamos a utilizar la instrucción "For Each", que "repite un
grupo de enunciados para cada elemento de una matriz o de un conjunto". El conjunto que
vamos a utilizar es Selection.Cells, que como sabemos son todas las celdas del rango
seleccionado. Es decir, que con
lo que hacemos es ejecutar una instrucción para cada una de las celdas del conjunto
Selection.Cells. La primera vez que se ejecute la instrucción de dentro del buble, h
representará la primera celda del conjunto de celdas, la segunda vez representará la segunda
celda del conjunto, etc. En este caso lo que hemos hecho ha sido sumar el valor uno a todas
las celdas del rango seleccionado.
La instrucción que va dentro del bucle es la misma que en el ejemplo anterior; tan sólo fíjate
que utilizamos "h" en lugar de ActiveCell.
Vamos a hacer otro pequeño ejemplo del uso de "For Each" y de conjuntos. En esta ocasión
vamos a cambiar el nombre de todas las hojas del libro activo. Para obtener una referencia al
libro activo utilizaremos la propiedad ActiveWorkbook del objeto Application. Para acceder a
todas las hojas de cálculo del libro activo, utilizaremos la propiedad Worksheets de dicho
objeto, ActiveWorkbook. He utilizado la propiedad Worksheets porque esta nos devuelve sólo
las hojas de cálculo (no las hojas de gráficos, módulos, etc.). Si queremos acceder a todas las
hojas (de cualquier tipo) del libro, utilizaremos la propiedad Sheets, que funciona igual que
Worksheets.
i = 15
For Each h In ActiveWorkbook.Worksheets
h.Name = "Hoja " & i
i=i+1
Next h
End Sub
Lo que hace esta rutina es cambiar los nombres de las hojas de cálculo del libro activo,
poniéndoles los nombres "Hoja15", "Hoja16", etc. No es que sea una rutina demasiado útil,
pero como siempre sirve para aprender un poco.
Como siempre, empezamos con la declaración de variables. Luego le damos a la variable "i" el
valor 15, porque nos da la gana, podíamos haberle dado cualquier otro. Luego viene lo que nos
interesa, el "For Each". Para cada hoja de cálculo (Worksheets) del libro activo
(ActiveWorkbook) vamos a ejecutar las dos instrucciones que están dentro del bucle.
Para cambiar el nombre de una hoja utilizamos la propiedad Name. Luego incrementamos el
valor de "i" para dar el nombre a la hoja siguiente. (Si intentamos dar a dos hojas el mismo
nombre Excel nos dará un mensaje de error)
Sub ListaHojas()
Dim h As Object
Dim r As Range
Lo que hace esta rutina es crear en la hoja de cálculo activa una tabla con los nombres de
todas las hojas del libro. Primero, con "Set r = ActiveCell", hacemos que la variable "r" apunte a
la celda activa.
Luego viene el bucle "For Each / Next", que al igual que en el ejemplo anterior hace que el
código entre estas dos líneas se ejecute una vez para cada hoja del libro. La única diferencia
es que en el ejemplo anterior utilizábamos "ActiveWorkbook.Worksheets" (que pasa por
todas las hojas de "cálculo" del libro) y aquí "ActiveWorkbook.Sheets" (que pasa por todas
las hojas del libro, de todo tipo).
Primero damos a la celda "r" el nombre de la primera hoja del libro. En la siguiente línea,
ponemos en a celda de la derecha de "r" (con el Offset(0,1)) el tipo de hoja de que se trata,
utilizando la función "TypeName(h)": esta función devuelve una cadena de carácteres que
proporciona información sobre la variable "h".
En la siguiente línea, utilizando otra vez Offset, "movemos" la variable "r" para que apunte a la
celda inferior. Y así, vuelta a empezar.
Y para terminar, vamos a aprender a utilizar el método Copy, que se aplica a objetos de Excel
que puedan ser copiados, como por ejemplo un objeto de tipo Range, aunque también a otros
objetos como hojas enteras o gráficos.
Sub Copiar_CeldaIzquierda()
If MsgBox("Esta macro copia en la celda
activa el contenido de la celda situada" & _
Chr(13) & "a su izquierda.", vbOK, "Copiar celda
izquierda") = vbCancel Then Exit Sub
ActiveCell.Offset(0, -1).Copy ActiveCell
End Sub
La sintaxis de Copy es muy sencilla: se ejecuta el método Copy sobre el rango de "origen", es
decir, el que queremos copiar. En el ejemplo, hacemos "ActiveCell.Offset(0,-1).Copy", ya que
queremos copiar la celda que está a la izquierda de la celda activa.
El parámetro del método Copy indica el rango de "destino" para la copia. En nuestro ejemplo
ponemos "ActiveCell", ya que queremos que lo que hemos copiado se copie en la celda activa.
Si omitimos el parámetro del método Copy la copia se hará en el "Portapapeles", y luego
deberemos utilizar otros métodos como "Paste" o "PasteSpecial" para pegar el contenido del
portapapeles en otra celda.
Hasta aquí llega esta segunda entrega del curso. En este capítulo hemos aprendido a trabajar
con celdas, rangos, libros y hojas, que es una de las partes más útiles de la programación en
Excel, permitiéndonos hacer cualquier operación (mover, copiar, borrar, hacer operaciones
aritméticas, etc) con los datos de una hoja de cálculo.
Excel2.xls
Recuerda que los ejemplos de este capítulo están incluídos en este fichero:
(39kbs)
Este capítulo va a tratar sobre los cuadros de diálogo, que se utilizan para obtener información
del usuario. Una aclaración respecto a versiones: uno de los cambios más importantes de
Excel 95 a Excel 97 en el apartado de programación es la parte de cuadros de diálogo. La
verdad es que hay muchas diferencias entre ambos y eso hace imposible hablar de las dos
versiones a la vez, por lo que este capítulo está dirigido sólo a Excel 97.
Excel3.xls
Todos los ejemplos de este capítulo están incluídos en este fichero:
(117kbs)
Los cuadros de diálogo en Office 97 son mucho más potentes que en la versión anterior. Se
han añadido muchas opciones, como la posibilidad de definir eventos, utilizar controles ActiveX
además de los incluidos en Excel (si no sabes qué es un control ActiveX no tiene demasiada
importancia, es un tema avanzado que quizá algún día tratemos), etc.
Nuestro primer cuadro de diálogo va a ser muy sencillo: vamos a presentar un cuadro de
diálogo en el que el usuario puede introducir un número, y si pulsa "Aceptar" copiaremos el
número introducido en la celda activa. Si el usuario pulsa "Cancelar" no haremos nada.
Ahora para crear nuestro cuadro de diálogo vamos a utilizar la opción "Insertar, Userform"
(Userform es el nombre que da Excel 97 a los cuadros de diálogo).
Etiqueta
: para mostrar un texto en el
cuadro de diálogo. El usuario
no puede editarlo.
C u a d r o d e t
introduzca un texto.
C u a d r
para que el usuario seleccione
una opción entre varias.
C u a d r o d e l i
seleccione una opción de entre
las que le presentamos.
C a s i l l a d
B o t ó n d e o p
seleccione una opción entre
varias.
B o t ó n d e c
como los típicos de "Aceptar" y
"Cancelar"
Marco: para agrupar varios controles. Su uso es básicamente por razones estéticas.
Como puedes ver en el diálogo de ejemplo un marco puede tener distintas apariencias.
Primero vamos a ver las propiedades del objeto UserForm. Para ello seleccionamos el
Userform de la parte derecha simplemente pulsándolo con el ratón. En la parte inferior
izquierda, en la ventana de Propiedades, tenemos la lista de propiedades del objeto UserForm.
Utilizando esta ventana podemos cambiar el valor de cualquier propiedad del Userform.
Algunas de las propiedades más importantes son:
Name: el nombre con el que vamos a identificar el UserForm. Tiene que ser único y no
puede tener espacios ni otros caracteres raros. Yo suelo ponerles un nombre que
empiece por "uf" (por ejemplo, ufDatosPersonales), porque así cuando en el código VB
haga una referencia a este objeto sé que se trata de un objeto UserForm.
Caption: es el título que el usuario verá en el cuadro de diálogo. Se puede poner
cualquier texto, incluyendo espacios.
BackColor: el color de fondo del cuadro de diálogo. Por defecto es el color gris que
suelen tener todos los cuadros de diálogo en Windows.
ForeColor: el color de primer plano, es decir, del texto que aparezca en el cuadro de
diálogo.
Font: el tipo de letra por defecto para el cuadro de diálogo. Este es el tipo de letra que
tendrán todos los controles que insertemos en el cuadro de diálogo, pero si luego
queremos cambiarlo para cualquier control puede hacerse.
StartupPosition: la posición en la que aparecerá el cuadro de diálogo. Si le damos el
valor "CenterScreen" el diálogo saldrá en el centro de la pantalla.
SpecialEffect: para cambiar un poco los bordes del cuadro de diálogo.
Picture, PictureAlignment, PictureSizeMode, PictureTiling: se utilizan para poner un
dibujo como fondo del cuadro de diálogo.
Hay más propiedades, pero su uso es bastante sencillo, y consultando la ayuda encontrarás la
descripción de todas las propiedades.
Como hemos dicho antes, en nuestro cuadro de diálogo queremos que el usuario escriba un
número. Para que pueda hacerlo, tendremos que poner un cuadro de texto en el diálogo. Para
ello pulsamos en el UserForm para que aparezca el "Cuadro de Herramientas" y en éste
pulsamos sobre el control "Cuadro de Texto" . Una vez seleccionado el "Cuadro de Texto"
pulsamos en cualquier parte del UserForm y veremos que aparece un cuadro de edición.
Podemos utilizar el ratón para moverlo y cambiarle el tamaño.
Name: el nombre del objeto. Como antes, no puede incluir espacios ni caracteres
especiales. Yo suelo utilizar nombres que empiecen por "tb", para identificar estos
objetos como un TextBox, pero se puede utilizar cualquier nombre.
Text: es el texto que va dentro del cuadro de edición, es decir, el que ha escrito el
usuario.
TextAlign: alineación del texto dentro del cuadro de diálogo. Normalmente si lo que
queremos es que el usuario introduzca una cadena de texto se suele alinear a la
izquierda, y si queremos que introduzca números se suele alinear a la derecha.
MultiLine: los valores posibles son verdadero y falso, indicando si queremos que el
control permita al usuario escribir más de una línea o no.
Las propiedas sobre la apariencia del control son parecidas a las que hemos visto antes
(BackColor, ForeColor, SpecialEffects). El resto de propiedades se pueden consultar en la
ayuda. Aunque parezca que nos estamos dejando muchas cosas, una vez que empezamos a
tener claras las cosas el utilizar propiedades que no hemos usado nunca es muy sencillo. O
sea, que por ahora nos centramos en lo básico.
Bueno, ahora vamos a nuestro cuadro de diálogo. Seleccionamos nuestro cuadro de edición, lo
colocamos en una posición que nos guste, y vamos a las propiedades. Primero la propiedad
Name, que en este caso vamos a dejar tal como está, TextBox1. No suele ser aconsejable
dejar estos nombres, porque si tienes varios cuadros de edición en un diálogo al final no sabes
a cuál te estás refiriendo, pero como en este caso sólo vamos a tener un cuadro de edición no
nos importa demasiado. Ahora vamos a la propiedad "TextAlign" y vamos a seleccionar la
opción "fmTextAlignRight" para alinear el texto a la derecha, ya que lo que queremos es que le
usuario introduzca un número. Por ahora no vamos a hacer nada más con este control.
Lo siguiente que vamos a hacer es poner un texto descriptivo para el cuadro de edición. Para
ello seleccionamos del "Cuadro de herramientas" el control "Etiqueta" , y pulsamos en el
UserForm para crear un control del tipo etiqueta. Utilizando el ratón le podemos cambiar el
tamaño y moverlo, para ponerlo a la izquierda del control de edición que hemos creado antes.
En la ventana de propiedades de nuestro nuevo control (recuerda que tienes que seleccionarlo
para poder ver sus propiedades en la ventana de propiedades) veremos como siempre la lista
de propiedades. La propiedad Name la vamos a dejar como está, ya que no vamos a referirnos
a este control en el código, y no nos interesa su nombre: normalmente los controles de etiqueta
se utilizan sólo para poner un texto en el diálogo, y no se suelen referenciar desde el código
VB. La propiedad que nos interesa es "Caption", en la que escribiremos el texto que queremos
que aparezca en el cuadro de diálogo, por ejemplo "Escribe un número:".
Si colocamos bien los dos controles (utilizando por ejemplo la opción "Formato, Alinear, Medio),
ya tenemos un diálogo algo más completo.
Lo típico en estos cuadros de diálogo es que en la parte inferior haya dos botones, uno para
"Aceptar" y el otro para "Cancelar". Vamos a colocar estos dos botones, empezando por el de
"Cancelar" que es un poco más fácil.
Name: el nombre del control. Vamos a darle el nombre "cbCancel" (cb viene de
CommandButton).
Caption: el texto del botón. Lógicamente, vamos a poner "Cancelar".
Cancel: puede ser verdadero o falso. Sólo puede haber un control en el cuadro de
diálogo con la propiedad Cancel establecida como verdadero. Si le damos a Cancel el
valor verdadero, cuando se esté ejecutando el cuadro de diálogo si el usuario pulsa
"Escape" será como si hubiese pulsado con el ratón sobre este botón. En este caso
nos interesa que ocurra, o sea que vamos a darle el valor verdadero.
Default: verdadero o falso, indica si el botón es el botón por defecto del cuadro de
diálogo. Si el usuario pulsa "Enter" cuando está viendo el diálogo será como si pulsa
con el ratón sobre el botón que tenga la propiedad Default (sólo puede haber uno). En
este caso vamos a dejar la propiedad en False porque queremos que el botón por
defecto sea el de "Aceptar", que crearemos más adelante.
Por ahora dejamos el resto de propiedades de los botones. Bueno, hasta ahora le hemos dado
a nuestro botón el nombre "cbCancel", le hemos puesto el texto "Cancelar" y hemos dado el
valor "Verdadero" a la propiedad "Cancel".
Si ejecutamos el cuadro de diálogo veremos que tenemos un botón muy bonito, pero que no
hace absolutamente nada. Para que haga algo tenemos que meternos con un concepto muy
importante de la programación orientada a objetos, los Eventos.
A estas alturas ya deberían estar claros los conceptos de Objeto, Propiedad y Método. En
Excel, un objeto es una variable que representa cualquier elemento de Excel, como un rango,
un libro, una celda, o un UserForm. Todos los objetos tienen propiedades (como Cell.Value,
Workbook.Name o UserForm.BackColor), y métodos (como Range.ClearContents o
UserForm.Show).
Bueno, no sé si ha quedado muy claro, pero creo que con un poco de práctica espero que sí.
Dominar los conceptos de objeto, propiedad, método y evento es muy importante, pero no
sólo para programación en Visual Basic for Applications, sino que estos conceptos son básicos
en todos los lenguajes de programación orientada a objetos (Visual Basic, Borland Delphi,
Java, etc.). De hecho, si dominas esos conceptos con cuatro cosas más podrás programar en
cualquiera de esos otros lenguajes.
Bueno, sigamos con los eventos. Vamos a centrarnos ahora en nuestro botón de " Cancelar". El
evento más normal para un botón es que el usuario lo pulse con el ratón (o con el teclado).
Cuando esto ocurra, se generará un evento Click, y llamará a la rutina cbCancelar_Click().
(cbCancelar es el nombre que habíamos dado al control, y Click es el nombre del evento). Lo
más fácil para crear un evento es seleccionar un control y luego pulsar el botón derecho y
seleccionar la opción "Ver Código". Veremos una página de código VB en la que Excel habrá
escrito la cabecera de un evento para dicho control (la verdad es que no sé cuál de los eventos
coge, supongo que cogerá el más utilizado). En nuestro caso, si pulsamos sobre el botón
"Cancelar" con el botón derecho y luego "Ver código" en la página de código veremos lo
siguiente:
Private Sub cbCancelar_Click()
End Sub
Excel nos ha creado la cabecera para la función que queremos crear. En este caso la función
no tiene ningún parámetro, pero en otros eventos la función tiene una lista de parámetros, y
Excel también nos los pone en la cabecera.
Otra cosa, la página de código que estamos viendo es como un módulo normal en el que
escribimos nuestro código, con la particularidad de que no sale en la lista de módulos en el
"Explorador de Proyectos", ya que es un módulo asociado al Userform.
Para crear una función para cualquier otro evento tenemos en la parte superior de la ventana
de código dos "persianas". En la persiana de la izquierda tenemos el objeto sobre el que
queremos definir una función para un evento. En la persiana de la derecha tenemos todos los
eventos que pueden ocurrir para el control seleccionado en la persiana de la izquierda. Si
queremos definir la función para otro evento lo único que tenemos que hacer es seleccionar
otro evento en esta persiana, y Excel insertará en el código la cabecera para la función que se
va a ejecutar cuando se de ese evento.
Bueno, lo que queremos hacer cuando el usuario pulsa el botón de Cancelar es simplemente
cerrar el cuadro de diálogo. Tendremos que cerrar el cuadro de diálogo cuando Excel nos avise
de que ha ocurrido un evento Click, es decir, dentro de la función cbCancelar_Click().
La instrucción que se utiliza para cerrar el UserForm es "Unload", que sirve para quitar un
objeto de la memoria. La instrucción Unload requiere un parámetro, que utilizaremos para
indicarle cuál es el objeto. En nuestro caso utilizaremos la palabra clave "Me", que apunta al
objeto en el que se está ejecutando el código, es decir, nuestro UserForm.
Nuestro "manejador de eventos" para el evento Click del botón cbCancel quedaría así:
Ahora nos queda todo el tema de los eventos. El procedimiento es el mismo que con el botón
de Cancelar, con la única diferencia de que antes de cerrar el cuadro de diálogo (con la
instrucción Unload) deberemos hacer lo que queremos que nuestro diálogo haga, es decir,
copiar el contenido del cuadro de edición TextBox1. La función sería la siguiente:
Esta función es prácticamente igual que la que hemos escrito para el botón Cancelar, con la
excepción de que antes de cerrar el cuadro de diálogo escribimos otra línea, que se encarga de
copiar en la celda activa (ActiveCell) el contenido del cuadro de edición. Fíjate como
accedemos al contenido del cuadro de edición, a través del nombre del control (TextBox1) y su
propiedad Value, que nos devuelve el valor numérico de lo que se ha introducido en el control
(si hay caracteres no numéricos la propiedad Value nos devolverá el valor 0).
Lo único que hace es cerrar el cuadro de diálogo al producirse el evento "Click" del botón
Cancelar.
Esta función se ejecuta también cuando se produce el evento Click del botón llamado
cbAceptar. Antes de cerrar el cuadro de diálogo debemos guardar en las celdas de la hoja de
cálculo los valores de los cuadros de texto. Para ello utilizamos un objeto Range (a estas
alturas somos unos autenticos expertos en el objeto Range), y le asignamos a su propiedad
Value el valor de la propiedad Text del objeto TextBox. Esta es la única novedad, la utilización
de una propiedad de los objetos TextBox (tbNombre y tbApellido).
Pero hay una pequeña opción que se nos ha escapado: si vamos directamente a la hoja de
cálculo, cambiamos los nombres en sus celdas, y ejecutamos el Userform, veremos que los
controles de edición no tienen ahora los nombres actualizados, ya que no recogen los cambios
que hemos hecho nosotros directamente en la hoja de cálculo.
Para eso vamos a utilizar también los eventos. En esta ocasión vamos a utilizar un evento del
Userform (sí, los UserForms también tienen eventos). Se trata del evento Initialize, que se
produce justo antes del que el UserForm aparezca en la pantalla. Ese es el momento para
hacer cualquier cambio en el Userform, como poner un texto en un control, que es lo que
queremos hacer.
Por lo tanto, seleccionamos el UserForm, pulsamos con el botón derecho y luego la opción "Ver
código" (también se puede hacer doble-click sobre el Userform) y en la persiana de la derecha
seleccionaremos el evento Initialize. Excel creará en ese momento la cabecera de nuestra
función:
End Sub
Ahora tenemos que escribir el código que queremos que se ejecute antes de que se muestre el
Userform. Lo que queremos hacer es poner en los dos cuadros de texto (el de nombre y el de
apellido) el contenido de las celdas que tienen esos datos. Para ello utilizaremos el siguiente
código:
No creo que tenga demasiada dificultad. Es lo mismo que hemos escrito para el botón Aceptar
pero al revés, es decir, damos a los cuadros de texto del Userform el valor que tienen las
celdas de la hoja de cálculo.
Pues ya está, ahora sí que el cuadro de diálogo funciona perfectamente, tanto si hacemos los
cambios en el UserForm (se actualizará la hoja de cálculo si pulsamos Aceptar) como si
hacemos los cambios en la hoja de cálculo (se actualizará el UserForm antes de aparecer en
pantalla, porque se habrá ocurrido un evento Initialize).
Bueno, hasta aquí llega esta tercera entrega. Todavía nos queda mucho por ver sobre los
cuadros de diálogo (o UserForms, o formularios, como prefieras), pero eso lo dejamos para la
próxima entrega. Hasta entonces te toca practicar, y sobre todo recuerda que lo más
importante es tener claros los conceptos importantes: objetos, propiedades, métodos y
eventos.
Excel3.xls
Recuerda que los ejemplos de este capítulo están incluídos en este fichero:
(117kbs)
Seguimos con los UserForms y los controles. En esta entrega vamos a ampliar el diálogo sobre
datos personales, añadiéndole más opciones, y vamos a crear dos nuevos userforms: uno para
convertir de pesetas a euros y viceversa, y otro para hacer operaciones (sumar, restar...) sobre
un rango seleccionado (algo parecido a lo que hicimos antes, pero más completo).
Excel4.xls
Todos los ejemplos de este capítulo están incluídos en este fichero:
(116kbs)
Habíamos escrito el código necesario para que al abrirse el diálogo (evento Initialize del
Userform) los cuadros de edición se llenen con el texto de las celdas de la hoja de cálculo, y
también para que cuando el usuario pulse Aceptar (evento Click del botón) se copie el texto de
los cuadros de edición a la hoja de cálculo. Para hacer estos traspasos entre la hoja de cálculo
y el Userform habíamos escrito un par de líneas de código en los eventos indicados, pero
vamos a ver que hay otro método para hacerlo:
Todos los controles tienen la propiedad "ControlSource", que se utiliza para decirle al control
cuál es la "fuente" de su información, que será una celda o un rango de una hoja de cálculo.
Por ejemplo, en el cuadro de edición del Nombre podemos poner como ControlSource la celda
de la hoja de cálculo en la que está ese dato. Como siempre, no vamos a utilizar referencias
absolutas a celdas y rangos (p.ej. Hoja1!A5), sino que vamos a utilizar nombres de rango. Por
ejemplo, vamos a la hoja de cálculo y damos a la celda "fuente" el nombre "rngNombre" (rng
porque es un rango de una hoja de cálculo). Luego vamos al editor VBE, seleccionamos el
control de edición Nombre y en su propiedad ControlSource escribimos el nombre del rango
que queremos que sea su "fuente", en este caso "rngNombre".
Ahora hacemos lo mismpo para el apellido: primero damos el nombre "rngApellido" a la celda
de la hoja de cálculo y luego escribimos rngApellido en la propiedad ControlSource del control
de edición de Apellido.
Ahora tenemos que borrar el código que habíamos escrito para pasar la
información de hoja de cálculo al Userform y viceversa. Mejor que
borrarlo, lo que haremos será "comentarlo", utilizando una comilla simple
', que indica a Excel que todo lo que escribamos en esa línea detrás de la
comilla son cosas nuestras y que las ignore (el texto "comentado"
aparecerá en otro color, normalmente en verde). Aprovechando que
explico lo de los comentarios, nunca está de más recordar la importancia
que tiene añadir al código todos los comentarios que sean necesarios.
Cuando estás escribiendo una rutina sabes perfectamente cómo funciona
y qué es lo que hace, y todos pensamos que los comentarios son innecesarios, pero cuando
tras algunas semanas tienes que volver a ver la rutina te encuentras con un montón de líneas
que no sabes para qué sirven ni cómo lo hacen, y si no las has comentado tienes que "bucear"
en ellas para averiguarlo.
A lo que íbamos, estábamos borrando el código de los eventos Initialize del Userform y Click
del botón Aceptar. Vamos al editor VBE, hacemos doble-click sobre el Userform y nos aparece
la rutina Userform_Initialize(). Ponemos una comilla delante de las dos líneas que se
encargan de copiar los datos de la hoja de cálculo al userform, y veremos que dichas líneas
cambian de color, indicándonos que para Excel son comentarios y los va a ignorar. Ahora
volvemos al Userform y hacemos doble-click en el botón Aceptar, y nos aparece la rutina
btnAceptar_Click(). Volvemos a poner las comillas en las dos líneas de código que queremos
quitar y ya está.
Si probamos ahora el diálogo, veremos que la propieda ControlSource funciona, y que antes de
mostrar el diálogo "lee" el contenido de la hoja de cálculo y lo pone en el Userform, y cuando
pulsamos Aceptar copia el contenido de los controles del Userform en la hoja de cálculo.
Sin embargo he detectado un problema con el uso de ControlSource. Si hacemos algún cambio
en el Userform y luego pulsamos el botón de "Cancelar", los cambios que hemos hecho en los
datos se actualizan en la hoja de cálculo, cuando no deberían actualizarse porque hemos
pulsado Cancelar. En cambio, si hacemos algún cambio y pulsamos la tecla Escape los
cambios no se actualizan en la hoja de cálculo. Es un poco raro. Creo que "se me escapa"
algo, si alguien descubre por qué ocurre esto que me avise.
Bueno, ahora vamos a añadir un control nuevo, que Excel llama "cuadro combinado" (el
nombre en inglés es ComboBox), que es la típica persiana que estamos hartos de ver en
cualquier diálogo, y permite al usuario escoger una opción entre varias que le presentamos. En
este caso vamos a mostrar una persiana para el "Estado Civil", y las opciones que vamos a
presentar son "soltero, casado, viudo y divorciado".
Rowsource: es el rango del que queremos que el ComboBox lea los elementos.
Podemos utilizar esta propiedad, o bien introducir nosotros mismos mediante código
los elementos (utilizando el método AddItem).
Style: identifica el tipo de ComboBox que queremos. Tiene dos valores posibles:
o fmStyleDropDownCombo: el usuario puede escoger uno de los valores de la
lista o escribir otro distinto.
o fmStyleDropDownList: el usuario sólo puede escoger uno de los valores de la
lista.
ControlTipText: esta propiedad se aplica a todos los controles, pero como todavía no
la he explicado, la pongo aquí. Esta propiedad sirve para mostrar al usuario un
pequeño texto de ayuda sobre el control cuando ponga el ratón sobre el mismo, el ya
clásico cuadrito amarillo.
Una vez vistas las propiedades, vamos con los métodos del objeto ComboBox:
Como siempre, hay muchos más métodos y propiedades, que están bastante bien explicados
en la ayuda de Excel.
Vamos a colocar nuestro ComboBox en el Userform, y una vez colocado vamos a las
propiedades. Primero vamos a establecer la propiedad Style como fmStyleDropDownList, para
que el usuario sólo pueda escoger uno de los valores que le presentamos (es decir, que no le
dejamos que se invente un nuevo estado civil). Ahora vamos a la hoja de cálculo y escribimos
en una celda cualquiera "Soltero", debajo "Casado", debajo "Divorciado" y debajo "Viudo".
Ahora vamos a dar un nombre a este rango, seleccionando las cuatro celdas y escribiendo en
el "Cuadro de Nombres" (en la parte superior izquierda) el nombre "rngEstadoCivil". Ya que
estamos vamos a seleccionar cualquier otra celda para que el ComboBox almacene el
elemento seleccionado por el usuario, y le damos a esta celda el nombre "rngValorEstadoCivil".
Ahora vamos otra vez al editor de Visual Basic (VBE), seleccionamos nuestro ComboBox, y en
la propiedad RowSource escribimos "rngEstadoCivil". En la propiedad ControlSource
escribimos "rngValorEstadoCivil".
Como propina, vamos a poner en la propiedad ControlTipText el texto "Selecciona tu estado
civil", que es lo que el usuario verá en un cuadrito amarillo cuando ponga el ratón sobre el
ComboBox. Recuerda que esta propiedad la tienen todos los controles.
Vamos a por otro control, el SpinButton (Botón de número). Este botón se utiliza normalmente
combinado con un Cuadro de edición: si pulsamos el SpinButton hacia arriba aumentamos el
valor del cuadro de edición, y viceversa.
Vamos a utilizar el control SpinButton combinado con un cuadro de edición que vamos a
utilizar para almacenar la edad. Primero ponemos un cuadro de edición, que llamaremos
"editEdad" (ya sabes, cambiando la propiedad Name). En una hoja de cálculo daremos el
nombre "rngEdad" a una celda, y utilizaremos esta celda para la propiedad ControlSource de
nuestro control "editEdad".
Ahora tenemos que jugar un poco con los eventos: cada vez que el usuario pulsa el SpinButton
se produce el evento Change. Cada vez que se produzca este evento queremos cambiar el
valor del cuadro de edición "editEdad". Hacemos doble-click en el SpinButton y aparece la
ventana de código, en la que escribiremos:
Bastante sencillo, ¿no? Simplemente damos a la propiedad Text del objeto "editEdad" el valor
del SpinButton.
Ahora tenemos que hacer lo mismo pero "al revés". Si el usuario va directamente al cuadro de
edición y escribe una edad, queremos que el valor del SpinButton se actualice, ya que tanto el
cuadro de edición como el SpinButton tienen que tener el mismo valor. Para ello usamos el
evento Change del objeto editEdad. Hacemos doble-click sobre él y en la ventana de código
escribimos:
Prácticamente igual que antes. El único cambio es que utilizamos la propiedad Value de
editEdad en lugar de la propiedad Text, porque queremos el valor numérico, y no la cadena de
caracteres. Si en el control de edición escribes alguna letra en lugar de un número verás que el
Userform se detiene mostrándote un mensaje de error porque no puede calcular la propiedad
Value de editEdad. En una aplicación "de verdad" deberíamos escribir algo de código para
evitar estos errores, pero todavía no hemos visto el control de errores (ya llegaremos).
Todavía nos queda un pequeño detalle respecto al SpinButton. Cuando el Userform se carga
por primera vez, el control editEdad lee de la hoja de cálculo la edad (porque se lo hemos dicho
en la propiedad ControlSource), pero el control SpinButton no está actualizado, tenemos que
darle el mismo valor que tiene el control editEdad. Para ello usaremos el evento Initialize el
Userform, que ya conocemos de sobra:
Ahora vamos con otros tipos de controles: las casillas de verificación (CheckBoxes en inglés),
y los botones de opción (OptionButtons). Para utilizarlos vamos a suponer que queremos que
el usuario nos indique si utiliza o no una hoja de cálculo, y en caso de que sí la utilice nos diga
cuál es su preferida.
Lo primero es preguntar si utiliza una hoja de cálculo, y para ello vamos a utilizar una casilla de
verificación, que puede tener el valor verdadero o falso. Como siempre colocamos el control
sobre el userform y le damos el nombre "cboxUtilizaHoja". En la propiedad ControlSource
vamos a escribir "rngUtilizarHoja", que es el nombre que hemos dado a un rango de una hoja
de cálculo (en el fichero de ejemplo es la celda C18 de la Hoja1). Y en la propiedad Caption
escribimos el texto del control, algo así como "Utiliza hoja de cálculo". También podemos
escribir algo en la propiedad ControlTipText.
TripleState: puede ser verdadero o falso (esto último por defecto). Si le damos el valor
verdadero el control tiene tres estados: verdadero, falso y nada (cuando se pone gris).
En algunas ocasiones puede ser útil pero normalmente lo dejaremos como falso.
Ahora vamos a ver cuál es la hoja de cálculo preferida del usuario. Para ello vamos a utilizar
unos botones de opción, para darle la opción de elegir entre Excel, Lotus 1-2-3 u otra hoja de
cálculo.
Lo primero que tenemos que hacer es colocar un control marco (Frame en inglés). Estos
controles sólo sirven para agrupar controles y para mejorar la presentación del userform.
También tienen sus propiedades y eventos, pero casi nunca se utilizan.
Bueno, colocamos un control Frame en el userform, y ahora vamos a poner dentro de él los
tres botones de opción. Para poner un control dentro del marco lo que hay que hacer es
seleccionar el marco y sin quitar la selección añadir el nuevo control. Vamos a hacer esto tres
veces, y añadiremos tres botones de opción dentro del marco.
Para guardar los valores de los botones de opción vamos a dar nombres a tres celdas de la
hoja de cálculo (en el ejemplo E16, E17 y E18), a las que nombraremos "rngExcel", "rngLotus"
y "rngOtros". Ahora vamos a los tres botones de opción que hemos puesto en el userform y en
la propiedad ControlSource de cada uno de ellos escribimos una de los nombres que
acabamos de crear. También convendría cambiar la propiedad Caption de cada uno de los
botones para mostrar el texto adecuado.
Las propiedades Value y TripleState de un botón de opción funcionan igual que en el control
de verificación, y el resto de propiedades no son demasiado importantes.
Lo que nos queda ahora es saber cuándo ha cambiado de estado (verdadero, falso) la casilla
de verificación cboxUtilizaHoja. Como siempre, lo hacemos con un evento, el evento Change
del control de verificación, que se ejecuta cada vez que cambia el estado del control. Por lo
tanto, en el evento Change tendremos que cambiar el estado (activado, desactivado) de los
botones de opción. El código es:
Fíjate que damos a la propiedad Enabled de los botones de opción y el marco el valor de la
propiedad Value del control de verificación. También podríamos haber escrito:
Como ejercicio, vamos a hacer otro userform, en el que no vamos a utilizar ningún control
nuevo pero sí vamos a ver un evento nuevo (KeyUp). Lo que vamos a hacer es un diálogo en
el que el usuario pueda escribir una cifra en pesetas y automáticamente le diremos cuántos
euros son. Y al revés, si escribe los euros calcularemos cuántas pesetas son.
Pues vamos al VBE, creamos un userform, y ponemos en él dos controles de edición, que
llamaremos editPesetas y editEuros, dos etiquetas al lado de cada control de edición, y un
botón para cerrar el diálogo.
Primero lo más fácil. En el botón de cerrar (al que cambiaremos el Caption para que ponga
"Cerrar", y que llamaremos btnCerrar) tenemos que poner el código para cerrar el userform:
Ahora vamos a los cuadros de edición. Lo que queremos hacer es que cada vez que el usuario
pulse una tecla se actualice el otro cuadro de edición. Por ejemplo, si el usuario va a escribir
2500 pts, nosotros actualizaremos el cuadro de edición de euros cada vez que el usuario pulse
una tecla, sin esperar a que termine. Para eso vamos a utilizar el evento KeyUp, que se
produce cada vez que el usuario pulsa una tecla.
Para escribir el código de este evento vamos a la ventana de código de nuestro userform, y en
las persianas de la parte superior seleccionamos el control editPesetas y en la parte derecha
el evento KeyUp. Excel nos habrá puesto la declaración de la rutina (con los parámetros
adecuados, que en este caso no nos interesan y vamos a ignorar) y el " End Sub"
correspondiente. Ahora sólo tenemos que poner lo del medio:
El "If" lo utilizo como una pequeña forma de detección de errores, por si el cuadro de edición
está vacío (de todas formas, se pueden producir muchos errores, como por ejemplo si el
usuario introduce una letra en lugar de un número, pero no vamos a ponernos ahora a escribir
código para detectar todos esos errores). El resto es bastante sencillo, se trata de poner en el
cuadro editEuros el importe de editPesetas dividido por 168 (el valor en pesetas de un euro),
y utilizando la función Format para que sólo presente dos decimales. (la función Format es
muy sencilla de utilizar, si quieres más información consulta la ayuda).
Podemos probar a ejecutar ahora el diálogo y veremos que cada vez que introduzcamos un
carácter en el cuadro editPesetas se actualiza el cuadro editEuros.
Ahora tenemos que hacer que cuando escribamos algo en editEuros se actualice editPesetas.
El procedimiento es exactamente el mismo:
Hasta ahora, todos los botones que hemos utilizado en los userforms servían para cerrar el
userform, con la diferencia de que solemos poner uno para Aceptar y otro para Cancelar. Pero
también podemos poner en un userform un botón que realice cualquier otra acción pero no
cierre el userform. Lo más típico es que este botón haga algún cambio sobre los controles del
userform.
En este caso, aprovechando nuestro conversor de euros, vamos a crear dos botones, uno al
lado de cada cuadro de edición, que van a pegar en la celda activa de la hoja de cálculo el
contenido del cuadro de edición asociado.
Colocamos los dos botones, uno al lado de cada cuadro de edición, y les damos los nombres
btnPegarPts y btnPegarEuros, y les ponemos como Caption algo como "Pegar". Ahora
vamos al código:
El evento que utilizamos es el evento Click, que ya conocemos de sobra. Y el código tampoco
tiene ninguna dificultad, simplemente es poner en ActiveCell el valor del control de edición,
editPesetas o editEuros.
Como verás, al pulsar estos botones se pega el contenido en la hoja de cálculo, pero no se
cierra el userform. Si quisiéramos que después de hacer el pegado se cerrara el userform
tendríamos que añadir el clásico "Unload Me" a las dos rutinas anteriores.
Y para terminar esta entrega, vamos a hacer un diálogo para hacer operaciones sobre un
rango, como los que ya hemos hecho, pero más completo. El diálogo va a permitirnos cambiar
el rango seleccionado, y luego nos permitirá seleccionar la operación aritmética que queremos
hacer sobre el rango (sumar, restar, multiplicar, dividir) utilizando para ello unos botones de
opción.
En este diálogo vamos a utilizar un control nuevo, el RefEdit, que sirve para que el usuario
pueda introducir una referencia (un rango). Puede hacerlo escribiendo la referencia absoluta o
el nombre del rango (como si fuese un cuadro de edición), o pulsando en el botoncito que
aparece a la derecha, que hace que desaparezca el userform y el usuario puede seleccionar el
rango con el ratón o el teclado.
Lo único nuevo que tenemos que aprender es que el rango que el usuario ha introducido en el
RefEdit se guarda en la propiedad Text. Pero Text es una cadena de caracteres, por lo que si
queremos hacer referencia al rango deberemos usar Range(RefEdit1.Text).
Primero hacemos que la operación seleccionada por defecto sea sumar (alguna tiene que ser)
y que en el RefEdit aparezca como rango la selección que tenía hecha el usuario antes de
llamar al diálogo.
Sub HacerOperacion()
Dim r As Range
Dim c As Object
Dim i As Double
Set r = Range(RefEdit1.Text)
i = tbValor.Value
For Each c In r.Cells
If obSumar.Value = True Then
c.Value = c.Value + i
ElseIf obRestar.Value = True Then
c.Value = c.Value - i
ElseIf obMultiplicar.Value = True Then
c.Value = c.Value * i
ElseIf obDividir.Value = True Then
c.Value = c.Value / i
End If
Next c
End Sub
Y aquí termina la cuarta entrega del curso. Si tienes cualquier duda o comentario que hacer, no
dudes en contactar conmigo. En la próxima entrega hablaremos de la creación de menús y
barras de herramientas personalizadas.
Excel4.xls
Recuerda que los ejemplos de este capítulo están incluídos en este fichero:
(116kbs)
Excel5.xls
Todos los ejemplos de este capítulo están incluídos en este fichero:
(90kbs)
Antes de nada, vamos a intentar aclarar la nomenclatura que se utiliza en VBA para hacer
referencia a cada una de las partes de un menu.
El nombre del menu en
sí mismo es
CommandBar. Un
CommandBar (barra de
menú) representa a todo
el menú, como por
ejemplo el que aparece
cuando estás en una
hoja de cálculo. Si
cambias a una hoja de
gráfico verás que el
menú cambia: se ha
cambiado de barra de
menú (CommandBar).
Dentro del menú desplegable, cada una de las opciones se llama ControlButton (opción de
menú). Por ejemplo, "nuevo" y "Guardar" son opciones del menú desplegable "archivo" de la
barra de menú de "Hoja de cálculo" de Excel.
Para tener acceso a las barras de comandos (que pueden ser menús o barras de herramientas)
utilizaremos la propiedad CommandBars, que devuelve el conjunto de barras de comandos de
la aplicación. Cada una de las barras de comando será por tanto un objeto CommandBar.
Por ejemplo, para ver los nombres de todas las barras de comando que existen escribiremos la
siguiente rutina:
Sub ListaBarrasComando()
Dim h as Object
Dim dst as Range
De esta forma obtendremos el nombre de todas las barras de comando. Recuerda que puede
haber barras de comando que existan pero no estén activas, que no aparezcan en la pantalla.
Como habrás podido deducir, la propiedad Name de un objeto CommandBar nos devuelve el
nombre de la barra de comando.
La primera variable (cBar) la utilizaremos para almacenar el menú de hoja de cálculo entero, la
segunda (cBarPopUp) para obtener el menú de "Edición" dentro de cBar, y la tercera para crear
nuestra opción (Macedonia) dentro del menú de Edición.
Con esto hemos conseguido que nuestra variable, cBar, contenga la barra de comandos que
nos interesa. Ahora queremos seleccionar una parte de ese barra de comandos: queremos el
menú de Edición. Para ello utilizamos el siguiente código:
Hemos utilizado la propiedad "Controls" del objeto CommandBar. Esta propiedad nos permite
acceder a todos los submenús de una barra de comandos. El objeto devuelto es del tipo
"CommandBarPopup". Reconozco que la terminología es un poco confusa, pero así lo ha
hecho Microsoft.
Almacenamos en nuestra variable cButton el resultado, porque luego queremos hacerle unos
cambios.
Nos queda hacer que nuestra opción de menú (o ControlButton), tenga el texto que nosotros
queremos y haga lo que nosotros queremos. Para ello utilizaremos las propiedades del
ControlButton:
Caption: es el texto que queremos que aparezca en la opción de menú. En nuestro
caso, "&Macedonia". El carácter "&" se utiliza para indicar que la letra que le sigue (la
"M" en este caso) queremos que apareza subrayada y funcione como tecla rápida una
vez que esté abierto el menú.
OnAction: es el nombre de la rutina que queremos que se ejecute cuando el usuario
seleccione esa opción. En este caso vamos a darle el valor "MiMacro", que será una
pequeña rutina que simplemente avisará de que hemos seleccionado esa opción.
ShortcutText: el texto que aparece en la opción del menú, a la derecha. Normalmente
se suele poner la tecla rápida para esa opción de menú. Cuidado, porque esta opción
sólo sirve para escribir el texto, pero no hace que la tecla rápida funcione, eso tendrás
que hacerlo tú por otro lado.
FaceID: es el número de la imagen que queremos que se asigne a nuestra opción de
menú. La imagen aparece en la parte izquierda de la opción. Excel tiene un montón de
imágenes para nuestras opciones, y se pueden seleccionar cambiando el ID. Para ver
todas las imágenes disponibles y saber qué ID corresponde a cada imagen, lo mejor es
hacer una pequeña rutina que muestre todas las imágenes. (eso te queda como
ejercicio; si tienes alguna duda escríbeme).
BeginGroup: true o false, indica si queremos que antes de nuestra opción se ponga un
"separador", una línea que separe un poco nuestra opción de la anterior.
Como siempre, hay muchas más propiedades, pero creo que hemos visto las más importantes.
Vamos a ver nuestra rutina completa:
Sub CrearOpcionMenu()
Dim cBar As Object
Dim cBarPopUp As Object
Dim cButton As Object
BorrarOpcionMenu
Set cBar = CommandBars("Worksheet Menu Bar")
Set cBarPopUp = cBar.Controls("Edición")
Set cButton = cBarPopUp.Controls.Add(msoControlButton)
With cButton
.Caption = "&Macedonia"
.OnAction = "MiMacro"
.FaceId = 7
.ShortcutText = "Ctrl+Shift+M"
.BeginGroup = True
End With
Call MsgBox("Se ha creado la opción 'Macedonia' en el menú 'Edición'", vbOKOnly,
"Macedonia")
End Sub
Para verla en acción abre el fichero de ejemplo, y utiliza el botón "Crear opción de menú".
Sub BorrarOpcionMenu()
Dim cBar As Object
Dim cBarPopUp As Object
Dim cc As Object
Ahora vamos a crear un menú desplegable (como el menú Archivo, o Edición, de la hoja de
cálculo de Excel). Como siempre, primero declaramos las variables que vamos a utilizar.
Para añadir un menú desplegable a dicha barra de comandos vamos a utilizar el método "Add"
de la colección "Controls" de la barra de comandos:
El tipo de control que queremos añadir es un "msoControlPopup", para indicar que queremos
un menú desplegable.
cBarPopUp.Caption = "&Macedonia"
Ahora tenemos en cBarPopUp un menú desplegable, igual que en el punto anterior teníamos el
menú desplegable "Edición". Ahora tenemos que añadir opciones en dicho menú desplagable,
igual que hemos hecho antes:
También podemos añadir un submenú dentro de alguna opción de nuestro menú, de una forma
muy parecida. La rutina completa para crear un menú desplegable es la siguiente:
Sub CrearMenuDesplegable()
Dim cBar As Object
Dim cBarPopUp As Object
Dim cButton As Object
Dim i, j As Integer
BorrarMenuDesplegable
Set cBar = CommandBars("Worksheet Menu Bar")
Set cBarPopUp = cBar.Controls.Add(Type:=msoControlPopup, _
Before:=10)
cBarPopUp.Caption = "&Macedonia"
For i = 1 To 10
If i <> 5 Then
Set cButton = cBarPopUp.Controls.Add(msoControlButton)
With cButton
.Caption = "&Macedonia " & i
.OnAction = "MiMacro"
If i Mod 3 = 0 Then .BeginGroup = True
End With
Else
Set cButton = cBarPopUp.Controls.Add(msoControlPopup)
cButton.Caption = "&Macedonia " & i
For j = 1 To 5
With cButton.Controls.Add(msoControlButton)
.Caption = "Submenú Macedonia " & j
.OnAction = "MiMacro"
If j Mod 3 = 0 Then .BeginGroup = True
End With
Next j
End If
Next i
Call MsgBox("Se ha añadido la opción 'Macedonia' en el menú principal", _
vbOKOnly, "Macedonia")
End Sub
Para ver esta rutina en acción utiliza el botón "Crear menú desplegable" del fichero de ejemplo.
Ahora vamos a crear una barra de menú completa, como la barra de menú "Worksheet Menu
Bar". Lo primero, como siempre, es declarar las variables:
En lugar de obtener la barra de menú "Worksheet Menu Bar" y luego trabajar con ella, ahora lo
que vamos a hacer es crear nosotros mismos una barra de menú, utilizando el método "Add"
de la colección "CommandBars".
El tercer argumento (verdadero o falso) indica si queremos que la nueva barra de menú
reemplace a la barra de menús activa o no.
Una vez que tenemos nuestra barra de menú utilizamos el código que hemos aprendido antes
para crear los menús desplegables y sus opciones. La siguiente rutina crea una barra de menú
y varios menús desplegables y opciones:
Private Const NOMBREMENU = "Menú Macedonia"
Sub CrearBarraMenu()
Dim cBar As Object
Dim cBarPopUp As Object
Dim cButton As Object
Dim i, j As Integer
BorrarBarraMenu
Set cBar = CommandBars.Add(NOMBREMENU, msoBarTop, True)
For j = 1 To 5
Set cBarPopUp = cBar.Controls.Add(Type:=msoControlPopup)
cBarPopUp.Caption = "&Macedonia " & j
For i = 1 To j + 2
Set cButton = cBarPopUp.Controls.Add(msoControlButton)
With cButton
.Caption = "&Macedonia " & i
.OnAction = "MiMacro"
If i Mod 3 = 0 Then .BeginGroup = True
End With
Next i
Next j
Call MsgBox("Se ha creado la barra de menú 'Macedonia'.", vbOKOnly, "Macedonia")
End Sub
Hemos utilizado la variable "NOMBREMENU" para dar el nombre a la barra de menú. Cuando
se usa una cadena en más de un sitio del código es aconsejable sustituir la cadena por una
variable, para evitar errores al escribir la cadena en varios sitios.
Con la rutina anterior hemos creado la barra de menú, pero todavía no la podemos ver, porque
hay que activarla, usando:
CommandBars(NOMBREMENU).Visible = True
Como al crear la barra hemos indicado (con el tercer argumento) que esta barra tiene que
sustituir a la que esta activa, la barra activa desaparece y la nuestra aparece. Para volver a
desactivar nuestra barra, utilizaremos:
CommandBars(NOMBREMENU).Visible = False
Si queremos borrar la barra de menu que hemos creado utilizaremos el metodo Delete:
CommandBars(NOMBREMENU).Delete
En el fichero excel5.xls tienes unos botones que sirven para crear, activar, desactivar y borrar
una barra de menú.
Como hemos visto al principio, en VBA las barras de menú y las barras de herramientas están
representadas por el mismo objeto (CommandBar), y su funcionamiento es prácticamente igual.
Crear una barra de herramientas es exactamente igual que crear una barra de menú:
Ahora vamos a crear un botón de la barra de herramientas. La única diferencia entre crear un
botón y crear un menú desplegable es el tipo de control, el parámetro del método Add. En este
caso utilizaremos "msoControlButton":
El código utilizado para crear, activar, desactivar y borrar una barra de herramientas es el
mismo que para una barra de menús. De hecho no hay ninguna diferencia entre ellas, en Excel
las dos son una barra de comandos (CommandBar). Además, también podemos mezclar
botones y menús dentro de una barra de comandos: sólo hay que crear la barra y luego añadir
controles tipo "msoControlPopup" para los menús y controles "msoControlButton" para los
botones.
Bueno, aquí termina la quinta entrega del curso de VBA para Excel. Si tienes cualquier duda o
comentario no dudes en escribirme.
Excel5.xls
Recuerda que los ejemplos de este capítulo están incluídos en este fichero:
(90kbs)