Está en la página 1de 33

Captulo 1.

Introduccin y primeros pasos Este curso va dirigido a aprender a programar en Visual Basic for Applications (VBA) para la hoja de clculo 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. Adems el VBA es tambin muy similar al Visual Basic de verdad, por lo que puede ser una puerta de acceso a la programacin de aplicaciones (utilizando Visual Basic) para personas sin conocimientos previos de programacin. Desde los primeros tiempos de las hojas de clculo, con las mticas primeras versiones de Lotus 1-2-3, existan macros (el nombre completo era macro-comandos), que servan para automatizar tareas repetitivas. En aquellos tiempos las macros se limitaban bsicamente 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 permita hacer cosas interesantes. Con el tiempo las macros fueron evolucionando, pudindose incluir en ellas sentencias que no se traducan en pulsaciones de teclas, aunque todo ello se haca introduciendo frmulas en las celdas de la hoja de clculo, 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 aade a las mismas unas posibilidades enormes de personalizacin y creacin de soluciones a medida de las necesidades de cada usuario. De hecho, creo que el nombre "macro" debera dejar de utilizarse en favor de otros conceptos ms relacionados con los lenguajes de programacin (como rutinas, subrutinas y funciones), pero yo creo que se mantiene por razones histricas. Lo primero que tuve que decidir antes de escribir este curso sobre programacin en Excel fue hacia quin iba a ir dirigido: por un lado estn todas las personas que dominan uno o ms lenguajes de programacin, y con poco esfuerzo pueden aprender los detalles especficos de Visual Basic for Applications para Excel. Por otro lado estn todas aquellas personas que utilizan Excel simplemente como una hoja de clculo que hace operaciones aritmticas, 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 estn en el primer grupo pueden tambin utilizar el curso, detenindose en las partes que expliquen cosas especficas de Excel y saltndose otras como los conceptos generales de programacin. Una nota sobre versiones de Excel: la ltima versin de Excel es la de Office 97 (llamada Excel 97), aunque todava existen muchos sitios en los que se utiliza la versin 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 mtodo para aprender VBA es utilizar la opcin 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 opcin para crear nuestra primera macro. Primero selecciona la opcin "Herramientas, Grabar Macro", y escribe algo en la celda A1. Luego selecciona la opcin "Herramientas, Grabar macro..., Detener grabacin" para que Excel debe de grabar. Para ver la macro que acabamos de crear el mtodo es distinto en Excel 95 y Excel 97: en Excel 95, las macros se almacenan en mdulos, que son como una hoja ms del libro, podemos ver una hoja llamada "Mdulo1" en las pestaas que estn en la parte inferior. En Excel 97, para escribir macros se utiliza el Visual Basic Editor, y accedemos a l mediante la opcin 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 opcin de que cuando pulsas "Intro" el cursor se desplaza a la celda de abajo, y Excel tambin ha incluido eso en la macro). Vamos a ir poco a poco. La primera lnea 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 lnea, una explicacin 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 clculo se utiliza el

Curso Visual Basic para Aplicaciones

1 de 33

objeto Range, o para representar una hoja de clculo 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 "mtodos". Una propiedad es un atributo del objeto que define una caracterstica del mismo. Por ejemplo, la propiedad "Row" del objeto "ActiveCell" nos indica en qu fila de la hoja de clculo 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 "mtodos" son acciones que se pueden llevar a cabo sobre un objeto, son rutinas que se aplican sobre el objeto. Para llamar a un mtodo se utiliza el nombre del objeto, un punto y el nombre del mtodo. Por ejemplo, el mtodo "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 lnea asigna un valor a la propiedad "Formula" del objeto ActiveCell. En realidad no es una formula sino una cadena, pero da lo mismo. Fjate en que en VBA siempre que escribamos una cadena de carcteres hay que encerrarla entre comillas dobles ("), igual que en otros lenguajes. Si dentro de una cadena queremos poner unas comillas dobles, slo tenemos que escribirlas dos veces ("en esta cadena hay unas comillas "" dobles") La tercera lnea llama al mtodo Select del rango "A2" de la hoja activa. Fjate en la forma de obtener el objeto que representa a la celda "A2", utilizando Range("A2"). La ltima lnea se encarga de indicar dnde termina la rutina. Por cada Sub que escribamos obligatoriamente tenemos que escribir un "End Sub". Ejecutar una subrutina Para ejecutar una rutina hay varios mtodos. Con la opcin "Herramientas, Macro..." Excel te lista todas las macros disponibles y puedes seleccionar la que quieras y ejecutarla. Asignar una macro a una nueva opcin del men de Herramientas. Asignar una "tecla rpida" a la macro, que se ejecutar cada vez que pulsemos esa tecla. Crear un botn y asignar a ese botn la rutina, de forma que sta se ejecutar cada vez que pulsemos el botn. Para crear un botn tenemos que mostrar la barra de herramientas de "Dilogo" (pulsa con el botn derecho sobre cualquier barra de herramientas, y en el men que aparece selecciona "Dilogo" y vers que aparece la nueva barra de herramientas). En esa barra de herramientas hay un botn que sirve para colocar botones (valga la redundancia) en nuestra hoja. Pulsa ese botn y crea el tuyo en cualquier parte de una hoja de clculo, con el tamao que quieras. Luego pulsa sobre ese botn con el botn derecho y del men contextual selecciona la opcin "Asignar macro". Vers una lista de macros disponibles, selecciona la que acabamos de crear (Macro1). Ahora cada vez que pulsemos el botn se ejecutar la macro Macro1. Mientras estamos editando una hoja de mdulos, un mtodo muy prctico de ejecutar las rutinas es situar el cursor dentro de una rutina y pulsar el botn de "Ejecutar macro" de la barra de herramientas de Visual Basic. Hay que tener cuidado con este mtodo en Excel 95, porque en algunos casos puede dar errores: por ejemplo, con este mtodo nuestra primera macro no funciona porque "ActiveCell" no existe, ya que estamos en una hoja de mdulo, por lo que Excel nos dar un mensaje de error. En Excel 97 este problema no ocurre porque no existen hojas de mdulo, sino mdulos dentro del Visual Basic Editor.

Podemos utilizar cualquiera de estos mtodos (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 seleccin a la celda de abajo. Utilizar funciones de VBA Adems de los objetos con sus mtodos y propiedades Excel tambin tiene funciones. Para llamar a una funcin simplemente hay que escribir su nombre y luego los parmetros necesarios. Por ejemplo, vamos a hacer una pequea macro que utilice la funcin MsgBox. Esta funcin sirve para presentar cuadros de dilogo con mensajes para el usuario, aunque no tenemos muchas opciones para disear el dilogo, slo se puede elegir el tipo de icono entre varios predefinidos (interrogacin, exclamacin, etc.) y unas cuantas opciones sobre los botones del cuadro de dilogo (Aceptar, Cancelar, S, No...). A pesar de todo es muy til para presentar informacin al usuario, por ejemplo cuando se ha terminado un proceso con xito, cuando ha ocurrido un error, o para pedir informacin del tipo de "Ests seguro de que quieres hacer....?", lo que hace que se una funcin bastante utilizada.

Curso Visual Basic para Aplicaciones

2 de 33

Pues nada, aqu tenemos una pequea rutina que utiliza la funcin 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 mdulo en Excel 95, o ir al editor de VB en Excel 97, y dentro de l seleccionar un mdulo. 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 dilogo con el ttulo "Mi segunda macro" y con el texto "Hola mundo", adems de un icono que indica que es un cuadro de informacin, y el botn aceptar. Hemos llamado a MsgBox, pasndole como primer parmetro el texto del cuadro de mensaje, como segundo parmetro los botones e icono que queremos que tenga y como tercer parmetro el ttulo del cuadro de dilogo. Como habrs podido observar los argumentos van separados por comas. Tambin se pueden poner ms parmetros para indicar qu fichero de ayuda queremos que se abra si el usuario pulsa F1 mientras est viendo el cuadro de dilogo. Si quieres ms informacin sobre dichos parmetros, as como una lista de todas las opciones que puedes utilizar como segundo parmetro (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 instruccin sobre la que queremos buscar la ayuda y pulsar F1. Si Excel encuentra esa palabra en el archivo de ayuda, nos mostrar la pgina de ayuda sobre ella. Otra pequea macro que utiliza MsgBox:

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 instruccin (la ayuda de Excel los llama enunciados) se utiliza para evaluar condiciones. Su forma general es: If <condicin> Then .... Else .... End If Si el resultado de la condicin es verdadero, se ejecutan las instrucciones que hay entre el If y el Else. Si es falso, se ejecutan las instrucciones que hay entre el Else y el End If. El Else no es obligatorio, o sea que si no nos interesa ejecutar nada en caso de que la condicin no sea verdadera, simplemente ponemos un End If y ya est. Volvamos a nuestra funcin: lo que hacemos es llamar a la funcin MsgBox con un texto y un parmetros (vbOkCancel) indicando los botones que queremos que tenga. Hasta aqu todo claro. Lo nico que cambia respecto al ejemplo anterior es que como hemos puesto MsgBox detrs del If, Excel nos obliga a poner los parmetros entre parntesis. Lo que hacemos despus es comprobar el valor que nos devuelve la funcin MsgBox una vez que el usuario ha cerrado el cuadro de dilogo. El usuario va a tener dos botones (Aceptar y Cancelar), y dependiendo de cul 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 estn todas los valores posibles que puede devolver MsgBox. Bueno, entendido esto supongo que el resto de la macro es fcil 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 ms.

Curso Visual Basic para Aplicaciones

3 de 33

Vamos hacer otra macro un poco ms complicada, que utilice la funcin MsgBox y las propiedades de los objetos que hemos aprendido antes:

Sub Macro4() If MsgBox("Informacin sobre la celda activa: " & Chr(13) & _ "Frmula: " & 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 lnea queremos decirle a Excel que la lnea contina, pero lo vamos a escribir debajo (por razones de legibilidad). Es decir, es como si desde el "If" de la segunda lnea hasta el "Then" de la sptima lnea estuviese todo en la misma lnea, pero si lo puesisemos en la misma lnea sera bastante difcil de leer. El carcter "&" se utiliza para concatenar dos cadenas de caracteres. Por ejemplo, la cadena "Macedonia Magazine" es igual que la cadena "Macedonia " & "Magazine". La funcin Chr() se utiliza para obtener el carcter representado por un cdigo ASCII. No es demasiado utilizada, tan slo nos interesa saber que cdigo ASCII nmero 13 representa el cambio de lnea, y en este caso lo utilizamos para empezar una nueva lnea en el texto que vamos a presentar en el cuadro de dilogo. Fjate cmo obtenemos informacin 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 frmula, y la otra tiene el valor) mientras que para dar un valor a la celda nos da lo mismo utilizar una u otra: la linea que dice ActiveCell.Value = "" puede sustituirse por ActiveCell.Formula = "", obteniendo el mismo resultado. Para ejecutar esta rutina, vamos a probar el mtodo de asignar a una tecla esta macro. Para ello vamos a Herramientas, Macro. De la lista de macros, seleccionamos sta y pulsamos el botn "Opciones...", que nos llevar a una ventana donde aparecen varias opciones para nuestra macro. En este dilogo podemos decir a Excel que ponga la macro como una opcin del menu de Herramientas, y tambin como tecla rpida. Podemos poner por ejemplo la tecla Ctrl-M. Ahora vamos a una hoja de clculo, e introducimos en cualquier celda la frmula "=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, cmo ejecutarla, unos conceptos bsicos sobre objetos y la instruccin "If-Then-Else", una de las ms utilizadas. Vamos a avanzar un poco ms, aprendiendo a utilizar otra instruccin muy til, el bucle "For", y a profundizar un poco en el uso del objeto Range, que es seguramente el ms utilizado. Despus de haber hecho el tpico programa "Hola mundo" (el primero que hemos hecho todos cuando hemos aprendido un lenguaje de programacin) vamos a hacer ahora otro clsico: vamos a pedirle al usuario que nos de un nmero y le vamos a dar la tabla de multiplicar de ese nmero. Aqu va la rutina completa, y luego la explicamos:

Sub TablaMultiplicar() Dim n, i As Integer Dim s As String Dim r As Range


Curso Visual Basic para Aplicaciones 4 de 33

s = InputBox("Tabla de multiplicar del nmero: ", "Ttulo") If s <> "" Then n = Val(s) ActiveSheet.Range("C2").Value = "Tabla de multiplicar del " & n Set r = ActiveSheet.Range("C4") For i = 0 To 10 r.Offset(i, 0).Value = i r.Offset(i, 1).Value = i * n Next i End If End Sub
Pulsa aqu para bajarte un fichero de Excel que contiene este ejemplo. Lo primero es la declaracin 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 nmeros enteros. Igualmente en las siguientes lneas 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 mdulo escribamos al principio "Options Explicit", con lo que estaremos indicando a VBA que debe comprobar que todas las variables que utilicemos estn previamente declaradas. No voy a entrar en la eterna polmica 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 difciles de localizar. En la siguiente lnea utilizamos la funcin "InputBox", que sirve para mostrar un cuadro de dilogo simple en el que el usuario puede escribir un dato. El primer parmetro es el texto descriptivo que se mostrar en el cuadro de dilogo y el segundo parmetro es el ttulo del cuadro de dilogo. El usuario puede utilizar el cuadro de edicin del dilogo para introducir el dato que le pedimos y luego pulsar Aceptar o Cancelar. Si pulsa Aceptar, la funcin InputBox devuelve una cadena de caracteres con el dato introducido por el usuario. Si pulsa Cancelar, la funcin devuelve una cadena de caracteres vaca (""). Utilizamos la funcin InputBox para que el usuario nos diga qu tabla de multiplicar quiere, y almacenamos el valor devuelto por la funcin en la variable s, que previamente hemos declarado como una variable de tipo cadena de carcteres (string). Despus de llamar a InputBox, comprobamos que variable "s" no est vaca, lo que significa que el usuario ha escrito algo en el dilogo y luego ha pulsado Aceptar. Si "s" esta vaca, la rutina termina sin hacer nada ms. Nuestro siguiente paso es obtener el nmero que ha introducido el usuario. Es importante distinguir entre nmeros y cadenas: en este momento tenemos la cadena de carcteres "s" que contiene la cadena introducida por el usuario, y como queremos hacer operaciones aritmticas necesitamos el nmero contenido en esa cadena. Por ejemplo, si el usuario ha escrito "3", la variable "s" contendr una cadena de carcteres de un solo carcter ("3"), y lo que nosotros queremos obtener es el valor numrico 3. Para ello utilizamos la funcin Val(), que dada una cadena de carcteres no da su valor numrico: p.ej: Val("3") nos devuelve 3. El resultado de la funcin Val lo almacenamos en la variable n, que previamente hemos declarado como variable de tipo entero. 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 nmeros. En una macro ms profesional deberamos comprobar esas posibilidades para asegurarnos de que nuestra macro no sufre ningn error en caso de que el usuario introduzca algn dato inesperado, pero por ahora no vamos a meternos en los de esos. La siguiente lnea debera ser fcil 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 pequea recomendacin: siempre que hagas referencia a rangos de hojas de clculo 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 "Ttulo tabla" y acceder a ella utilizando Range("Ttulo tabla"). La ventaja de esto es que si luego queremos que en lugar de en la celda C2 lo escriba en cualquier otra celda slo tenemos que cambiar el nombre, sin tocar el cdigo.

Curso Visual Basic para Aplicaciones

5 de 33

En la siguiente lnea 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 ms 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 cdigo comprendido entre las lneas For y Next. Es decir, las dos lneas 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 programacin. Las dos lneas que hay entre el For y el Next son prcticamente iguales. El mtodo "Offset" es un mtodo que se aplica a los objetos de tipo Range (como nuestra variable "r") para desplazar el rango al que apunta. El primer parmetro del mtodo Offset es el nmero de filas que queremos desplazar el rango (positivo hacia abajo, negativo hacia arriba), y el segundo parmetro es el nmero de columnas que queremos desplazar el rango. Vamos a verlo con un ejemplo: si nuestra variable "r" apunta al rango C4: r.Value = 1 r.Offset(1,0).Value = 2 r.Offset(-1,0).Value = 3 r.Offset(0,1).Value = 4 r.Offset(-1,-1).Value = 5 Pone el valor 1 en la celda C4 Pone el valor 2 en la celda C5 Pone el valor 3 en la celda C3 Pone el valor 4 en la celda D4 Pone el valor 5 en la celda B3

Las dos lneas de nuestra rutina lo que hacen es crear una tabla de dos columnas, poniendo en la primera columna los nmeros del 0 al 10 (es decir, los valores que va tomando i cada vez que se ejecutan estas dos lneas) y en la segunda columna el resultado de multiplicar el valor de i por el nmero 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 ms sencilla y rpida sin utilizar macros, utilizando tan slo funciones de hoja de clculo, pero nos ha servido como ejemplo sencillo para aprender algunas cosas ms 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. Tambin es muy til consultar a menudo la ayuda de Excel, que es bastante completa. Espero que alguno de los que habis llegado hasta aqu me escribis dicindome qu os ha parecido.

Curso Visual Basic para Aplicaciones

6 de 33

Captulo 2. Celdas, rangos, libros y hojas. En este captulo vamos a aprender un poco ms sobre cmo hacer referencia a celdas, rangos, hojas y libros. Supongo que todos estos conceptos estn claros, que todo el mundo sabe lo que es una celda o un rango, o la diferencia entre un libro y una hoja. Bueno, para entrar en calor vamos a hacer una pequea rutina que pida al usuario un valor y luego sume ese valor a la celda activa.

Sub Sumar_A_Celda() Dim i As Double If MsgBox("Esta macro pide al usuario un valor y lo suma a la celda activa.", _ vbOK, "Sumar a celda") = vbCancel Then Exit Sub i = Val(InputBox("Importe a sumar: ", "Sumar a celda activa")) ActiveCell.Value = ActiveCell.Value + i End Sub La primera lnea es la declaracin de la variable "i". Ya hemos comentado anteriormente lo que es la declaracin de variables, lo nico nuevo es el tipo de variable (double). Cuando declaramos una variable hay que indicar qu tipo de variable queremos que sea. Los tipos de variables ms importantes son: Integer Long Boolean Single Double String Date Object Variant Un valor entero, entre -32.768 y 32.767 Un valor entero, entre -2.147.483.648 y 2.147.483.647 Verdadero y Falso Un valor con decimales, con precisin simple Un valor con decimales, con precisin doble Un cadena de caracteres Una fecha Referencia a cualquier tipo de objeto de Excel Un variable que puede cambiar de tipo

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 pequeo mensaje diciendo lo que vamos a hacer. Esto est explicado en la entrega anterior, no creo que necesite nada ms. Si el usuario pulsa "Cancelar", salimos de la rutina y no hacemos nada. En la siguiente lnea obtenemos del usuario el valor que quiere sumar a la celda activa. La funcin 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 numrico, utilizamos la funcin Val() para convertir la cadena de caracteres proveniente de InputBox en un nmero. Lo ponemos todo en la misma lnea, pero tambin se poda haber escrito en dos lneas:

Dim s as String s = InputBox("Importe a sumar: ", "Sumar a celda activa") i = Val(s)


Bueno, seguramente queda ms 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. La ltima lnea es la que hace realmente la suma, dando valor a la propiedad Value de ActiveCell. Ya hemos visto en la entrega anterior lo que es ActiveCell. Una aclaracin sobre ActiveCell y ActiveSheet (que tambin vimos en la entrega anterior): en realidad, ActiveCell no es un objeto, sino que es una "propiedad" de un objeto especial llamado

Curso Visual Basic para Aplicaciones

7 de 33

Application, pero cuando escribimos "ActiveCell" Excel entiende que estamos escribiendo "Application.ActiveCell". Application es un objeto que representa la aplicacin Excel completa. A travs de Application se puede acceder a todas las opciones de la aplicacin (las que podemos cambiar a travs de Herramientas, Opciones), acceder a las funciones de hoja de clculo (SUMA, PROMEDIO, etc) y tambin podemos obtener objetos que referencian a la celda activa (ActiveCell), la hoja activa (ActiveSheet), el libro activo (ActiveWorkbook), etc. Un pequeo 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 cdigo: Para ocultar la barra de estado:

Application.DisplayStatusBar = False
Para volver a mostrar la barra de estado:

Application.DisplayStatusBar = True
El objeto Application tiene un montn de propiedades y mtodos, que estn muy bien explicados en la ayuda de Excel, y su uso es bastante sencillo. Siguiendo con la ltima lnea de la rutina, podrs comprobar que utilizamos la propiedad Value de ActiveCell. Si hubisemos utilizado la propiedad Formula en lugar de Value, la rutina tendra 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 vers que no hay ninguna frmula; la suma la ha hecho nuestra rutina, y ha puesto en la celda el resultado de dicha suma. Sin embargo, si queremos que la frmula de la suma quede en la celda debemos usar la propiedad Formula. La propiedad Formula es una "cadena de carcteres", que incluye todo lo que se escribira normalmente en una celda de una hoja de clculo para introducir una frmula (incluyendo el signo "=" al principio). Por ejemplo, si queremos que poner en la celda A2 una frmula 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 frmula tal como lo haramos en la hoja de clculo. Tras esta explicacin, si queremos cambiar nuestra rutina para introducir la fmula de suma en la celda, nuestro primer intento sera escribir: ActiveCell.Formula = ActiveCell.Formula + i Si ejecutamos este cdigo veremos que el resultado puede variar dependiendo de lo que contenga la celda activa: Si la celda activa contiene un nmero (no una frmula), el resultado es el mismo que antes. La razn es que como no hay ninguna frmula ActiveCell.Formula devuelve un nmero, igual que ActiveCell.Value. Luego le sumamos nuestro valor y asignamos el valor resultante como frmula de la celda. Si la celda activa contiene una frmula, el resultado es que la macro se para con un error. Esto es debido a que ActiveCell.Frmula nos devuelve una cadena de caracteres (por ejemplo, la cadena "=A1*2"), y luego estamos intentando sumar un nmero (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 frmula en la celda), debemos asignar a ActiveCell.Formula una cadena de caracteres con una frmula escrita correctamente. Vamos a intentarlo: ActiveCell.Formula = ActiveCell.Formula & "+" & i El operador & ya lo vimos en la primera entrega, se utiliza para concatenar cadenas de caracteres. Partimos de la frmula que actualmente tiene la celda activa (por ejemplo, "=A1*2") y luego le aadimos un signo "+" y luego nuestro valor (i), con lo que la frmula pasar a ser "=A1*2+3" (si i tiene el valor 3). 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 frmula para decirle a Excel que es una frmula. O sea que deberamos aadir delante de la frmula un "=", lo que podemos hacer de la siguiente forma:

Curso Visual Basic para Aplicaciones

8 de 33

ActiveCell.Formula = "=" & ActiveCell.Formula & "+" & i Cul es el problema ahora? Pues que si la celda activa tiene una frmula nos encontramos con que nuestra frmula definitiva tiene dos signos "=" al principio, uno el que ya tena y otro el que le hemos puesto nosotros. El resultado es que introducimos una frmula incorrecta y Excel nos vuelve a dar un error. Bueno, creo que he montado un pequeo lo, pero en realidad no tiene ninguna dificultad. Lo que hay que hacer es comprobar si en la celda activa hay una frmula (esto se puede hacer mirando si el primer carcter es el signo "=", utilizando por ejemplo la funcin Left). Si hay una frmula, slo aadimos la parte del final, y si no hay una frmula aadimos 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 lo ya lo hemos visto todo. Si ejecutas la rutina Sumar_A_Celda() comprobars 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 ms rpido utilizando "Pegado especial..", que adems es capaz de restar, multiplicar y dividir. Ya llegaremos a eso tambin, 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 If MsgBox("Esta macro pide al usuario un valor y lo suma a todas las celdas " & _ Chr(13) & "del rango seleccionado.", vbOK, "Copiar celda izquierda") _ = vbCancel Then Exit Sub i = Val(InputBox("Importe a sumar: ", "Sumar a rango seleccionado")) For Each h In Selection.Cells h.Value = h.Value + i Next h End Sub 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 lneas son iguales que antes: primero presentamos un pequeo mensaje al usuario, y luego obtenemos el valor y convertimos la cadena a un valor numrico. En las tres siguientes lneas 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 definicin 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 instruccin "For". En la entrega anterior vimos una instruccin For, pero un poco distinta a esta. En ese caso lo que hacamos era dar a una variable distintos valores, desde el 1 hasta el 10, y para cada valor de la variable ejecutbamos unas instrucciones. Anlogamente, en esta ocasin vamos a dar a la variable "h" (de tipo Object) unos valores, y para cada valor de "h" vamos a ejecutar una instruccin.

Curso Visual Basic para Aplicaciones

9 de 33

Para dar los distintos valores a "h" vamos a utilizar la instruccin "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

For Each h In Selection.Cells h.Value = h.Value + 1 Next h


lo que hacemos es ejecutar una instruccin para cada una de las celdas del conjunto Selection.Cells. La primera vez que se ejecute la instruccin 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 instruccin que va dentro del bucle es la misma que en el ejemplo anterior; tan slo fjate que utilizamos "h" en lugar de ActiveCell. Vamos a hacer otro pequeo ejemplo del uso de "For Each" y de conjuntos. En esta ocasin 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 clculo del libro activo, utilizaremos la propiedad Worksheets de dicho objeto, ActiveWorkbook. He utilizado la propiedad Worksheets porque esta nos devuelve slo las hojas de clculo (no las hojas de grficos, mdulos, etc.). Si queremos acceder a todas las hojas (de cualquier tipo) del libro, utilizaremos la propiedad Sheets, que funciona igual que Worksheets. Aqu va la rutina de ejemplo: Sub NombresHojas() Dim h As Object Dim i As Integer 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 clculo del libro activo, ponindoles 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 declaracin de variables. Luego le damos a la variable "i" el valor 15, porque nos da la gana, podamos haberle dado cualquier otro. Luego viene lo que nos interesa, el "For Each". Para cada hoja de clculo (Worksheets) del libro activo (ActiveWorkbook) vamos a ejecutar las dos instrucciones que estn 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) Bueno, otra rutina para jugar un poco con hojas y celdas: Sub ListaHojas() Dim h As Object Dim r As Range If MsgBox("Esta macro crea en la celda activa una lista con los nombres de todas" & _ Chr(13) & "las hojas del libro activo.", vbOK, "Lista Hojas") = vbCancel _ Then Exit Sub Set r = ActiveCell For Each h In ActiveWorkbook.Sheets r.Value = h.Name

Curso Visual Basic para Aplicaciones

10 de 33

r.Offset(0, 1).Value = TypeName(h) Set r = r.Offset(1, 0) Next h End Sub Lo que hace esta rutina es crear en la hoja de clculo 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 cdigo entre estas dos lneas se ejecute una vez para cada hoja del libro. La nica diferencia es que en el ejemplo anterior utilizbamos "ActiveWorkbook.Worksheets" (que pasa por todas las hojas de "clculo" 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 lnea, ponemos en a celda de la derecha de "r" (con el Offset(0,1)) el tipo de hoja de que se trata, utilizando la funcin "TypeName(h)": esta funcin devuelve una cadena de carcteres que proporciona informacin sobre la variable "h". En la siguiente lnea, 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 mtodo Copy, que se aplica a objetos de Excel que puedan ser copiados, como por ejemplo un objeto de tipo Range, aunque tambin a otros objetos como hojas enteras o grficos. Lo que vamos a hacer es copiar en la celda activa el contenido de la celda de su izquierda: 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 mtodo 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 parmetro del mtodo 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 parmetro del mtodo Copy la copia se har en el "Portapapeles", y luego deberemos utilizar otros mtodos como "Paste" o "PasteSpecial" para pegar el contenido del portapapeles en otra celda. Hasta aqu llega esta segunda entrega del curso. En este captulo hemos aprendido a trabajar con celdas, rangos, libros y hojas, que es una de las partes ms tiles de la programacin en Excel, permitindonos hacer cualquier operacin (mover, copiar, borrar, hacer operaciones aritmticas, etc) con los datos de una hoja de clculo.

Curso Visual Basic para Aplicaciones

11 de 33

Captulo 3. Cuadros de dilogo (Userforms). Este captulo va a tratar sobre los cuadros de dilogo, que se utilizan para obtener informacin del usuario. Una aclaracin respecto a versiones: uno de los cambios ms importantes de Excel 95 a Excel 97 en el apartado de programacin es la parte de cuadros de dilogo. 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 captulo est dirigido slo a Excel 97. Los cuadros de dilogo en Office 97 son mucho ms potentes que en la versin anterior. Se han aadido muchas opciones, como la posibilidad de definir eventos, utilizar controles ActiveX adems de los incluidos en Excel (si no sabes qu es un control ActiveX no tiene demasiada importancia, es un tema avanzado que quiz algn da tratemos), etc. Nuestro primer cuadro de dilogo va a ser muy sencillo: vamos a presentar un cuadro de dilogo en el que el usuario puede introducir un nmero, y si pulsa "Aceptar" copiaremos el nmero introducido en la celda activa. Si el usuario pulsa "Cancelar" no haremos nada. Lo primero es ir al editor de Visual Basic, utilizando la opcin "Herramientas, Macro, Editor de Visual Basic", o simplemente pulsando Alt-F11. En la parte izquierda de la pantalla tendremos el "Explorador de Proyectos" y la ventana de "Propiedades". Igual que antes, si no puedes ver estas ventanas utiliza el men "Ver" para hacer que aparezcan. En el "Explorador de Proyectos" aparecen todos los "proyectos" de VBA: cada libro que tengamos abierto es un proyecto. Dentro de cada libro aparecen todas las hojas del libro y tambin los mdulos y cuadros de dilogo que crearemos ms adelante. En la ventana de "Propiedades" aparecen las propiedades del objeto que tengamos seleccionado en ese momento. Supongo que a estas alturas ya debe estar claro el concepto de "propiedad" de un objeto. Por ejemplo, vamos a ir a un proyecto de VBA en el "Explorador de Proyectos". Dentro de l veremos las hojas de clculo del libro, y vamos a seleccionar una de ellas. En la ventana de "Propiedades" van a aparecer las propiedades de la hoja seleccionada. Por ejemplo, la primera propiedad que vemos es la propiedad Name, que ya conocemos. Podemos utilizar la ventana de "Propiedades" para cambiar las propiedades del objeto seleccionado. Ahora para crear nuestro cuadro de dilogo vamos a utilizar la opcin "Insertar, Userform" (Userform es el nombre que da Excel 97 a los cuadros de dilogo). En este momento vemos en la parte derecha un cuadro de dilogo vaco, y por otro lado veremos el "Cuadro de herramientas", en el que estn todos los controles que podemos poner en el cuadro de dilogo. Si no aparece el Cuadro de Herramientas utiliza la opcin "Ver, Cuadro de herramientas" para que aparezca. Los controles del "Cuadro de herramientas" son los tpicos de cualquier cuadro de dilogo que podemos ver en cualquier aplicacin de Windows: Etiqueta: para mostrar un texto en el cuadro de dilogo. El usuario no puede editarlo. Cuadro de texto: para que el usuario introduzca un texto. Cuadro combinado: el clsico control de persiana para que el usuario seleccione una opcin entre varias. Cuadro de lista: para que el usuario seleccione una opcin de entre las que le presentamos. Casilla de verificacin: verdadero o falso Botn de opcin: tambin para que el usuario seleccione una opcin entre varias. Botn de comando: un botn normal y corriente, como los tpicos de "Aceptar" y "Cancelar" Marco: para agrupar varios controles. Su uso es bsicamente por razones estticas. Como puedes ver en el dilogo 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 pulsndolo con el ratn. 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 ms importantes son:

Curso Visual Basic para Aplicaciones

12 de 33

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 cdigo VB haga una referencia a este objeto s que se trata de un objeto UserForm. Caption: es el ttulo que el usuario ver en el cuadro de dilogo. Se puede poner cualquier texto, incluyendo espacios. BackColor: el color de fondo del cuadro de dilogo. Por defecto es el color gris que suelen tener todos los cuadros de dilogo en Windows. ForeColor: el color de primer plano, es decir, del texto que aparezca en el cuadro de dilogo. Font: el tipo de letra por defecto para el cuadro de dilogo. Este es el tipo de letra que tendrn todos los controles que insertemos en el cuadro de dilogo, pero si luego queremos cambiarlo para cualquier control puede hacerse. StartupPosition: la posicin en la que aparecer el cuadro de dilogo. Si le damos el valor "CenterScreen" el dilogo saldr en el centro de la pantalla. SpecialEffect: para cambiar un poco los bordes del cuadro de dilogo. Picture, PictureAlignment, PictureSizeMode, PictureTiling: se utilizan para poner un dibujo como fondo del cuadro de dilogo.

Hay ms propiedades, pero su uso es bastante sencillo, y consultando la ayuda encontrars la descripcin de todas las propiedades. Vamos con nuestro dilogo: lo primero es cambiarle el nombre; vamos a la ventana de Propiedades y en la propiedad Name, escribimos por ejemplo "ufPrimero". Luego en la propiedad "Caption" escribiremos "Mi primer UserForm". Las dems propiedades las dejamos como estn, aunque si quieres cambiar alguna que afecte a la presentacin del dilogo (color de fondo, efectos especiales, etc) puedes hacerlo tranquilamente. En cualquier momento puedes probar tu cuadro de dilogo seleccionndolo con el ratn y utilizando la opcin "Ejecutar, Ejecutar Sub/Userform" (o ms rpido pulsando F5 o el botn de ejecutar ). Para cerrar el dilogo tendrs que utilizar la "X" que aparece en la parte superior derecha, porque todava no hemos aadido ningn botn para cerrar el dilogo. Como hemos dicho antes, en nuestro cuadro de dilogo queremos que el usuario escriba un nmero. Para que pueda hacerlo, tendremos que poner un cuadro de texto en el dilogo. 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 edicin. Podemos utilizar el ratn para moverlo y cambiarle el tamao. Pulsando con el ratn, seleccionaremos el cuadro de edicin, y como de costumbre veremos que en la ventana de "Propiedades" aparecen todas las propiedades del objeto "Cuadro de Texto" (TextBox en ingls), entre las que se encuentran: 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 edicin, es decir, el que ha escrito el usuario. TextAlign: alineacin del texto dentro del cuadro de dilogo. 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 nmeros se suele alinear a la derecha. MultiLine: los valores posibles son verdadero y falso, indicando si queremos que el control permita al usuario escribir ms de una lnea 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

Curso Visual Basic para Aplicaciones

13 de 33

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 bsico. Bueno, ahora vamos a nuestro cuadro de dilogo. Seleccionamos nuestro cuadro de edicin, lo colocamos en una posicin 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 edicin en un dilogo al final no sabes a cul te ests refiriendo, pero como en este caso slo vamos a tener un cuadro de edicin no nos importa demasiado. Ahora vamos a la propiedad "TextAlign" y vamos a seleccionar la opcin "fmTextAlignRight" para alinear el texto a la derecha, ya que lo que queremos es que le usuario introduzca un nmero. Por ahora no vamos a hacer nada ms con este control. Si ejecutamos el cuadro de dilogo veremos que podemos introducir un valor en el cuadro de edicin que hemos creado, pero aparte de eso no podemos hacer mucho ms. Lo siguiente que vamos a hacer es poner un texto descriptivo para el cuadro de edicin. Para ello seleccionamos del "Cuadro de herramientas" el control "Etiqueta" , y pulsamos en el UserForm para crear un control del tipo etiqueta. Utilizando el ratn le podemos cambiar el tamao y moverlo, para ponerlo a la izquierda del control de edicin 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 cdigo, y no nos interesa su nombre: normalmente los controles de etiqueta se utilizan slo para poner un texto en el dilogo, y no se suelen referenciar desde el cdigo VB. La propiedad que nos interesa es "Caption", en la que escribiremos el texto que queremos que aparezca en el cuadro de dilogo, por ejemplo "Escribe un nmero:". Si colocamos bien los dos controles (utilizando por ejemplo la opcin "Formato, Alinear, Medio), ya tenemos un dilogo algo ms completo. Lo tpico en estos cuadros de dilogo 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 ms fcil. Como antes, vamos al "Cuadro de Herramientas" y seleccionamos el control "Botn de comando" . Pulsamos sobre el UserForm y hemos creado nuestro primer botn, que podemos mover y cambiar de tamao utilizando el ratn. Una vez seleccionado nuestro nuevo control podremos ver sus propiedades en la ventana de "Propiedades": Name: el nombre del control. Vamos a darle el nombre "cbCancel" (cb viene de CommandButton). Caption: el texto del botn. Lgicamente, vamos a poner "Cancelar". Cancel: puede ser verdadero o falso. Slo puede haber un control en el cuadro de dilogo con la propiedad Cancel establecida como verdadero. Si le damos a Cancel el valor verdadero, cuando se est ejecutando el cuadro de dilogo si el usuario pulsa "Escape" ser como si hubiese pulsado con el ratn sobre este botn. En este caso nos interesa que ocurra, o sea que vamos a darle el valor verdadero. Default: verdadero o falso, indica si el botn es el botn por defecto del cuadro de dilogo. Si el usuario pulsa "Enter" cuando est viendo el dilogo ser como si pulsa con el ratn sobre el botn que tenga la propiedad Default (slo puede haber uno). En este caso vamos a dejar la propiedad en False porque queremos que el botn por defecto sea el de "Aceptar", que crearemos ms adelante.

Por ahora dejamos el resto de propiedades de los botones. Bueno, hasta ahora le hemos dado a nuestro botn el nombre "cbCancel", le hemos puesto el texto "Cancelar" y hemos dado el valor "Verdadero" a la propiedad "Cancel". Si ejecutamos el cuadro de dilogo veremos que tenemos un botn muy bonito, pero que no hace absolutamente nada. Para que haga algo tenemos que meternos con un concepto muy importante de la programacin orientada a objetos, los Eventos. A estas alturas ya deberan estar claros los conceptos de Objeto, Propiedad y Mtodo. 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 mtodos (como Range.ClearContents o UserForm.Show).

Curso Visual Basic para Aplicaciones

14 de 33

Adems de propiedades y mtodos los objetos tienen tambin "eventos". He mirado en la ayuda y no he encontrado una definicin de evento, y tampoco me atrevo a dar una, pero voy a ver si puedo explicar el concepto. Imaginemos que tenemos un control, como por ejemplo el control de edicin que hemos colocado en nuestro dilogo. Cuando sucede un "evento" de los que este control "entiende", Excel llamar a una funcin con un nombre especial, siempre que hayamos definido esa funcin (si no la hemos definido, no pasa nada, el "evento" se ignora). Un ejemplo de evento es que el usuario mueva el ratn por encima de nuestro control. Cada vez que el ratn se mueve se produce un evento "MouseMove", y entonces Excel llamar a la rutina TextBox1_MouseMove( ... ), en caso de que hayamos definido esa rutina, lo que haremos en caso de que nos interese hacer algo cada vez que el ratn pase por encima de nuestro control. El nombre de la rutina es especial: primero va el nombre del control (recuerda que lo habamos dejado tal como nos lo haba puesto Excel, TextBox1), luego un carcter de subrayado ("_"), y luego el nombre del evento. Otro ejemplo de evento: queremos que el usuario introduzca un nmero en el cuadro de edicin, pero si lo probamos veremos que se puede escribir cualquier carcter que no sea un nmero. Cada vez que el usuario pulsa una tecla se produce el evento "KeyPress", que podemos utilizar para ignorar la tecla pulsada por el usuario si ste pulsa una tecla que no es un nmero. Ms adelante veremos cmo se hace. Bueno, no s si ha quedado muy claro, pero creo que con un poco de prctica espero que s. Dominar los conceptos de objeto, propiedad, mtodo y evento es muy importante, pero no slo para programacin en Visual Basic for Applications, sino que estos conceptos son bsicos en todos los lenguajes de programacin orientada a objetos (Visual Basic, Borland Delphi, Java, etc.). De hecho, si dominas esos conceptos con cuatro cosas ms podrs programar en cualquiera de esos otros lenguajes. Bueno, sigamos con los eventos. Vamos a centrarnos ahora en nuestro botn de "Cancelar". El evento ms normal para un botn es que el usuario lo pulse con el ratn (o con el teclado). Cuando esto ocurra, se generar un evento Click, y llamar a la rutina cbCancelar_Click(). (cbCancelar es el nombre que habamos dado al control, y Click es el nombre del evento). Lo ms fcil para crear un evento es seleccionar un control y luego pulsar el botn derecho y seleccionar la opcin "Ver Cdigo". Veremos una pgina de cdigo VB en la que Excel habr escrito la cabecera de un evento para dicho control (la verdad es que no s cul de los eventos coge, supongo que coger el ms utilizado). En nuestro caso, si pulsamos sobre el botn "Cancelar" con el botn derecho y luego "Ver cdigo" en la pgina de cdigo veremos lo siguiente:

Private Sub cbCancelar_Click() End Sub


Excel nos ha creado la cabecera para la funcin que queremos crear. En este caso la funcin no tiene ningn parmetro, pero en otros eventos la funcin tiene una lista de parmetros, y Excel tambin nos los pone en la cabecera. Otra cosa, la pgina de cdigo que estamos viendo es como un mdulo normal en el que escribimos nuestro cdigo, con la particularidad de que no sale en la lista de mdulos en el "Explorador de Proyectos", ya que es un mdulo asociado al Userform. Para crear una funcin para cualquier otro evento tenemos en la parte superior de la ventana de cdigo dos "persianas". En la persiana de la izquierda tenemos el objeto sobre el que queremos definir una funcin 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 funcin para otro evento lo nico que tenemos que hacer es seleccionar otro evento en esta persiana, y Excel insertar en el cdigo la cabecera para la funcin que se va a ejecutar cuando se de ese evento. Bueno, lo que queremos hacer cuando el usuario pulsa el botn de Cancelar es simplemente cerrar el cuadro de dilogo. Tendremos que cerrar el cuadro de dilogo cuando Excel nos avise de que ha ocurrido un evento Click, es decir, dentro de la funcin cbCancelar_Click(). La instruccin que se utiliza para cerrar el UserForm es "Unload", que sirve para quitar un objeto de la memoria. La instruccin Unload requiere un parmetro, que utilizaremos para indicarle cul es el objeto. En nuestro caso utilizaremos la palabra clave "Me", que apunta al objeto en el que se est ejecutando el cdigo, es decir, nuestro UserForm.

Curso Visual Basic para Aplicaciones

15 de 33

Nuestro "manejador de eventos" para el evento Click del botn cbCancel quedara as:

Private Sub cbCancelar_Click() Unload Me End Sub


Cuando el usuario pulse el botn de Cancelar se generar un evento Click, y Excel llamar a nuestra funcin, que utilizar la instruccin Unload para cerrar el dilogo. Fjate en que si pulsas la tecla "Escape" el dilogo se cierra igual que si hubieses pulsado con el ratn sobre el botn: esto es debido a que hemos dado el valor verdadero a la propiedad "Cancel" del botn Cancelar. Despus de probar el cuadro de dilogo y comprobar que nuestro botn de Cancelar funciona perfectamente nos queda aadir el botn de Aceptar. Para crear el botn seleccionamos en el "Cuadro de Herramientas" el "Botn de comando" y lo colocamos en el UserForm. Luego le ponemos su nombre (cbAceptar por ejemplo), cambiamos su texto (ponemos Aceptar) y le damos el valor "Verdadero" a la propiedad Default para que si el usuario pulsa Enter sea como si hubiese pulsado con el ratn sobre el botn. Ahora nos queda todo el tema de los eventos. El procedimiento es el mismo que con el botn de Cancelar, con la nica diferencia de que antes de cerrar el cuadro de dilogo (con la instruccin Unload) deberemos hacer lo que queremos que nuestro dilogo haga, es decir, copiar el contenido del cuadro de edicin TextBox1. La funcin sera la siguiente:

Private Sub cbAceptar_Click() ActiveCell.Value = TextBox1.Value Unload Me End Sub


Esta funcin es prcticamente igual que la que hemos escrito para el botn Cancelar, con la excepcin de que antes de cerrar el cuadro de dilogo escribimos otra lnea, que se encarga de copiar en la celda activa (ActiveCell) el contenido del cuadro de edicin. Fjate como accedemos al contenido del cuadro de edicin, a travs del nombre del control (TextBox1) y su propiedad Value, que nos devuelve el valor numrico de lo que se ha introducido en el control (si hay caracteres no numricos la propiedad Value nos devolver el valor 0). Si probamos ahora el cuadro de dilogo veremos que ya funciona perfectamente, ya hemos conseguido que nuestro primer UserForm funcione. El nico problema que tiene es que en el cuadro de edicin el usuario puede escribir cualquier caracter adems de nmeros. Para evitar esto ya he adelantado antes que hay que utilizar el evento KeyPress del cuadro de edicin, pero eso lo veremos ms adelante. - El segundo cuadro de dilogo. Vamos a hacer otro cuadro de dilogo: tenemos en una hoja de clculo una celda con el nombre de una persona y otra celda con el apellido. Queremos crear un Userform que permita al usuario editar ese nombre y apellido, y si pulsa Aceptar en el cuadro de dilogo los valores de esas celdas deben actualizarse con lo introducido por el usuario. Si te fijas en el fichero de ejemplo vers las dos celdas que incluyen el nombre y el apellido. A estas celdas les he dado el nombre "rngNombre" y "rngApellido", respectivamente. Cuando hagamos referencias a celdas de hojas de clculo en nuestro cdigo es muy conveniente utilizar nombres de rangos en lugar de referencias absolutas (como por ejemplo C12), ya que si

Curso Visual Basic para Aplicaciones

16 de 33

utilizamos nombres de rangos y movemos esas celdas no tenemos que hacer ningn cambio en el cdigo, lo que deberemos hacer si utilizamos referencias absolutas. Repetimos los pasos anteriores: Crear el UserForm, utilizando "Insertar, Userform" en el editor de Visual Basic. Vamos a dar al UserForm el nombre "ufDatosPersonales" Insertamos dos cuadros de texto, uno para el nombre y otro para el apellido, a los que daremos los nombres tbNombre y tbApellido. Insertamos dos etiquetas que colocaremos a la izquierda de cada uno de los dos cuadros de texto. Insertamos un botn para Cancelar el cuadro de dilogo, al que cambiaremos el nombre a "cbCancelar", el texto a "Cancelar" (utilizando la propiedad Caption") y daremos a la propiedad Cancel el valor Verdadero. Insertamos un botn para Aceptar, cambindole el nombre a "cbAceptar", el texto a "Aceptar" y damos a la propiedad Default el valor Verdadero.

Vamos con los eventos: para el botn Cancelar la funcin que debemos escribir es exactamente igual que en el caso anterior:

Private Sub cbCancelar_Click() Unload Me End Sub


Lo nico que hace es cerrar el cuadro de dilogo al producirse el evento "Click" del botn Cancelar. La funcin para el botn Aceptar tambin es muy similar a la anterior:

Private Sub cbAceptar_Click() Range("rngNombre").Value = tbNombre.Text Range("RngApellido").Value = tbApellido.Text Unload Me End Sub
Esta funcin se ejecuta tambin cuando se produce el evento Click del botn llamado cbAceptar. Antes de cerrar el cuadro de dilogo debemos guardar en las celdas de la hoja de clculo 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 utilizacin de una propiedad de los objetos TextBox (tbNombre y tbApellido). Si ejecutamos ahora el cuadro de dilogo veremos que funciona perfectamente: si cambiamos los nombres en el UserForm y pulsamos Aceptar veremos que las celdas de la hoja de clculo han cambiado y ahora contienen los nuevos nombres. Pero hay una pequea opcin que se nos ha escapado: si vamos directamente a la hoja de clculo, cambiamos los nombres en sus celdas, y ejecutamos el Userform, veremos que los controles de edicin no tienen ahora los nombres actualizados, ya que no recogen los cambios que hemos hecho nosotros directamente en la hoja de clculo. Para eso vamos a utilizar tambin los eventos. En esta ocasin vamos a utilizar un evento del Userform (s, los UserForms tambin 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 botn derecho y luego la opcin "Ver cdigo" (tambin 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 funcin:

Private Sub UserForm_Initialize() End Sub


Curso Visual Basic para Aplicaciones 17 de 33

Ahora tenemos que escribir el cdigo 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 cdigo:

Private Sub UserForm_Initialize() tbNombre.Text = Range("rngNombre").Value tbApellido.Text = Range("rngApellido").Value End Sub


No creo que tenga demasiada dificultad. Es lo mismo que hemos escrito para el botn Aceptar pero al revs, es decir, damos a los cuadros de texto del Userform el valor que tienen las celdas de la hoja de clculo. Pues ya est, ahora s que el cuadro de dilogo funciona perfectamente, tanto si hacemos los cambios en el UserForm (se actualizar la hoja de clculo si pulsamos Aceptar) como si hacemos los cambios en la hoja de clculo (se actualizar el UserForm antes de aparecer en pantalla, porque se habr ocurrido un evento Initialize). Bueno, hasta aqu llega esta tercera entrega. Todava nos queda mucho por ver sobre los cuadros de dilogo (o UserForms, o formularios, como prefieras), pero eso lo dejamos para la prxima entrega. Hasta entonces te toca practicar, y sobre todo recuerda que lo ms importante es tener claros los conceptos importantes: objetos, propiedades, mtodos y eventos.

Curso Visual Basic para Aplicaciones

18 de 33

Captulo 4. Cuadros de dilogo (Userforms). Segunda parte. Seguimos con los UserForms y los controles. En esta entrega vamos a ampliar el dilogo sobre datos personales, aadindole ms 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 ms completo). Primero vamos a volver a hacer un dilogo de "Datos Personales" como el de la entrega anterior, pero aadiendo algunas cosas. Partimos del userform de la entrega anterior, que tena un cuadro de edicin para el nombre y otro para el apellido, y los dos botones clsicos (Aceptar y Cancelar). Habamos escrito el cdigo necesario para que al abrirse el dilogo (evento Initialize del Userform) los cuadros de edicin se llenen con el texto de las celdas de la hoja de clculo, y tambin para que cuando el usuario pulse Aceptar (evento Click del botn) se copie el texto de los cuadros de edicin a la hoja de clculo. Para hacer estos traspasos entre la hoja de clculo y el Userform habamos escrito un par de lneas de cdigo en los eventos indicados, pero vamos a ver que hay otro mtodo para hacerlo: Todos los controles tienen la propiedad "ControlSource", que se utiliza para decirle al control cul es la "fuente" de su informacin, que ser una celda o un rango de una hoja de clculo. Por ejemplo, en el cuadro de edicin del Nombre podemos poner como ControlSource la celda de la hoja de clculo 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 clculo y damos a la celda "fuente" el nombre "rngNombre" (rng porque es un rango de una hoja de clculo). Luego vamos al editor VBE, seleccionamos el control de edicin 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 clculo y luego escribimos rngApellido en la propiedad ControlSource del control de edicin de Apellido. Ahora tenemos que borrar el cdigo que habamos escrito para pasar la informacin de hoja de clculo 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 lnea detrs 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 ms recordar la importancia que tiene aadir al cdigo todos los comentarios que sean necesarios. Cuando ests escribiendo una rutina sabes perfectamente cmo 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 montn de lneas que no sabes para qu sirven ni cmo lo hacen, y si no las has comentado tienes que "bucear" en ellas para averiguarlo. A lo que bamos, estbamos borrando el cdigo de los eventos Initialize del Userform y Click del botn 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 lneas que se encargan de copiar los datos de la hoja de clculo al userform, y veremos que dichas lneas cambian de color, indicndonos que para Excel son comentarios y los va a ignorar. Ahora volvemos al Userform y hacemos doble-click en el botn Aceptar, y nos aparece la rutina btnAceptar_Click(). Volvemos a poner las comillas en las dos lneas de cdigo que queremos quitar y ya est. Si probamos ahora el dilogo, veremos que la propieda ControlSource funciona, y que antes de mostrar el dilogo "lee" el contenido de la hoja de clculo y lo pone en el Userform, y cuando pulsamos Aceptar copia el contenido de los controles del Userform en la hoja de clculo. Sin embargo he detectado un problema con el uso de ControlSource. Si hacemos algn cambio en el Userform y luego pulsamos el botn de "Cancelar", los cambios que hemos hecho en los datos se actualizan en la hoja de clculo, cuando no deberan actualizarse porque hemos pulsado Cancelar. En cambio, si hacemos algn cambio y pulsamos la tecla Escape los cambios no se actualizan en la hoja de clculo. Es un poco raro. Creo que "se me escapa" algo, si alguien descubre por qu ocurre esto que me avise. Bueno, ahora vamos a aadir un control nuevo, que Excel llama "cuadro combinado" (el nombre en ingls es ComboBox), que es la tpica persiana que estamos hartos de ver en cualquier dilogo, y permite al usuario escoger una opcin 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".

Curso Visual Basic para Aplicaciones

19 de 33

Las propiedades ms importantes de un ComboBox son: List: un conjunto de cadenas de caracteres (strings) que representan a todos los elementos de la lista. Para acceder a un elemento en concreto utilizamos MiComboBox.List( 3 ), que nos devolvera el cuarto elemento de la lista, ya que el primero tiene el nmero 0. ListCount: el nmero de elementos que hay en la lista. Si utilizamos MiComboBox.List( MiComboBox.ListCount-1 ) obtendremos el ltimo elemento de la lista. ListIndex: el nmero del elemento seleccionado actualmente por el usuario. Para obtener el texto del elemento seleccionado utilizaramos MiComboBox.List( MiComboBox.ListIndex ). Si hemos definido el control como "multiseleccin" (es decir, que el usuario pueda escoger ms de un elemento), esta propiedad no se puede usar, pero por ahora no nos vamos a meter en esto. Rowsource: es el rango del que queremos que el ComboBox lea los elementos. Podemos utilizar esta propiedad, o bien introducir nosotros mismos mediante cdigo los elementos (utilizando el mtodo AddItem). ControlSource: la celda en la que el ComboBox lee y escribe el elemento seleccionado. Igual que con RowSource, podemos utilizar esta propiedad para que el ComboBox nos escriba en una celda el elemento seleccionado o podemos utilizar cdigo para obtener el elemento seleccionado (utilizando ListIndex). 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 slo puede escoger uno de los valores de la lista.

ControlTipText: esta propiedad se aplica a todos los controles, pero como todava no la he explicado, la pongo aqu. Esta propiedad sirve para mostrar al usuario un pequeo texto de ayuda sobre el control cuando ponga el ratn sobre el mismo, el ya clsico cuadrito amarillo.

Una vez vistas las propiedades, vamos con los mtodos del objeto ComboBox: AddItem: sirve para aadir un elemento a la lista. Su sintaxis es MiComboBox.AddItem( 'Mi texto', 3 ). El primer parmetro es el texto del elemento, y el segundo parmetro (que es opcional), es la posicin dentro de la lista que queremos para el nuevo elemento. Si no utilizamos el segundo parmetro, nuestro nuevo elemento se aadir al final de la lista. RemoveItem: para borrar un elemento. Su sintaxis es MiComboBox.RemoveItem( 3 ), para borrar el elemento nmero 3. Clear: borra todos los elementos de la lista.

Como siempre, hay muchos ms mtodos y propiedades, que estn 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 slo 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 clculo 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".

Curso Visual Basic para Aplicaciones

20 de 33

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 ratn sobre el ComboBox. Recuerda que esta propiedad la tienen todos los controles. Ya tenemos nuestro ComboBox, y si lo probamos veremos que funciona perfectamente. Recuerda que el ComboBox coge los valores del rango establecido en RowSource, y almacena el valor seleccionado por el usuario en la celda establecida en ControlSource. Como ejercicio podemos hacer lo siguiente: borramos las propiedades ControlSource y RowSource, y hacemos que el control funcione igual pero encargndonos nosotros mismos de poner los valores en la lista y luego identificar la seleccin del usuario y poner su valor en la celda que queremos. Para ello tendremos que utilizar las propiedades List y ListIndex, y los mtodos Clear y AddItem, poniendo el cdigo en los eventos Userform_Initialize() y btnAceptar_Click(). Ahora que ya dominamos el ComboBox, una buena noticia: el control ListBox ("Cuadro de Lista" segn la traduccin de Excel) funciona prcticamente igual. El ComboBox es el control en el que slo se ve una lnea y pulsando un botn sale una "persiana" con las distintas opciones, y en cambio en el control ListBox se ve siempre la lista de opciones, no hay persiana. Aparte de esta diferencia "visual", los dos tipos de controles son prcticamente iguales. Vamos a por otro control, el SpinButton (Botn de nmero). Este botn se utiliza normalmente combinado con un Cuadro de edicin: si pulsamos el SpinButton hacia arriba aumentamos el valor del cuadro de edicin, y viceversa. Las propiedades ms importantes del SpinButton son: Value: el valor del SpinButton, un nmero. Min: el valor mnimo que puede tener el SpinButton. Max: el mximo. SmallChange: el incremento/decremento que sufrir la variable Value cada vez que el usuario pulse el SpinButton. Normalmente es 1, pero lo podemos cambiar.

Vamos a utilizar el control SpinButton combinado con un cuadro de edicin que vamos a utilizar para almacenar la edad. Primero ponemos un cuadro de edicin, que llamaremos "editEdad" (ya sabes, cambiando la propiedad Name). En una hoja de clculo daremos el nombre "rngEdad" a una celda, y utilizaremos esta celda para la propiedad ControlSource de nuestro control "editEdad". Ahora colocamos un control SpinButton. Normalmente se suelen colocar a la derecha del cuadro de edicin al que van asociados. En el cuadro de propiedades vamos a poner a Min el valor 0 (edad mnima) y a Max el valor 150 (edad mxima). El nombre del control lo dejamos como est (SpinButton1). 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 edicin "editEdad". Hacemos doble-click en el SpinButton y aparece la ventana de cdigo, en la que escribiremos: Private Sub SpinButton1_Change() editEdad.Text = SpinButton1.Value End Sub Bastante sencillo, no? Simplemente damos a la propiedad Text del objeto "editEdad" el valor del SpinButton. Ahora tenemos que hacer lo mismo pero "al revs". Si el usuario va directamente al cuadro de edicin y escribe una edad, queremos que el valor del SpinButton se actualice, ya que tanto el cuadro de edicin 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 cdigo escribimos: Private Sub editEdad_Change() SpinButton1.Value = editEdad.Value End Sub Prcticamente igual que antes. El nico cambio es que utilizamos la propiedad Value de editEdad en lugar de la propiedad Text, porque queremos el valor numrico, y no la cadena de caracteres. Si en el control de edicin

Curso Visual Basic para Aplicaciones

21 de 33

escribes alguna letra en lugar de un nmero vers que el Userform se detiene mostrndote un mensaje de error porque no puede calcular la propiedad Value de editEdad. En una aplicacin "de verdad" deberamos escribir algo de cdigo para evitar estos errores, pero todava no hemos visto el control de errores (ya llegaremos). Todava nos queda un pequeo detalle respecto al SpinButton. Cuando el Userform se carga por primera vez, el control editEdad lee de la hoja de clculo 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: Private Sub UserForm_Initialize() SpinButton1.Value = editEdad.Value End Sub El cdigo es el mismo que el utilizado en el evento editEdad_Change(). Si probamos ahora el dilogo veremos que la combinacin editEdad + SpinButton1 funciona perfectamente (aparte de la deteccin de errores, que veremos ms adelante). Ahora vamos con otros tipos de controles: las casillas de verificacin (CheckBoxes en ingls), y los botones de opcin (OptionButtons). Para utilizarlos vamos a suponer que queremos que el usuario nos indique si utiliza o no una hoja de clculo, y en caso de que s la utilice nos diga cul es su preferida. Lo primero es preguntar si utiliza una hoja de clculo, y para ello vamos a utilizar una casilla de verificacin, 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 clculo (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 clculo". Tambin podemos escribir algo en la propiedad ControlTipText. Adems de todas esas propiedades que ya conocemos las propiedades importantes de un control de verificacin o CheckBox son: Value: el valor del control. Puede ser verdadero o falso. 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 cul es la hoja de clculo preferida del usuario. Para ello vamos a utilizar unos botones de opcin, para darle la opcin de elegir entre Excel, Lotus 1-2-3 u otra hoja de clculo. Lo primero que tenemos que hacer es colocar un control marco (Frame en ingls). Estos controles slo sirven para agrupar controles y para mejorar la presentacin del userform. Tambin 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 opcin. Para poner un control dentro del marco lo que hay que hacer es seleccionar el marco y sin quitar la seleccin aadir el nuevo control. Vamos a hacer esto tres veces, y aadiremos tres botones de opcin dentro del marco. Para guardar los valores de los botones de opcin vamos a dar nombres a tres celdas de la hoja de clculo (en el ejemplo E16, E17 y E18), a las que nombraremos "rngExcel", "rngLotus" y "rngOtros". Ahora vamos a los tres botones de opcin 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. Tambin convendra cambiar la propiedad Caption de cada uno de los botones para mostrar el texto adecuado. Las propiedades Value y TripleState de un botn de opcin funcionan igual que en el control de verificacin, y el resto de propiedades no son demasiado importantes. Si probamos ahora el userform debera funcionar perfectamente, excepto un pequeo detalle. Si el usuario nos dice que no utiliza ninguna hoja de clculo, los botones de opcin siguen preguntndole cul es su hoja de clculo preferida, lo que evidentemente no tiene ningn sentido. Lo que tenemos que hacer es desactivar los botones de

Curso Visual Basic para Aplicaciones

22 de 33

opcin: para desactivar cualquier control (no slo los botones de opcin) se utiliza la propiedad Enabled; si esta propiedad es verdadera, el control est activado, y si es falso el control estar desactivado (aparece en color gris), y el usuario no puede interactuar con l. Lo que nos queda ahora es saber cundo ha cambiado de estado (verdadero, falso) la casilla de verificacin cboxUtilizaHoja. Como siempre, lo hacemos con un evento, el evento Change del control de verificacin, 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 opcin. El cdigo es: Private Sub cboxUtilizaHoja_Change() Frame2.Enabled = cboxUtilizaHoja.Value OptionButton1.Enabled = cboxUtilizaHoja.Value OptionButton2.Enabled = cboxUtilizaHoja.Value OptionButton3.Enabled = cboxUtilizaHoja.Value End Sub Fjate que damos a la propiedad Enabled de los botones de opcin y el marco el valor de la propiedad Value del control de verificacin. Tambin podramos haber escrito: If cboxUtilizaHoja.Value = True Then OptionButton1.Enabled = True ..... Else OptionButton1.Enabled = False ..... End If El resultado es el mismo, pero la primera opcin es bastante ms elegante. Un pequeo detalle. Cuando el userform se inicia tambin deberamos activar/desactivar los botones segn el valor de la casilla de verificacin. Una solucin rpida sera escribir dentro del evento Userform_Initialize (que ya conocemos) el mismo cdigo que en cboxUtilizaHoja_Change, pero no es lo ms adecuado porque estaramos escribiendo el mismo cdigo en dos sitios distintos, cosa que hay que evitar porque si luego tenemos que hacer algn cambio en el cdigo tendremos que hacerlo en dos sitios. Lo mejor es llamar a cboxUtilizaHoja_Change() desde el evento Userform_Initialize(). La rutina cboxUtilizaHoja_Change es llamada cada vez que se produce el evento Change, pero nada nos impide llamarla por nuestra cuenta en cualquier otro momento, como por ejemplo cuando se inicia el userform. El evento Userform_Initialize quedar as: Private Sub UserForm_Initialize() cboxUtilizaHoja_Change SpinButton1.Value = editEdad.Value End Sub Pues ya tenemos el userform de datos personales completo, y ya hemos aprendido a usar prcticamente todos los controles. La apariencia final del userform de datos personales es la siguiente.

Curso Visual Basic para Aplicaciones

23 de 33

Como ejercicio, vamos a hacer otro userform, en el que no vamos a utilizar ningn control nuevo pero s vamos a ver un evento nuevo (KeyUp). Lo que vamos a hacer es un dilogo en el que el usuario pueda escribir una cifra en pesetas y automticamente le diremos cuntos euros son. Y al revs, si escribe los euros calcularemos cuntas pesetas son. Pues vamos al VBE, creamos un userform, y ponemos en l dos controles de edicin, que llamaremos editPesetas y editEuros, dos etiquetas al lado de cada control de edicin, y un botn para cerrar el dilogo. Primero lo ms fcil. En el botn de cerrar (al que cambiaremos el Caption para que ponga "Cerrar", y que llamaremos btnCerrar) tenemos que poner el cdigo para cerrar el userform: Private Sub btnCerrar_Click() Unload Me End Sub Ahora vamos a los cuadros de edicin. Lo que queremos hacer es que cada vez que el usuario pulse una tecla se actualice el otro cuadro de edicin. Por ejemplo, si el usuario va a escribir 2500 pts, nosotros actualizaremos el cuadro de edicin 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 cdigo de este evento vamos a la ventana de cdigo 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 declaracin de la rutina (con los parmetros adecuados, que en este caso no nos interesan y vamos a ignorar) y el "End Sub" correspondiente. Ahora slo tenemos que poner lo del medio: Private Sub editPesetas_KeyUp(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer) If editPesetas.Text <> "" Then editEuros.Text = Format(editPesetas.Value / 168, "0.00") Else editEuros.Text = "" End If End Sub

Curso Visual Basic para Aplicaciones

24 de 33

El "If" lo utilizo como una pequea forma de deteccin de errores, por si el cuadro de edicin est vaco (de todas formas, se pueden producir muchos errores, como por ejemplo si el usuario introduce una letra en lugar de un nmero, pero no vamos a ponernos ahora a escribir cdigo 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 funcin Format para que slo presente dos decimales. (la funcin Format es muy sencilla de utilizar, si quieres ms informacin consulta la ayuda). Podemos probar a ejecutar ahora el dilogo y veremos que cada vez que introduzcamos un carcter 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: Private Sub editEuros_KeyUp(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer) If editEuros.Text <> "" Then editPesetas.Text = Format(editEuros.Value * 168, "0.00") Else editPesetas.Text = "" End If End Sub Igual que antes, pero multiplicando por 168 en lugar de dividir. Hasta ahora, todos los botones que hemos utilizado en los userforms servan para cerrar el userform, con la diferencia de que solemos poner uno para Aceptar y otro para Cancelar. Pero tambin podemos poner en un userform un botn que realice cualquier otra accin pero no cierre el userform. Lo ms tpico es que este botn haga algn 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 edicin, que van a pegar en la celda activa de la hoja de clculo el contenido del cuadro de edicin asociado. Colocamos los dos botones, uno al lado de cada cuadro de edicin, y les damos los nombres btnPegarPts y btnPegarEuros, y les ponemos como Caption algo como "Pegar". Ahora vamos al cdigo: Private Sub btnPegarPts_Click() ActiveCell.Value = editPesetas.Value End Sub Private Sub btnPegarEuros_Click() ActiveCell.Value = editEuros.Value End Sub El evento que utilizamos es el evento Click, que ya conocemos de sobra. Y el cdigo tampoco tiene ninguna dificultad, simplemente es poner en ActiveCell el valor del control de edicin, editPesetas o editEuros. Como vers, al pulsar estos botones se pega el contenido en la hoja de clculo, pero no se cierra el userform. Si quisiramos que despus de hacer el pegado se cerrara el userform tendramos que aadir el clsico "Unload Me" a las dos rutinas anteriores. As nos ha quedado el userform del conversor de euros:

Curso Visual Basic para Aplicaciones

25 de 33

Y para terminar esta entrega, vamos a hacer un dilogo para hacer operaciones sobre un rango, como los que ya hemos hecho, pero ms completo. El dilogo va a permitirnos cambiar el rango seleccionado, y luego nos permitir seleccionar la operacin aritmtica que queremos hacer sobre el rango (sumar, restar, multiplicar, dividir) utilizando para ello unos botones de opcin. En este dilogo 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 edicin), 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 ratn o el teclado. Los controles que vamos a poner en este userform son:

Tipo de control Name RefEdit RefEdit1 TextBox Frame OptionButton OptionButton OptionButton OptionButton tbValor Frame1 obSumar obRestar obDividir

Caption N/A N/A Operacin Sumar Restar Dividir Aceptar Cancelar

obMultiplicar Multiplicar

CommandButton btnAceptar CommandButton btnCancelar


El resultado final ser algo as:

Curso Visual Basic para Aplicaciones

26 de 33

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). Vamos con el cdigo: Private Sub UserForm_Initialize() obSumar.Value = True RefEdit1.Text = Selection.Address End Sub Primero hacemos que la operacin seleccionada por defecto sea sumar (alguna tiene que ser) y que en el RefEdit aparezca como rango la seleccin que tena hecha el usuario antes de llamar al dilogo. Ahora los botones: Private Sub btnAceptar_Click() HacerOperacion Unload Me End Sub Private Sub btnCancelar_Click() Unload Me End Sub La nica diferencia entre los dos botones es que uno de ellos llama a la rutina HacerOperacion antes de cerrar el userform. La rutina HacerOperacion es la siguiente: 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 Primero obtenemos el rango seleccionado y lo almacenamos en "r". Luego obtenemos el valor que hay que utilizar, que el usuario ha escrito en tbValor, y lo almacenamos en "i". Luego hacemos un bucle "For Each - Next", que ya conocemos, para repetir el mismo cdigo para todas las celdas del rango. El "If" tan largo que utilizamos es bastante ms sencillo de lo que parece: lo nico que hace es comprobar cul es el botn de opcin activado (Value = True) y efecta la operacin asociada a ese botn. Y aqu termina la cuarta entrega del curso. Si tienes cualquier duda o comentario que hacer, no dudes en contactar conmigo. En la prxima entrega hablaremos de la creacin de mens y barras de herramientas personalizadas.

Curso Visual Basic para Aplicaciones

27 de 33

Captulo 5. Mens y barras de herramientas. En esta entrega vamos a tratar sobre la creacin de mens y barras de herramientas personalizadas para nuestras hojas. En Visual Basic for Applications, las barras de men y las barras de herramientas estn representadas por el mismo objeto (CommandBar), y su funcionamiento es exactamente igual. 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 ests en una hoja de clculo. Si cambias a una hoja de grfico vers que el men cambia: se ha cambiado de barra de men (CommandBar). Cada una de las opciones de la barra de men se llama CommandBarPopUp (men desplegable segn la traduccin de Microsoft). Por ejemplo, en el men de una hoja de clculo la opcin "Archivo" es un men desplegable o CommandBarPopUp. Dentro del men desplegable, cada una de las opciones se llama ControlButton (opcin de men). Por ejemplo, "nuevo" y "Guardar" son opciones del men desplegable "archivo" de la barra de men de "Hoja de clculo" de Excel. Para tener acceso a las barras de comandos (que pueden ser mens o barras de herramientas) utilizaremos la propiedad CommandBars, que devuelve el conjunto de barras de comandos de la aplicacin. 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 Set dst = Sheets("Hoja1").Range("A1") For Each h in CommandBars dst.Value = h.Name Set dst = dst.Offset(1, 0) Next h End Sub De esta forma obtendremos el nombre de todas las barras de comando. Recuerda que puede haber barras de comando que existan pero no estn activas, que no aparezcan en la pantalla. Como habrs podido deducir, la propiedad Name de un objeto CommandBar nos devuelve el nombre de la barra de comando. 1. Crear una opcin de men. Lo primero que vamos a hacer es crear una opcion dentro de un men desplegable. Por ejemplo, vamos a crear una opcin llamada "Macedonia" dentro del men "Edicin". Antes que nada, declaramos las variables que vamos a utilizar:

Curso Visual Basic para Aplicaciones

28 de 33

Dim cBar As Object Dim cBarPopUp As Object Dim cButton As Object La primera variable (cBar) la utilizaremos para almacenar el men de hoja de clculo entero, la segunda (cBarPopUp) para obtener el men de "Edicin" dentro de cBar, y la tercera para crear nuestra opcin (Macedonia) dentro del men de Edicin. Vamos a obtener el men de hoja de clculo. Si te fijas en el resultado de la rutina ListaBarrasComando que hemos creado antes, vers que una de las barras de comando se llama "Worksheet Menu Bar". Esta es la barra de comandos que est presente cuando ests en una hoja de clculo. Hay otras barras, como por ejemplo "Chart Menu Bar", que es la que aparece cuando ests en una hoja de grficos. Para utilizar la barra de comandos "Worksheet Menu Bar" haremos lo siguiente: Set cBar = CommandBars("Worksheet Menu Bar") 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 Edicin. Para ello utilizamos el siguiente cdigo: Set cBarPopUp = cBar.Controls("Edicin") Hemos utilizado la propiedad "Controls" del objeto CommandBar. Esta propiedad nos permite acceder a todos los submens de una barra de comandos. El objeto devuelto es del tipo "CommandBarPopup". Reconozco que la terminologa es un poco confusa, pero as lo ha hecho Microsoft. Ahora ya tenemos el men de "Edicin" en nuestra variable. Y lo que queremos hacer es aadir una opcin dentro de ese men. Para hacerlo utilizaremos deberemos acceder a la propiedad "Controls" de nuestro men de Edicin. Fjate que antes hemos accedido a la propiedad Controls del objeto cBar, y ahora vamos a acceder a la propiedad Controls del objeto cBarPopUp. Pues bien, una vez que accedemos a la propiedad "Controls" del men Edicin (cBarPopUp), utilizamos el mtodo Add para aadir una nueva opcin del men: Set cButton = cBarPopUp.Controls.Add(msoControlButton) Almacenamos en nuestra variable cButton el resultado, porque luego queremos hacerle unos cambios. El tipo de control que queremos aadir puede variar ( msoControlButton, msoControlEdit, msoControlDropdown, msoControlComboBox o msoControlPopup ), pero en nuestro caso queremos una opcin de men, y utilizamos msoControlButton. Nos queda hacer que nuestra opcin 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 opcin de men. En nuestro caso, "&Macedonia". El carcter "&" se utiliza para indicar que la letra que le sigue (la "M" en este caso) queremos que apareza subrayada y funcione como tecla rpida una vez que est abierto el men. OnAction: es el nombre de la rutina que queremos que se ejecute cuando el usuario seleccione esa opcin. En este caso vamos a darle el valor "MiMacro", que ser una pequea rutina que simplemente avisar de que hemos seleccionado esa opcin. ShortcutText: el texto que aparece en la opcin del men, a la derecha. Normalmente se suele poner la tecla rpida para esa opcin de men. Cuidado, porque esta opcin slo sirve para escribir el texto, pero no hace que la tecla rpida funcione, eso tendrs que hacerlo t por otro lado. FaceID: es el nmero de la imagen que queremos que se asigne a nuestra opcin de men. La imagen aparece en la parte izquierda de la opcin. Excel tiene un montn de imgenes para nuestras opciones, y se pueden seleccionar cambiando el ID. Para ver todas las imgenes disponibles y saber qu ID corresponde a cada imagen, lo mejor es hacer una pequea rutina que muestre todas las imgenes. (eso te queda como ejercicio; si tienes alguna duda escrbeme). BeginGroup: true o false, indica si queremos que antes de nuestra opcin se ponga un "separador", una lnea que separe un poco nuestra opcin de la anterior.

Curso Visual Basic para Aplicaciones

29 de 33

Como siempre, hay muchas ms propiedades, pero creo que hemos visto las ms 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("Edicin") 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 opcin 'Macedonia' en el men 'Edicin'", vbOKOnly, "Macedonia") End Sub Para verla en accin abre el fichero de ejemplo, y utiliza el botn "Crear opcin de men". Si te fijas en la rutina CrearOpcionMenu, hemos incluido una llamada a la rutina BorrarOpcionMenu. Esta ltima se encarga de borrar la opcin "Macedonia" del men Edicin en caso de que ya exista, y llamndola evitamos que aparezcan dos opciones "Macedonia". La rutina BorrarOpcionMenu es la siguiente: Sub BorrarOpcionMenu() Dim cBar As Object Dim cBarPopUp As Object Dim cc As Object Set cBar = CommandBars("Worksheet Menu Bar") Set cBarPopUp = cBar.Controls("Edicin") For Each cc In cBarPopUp.Controls If cc.Caption = "&Macedonia" Then cc.Delete Next cc End Sub Al igual que en la rutina CrearOpcionMenu, primero obtenemos la barra de comandos "Worksheet Menu Bar", despues la barra "Edicin", y luego, utilizando la instruccin "For Each", pasamos por todos las opciones de men, y borramos aquellas cuyo "Caption" sea "&Macedonia" (incluyendo el &). Para borrar la opcin de men utilizamos el mtodo Delete. 2. Crear un men desplegable. Ahora vamos a crear un men desplegable (como el men Archivo, o Edicin, de la hoja de clculo de Excel). Como siempre, primero declaramos las variables que vamos a utilizar. Dim cBar As Object Dim cBarPopUp As Object Dim cButton As Object Luego vamos a obtener la barra de comandos de la hoja de clculo: Set cBar = CommandBars("Worksheet Menu Bar") Para aadir un men desplegable a dicha barra de comandos vamos a utilizar el mtodo "Add" de la coleccin "Controls" de la barra de comandos:

Curso Visual Basic para Aplicaciones

30 de 33

Set cBarPopUp = cBar.Controls.Add(Type:=msoControlPopup, Before:=10) El tipo de control que queremos aadir 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 tenamos el men desplegable "Edicin". Ahora tenemos que aadir opciones en dicho men desplagable, igual que hemos hecho antes: Set cButton = cBarPopUp.Controls.Add(msoControlButton) With cButton .Caption = "&Macedonia 1" .OnAction = "MiMacro" End With Tambin podemos aadir un submen dentro de alguna opcin 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 aadido la opcin 'Macedonia' en el men principal", _ vbOKOnly, "Macedonia") End Sub Para ver esta rutina en accin utiliza el botn "Crear men desplegable" del fichero de ejemplo. 3. Crear una barra de men. 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:

Curso Visual Basic para Aplicaciones

31 de 33

Dim cBar As Object Dim cBarPopUp As Object Dim cButton As Object 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 mtodo "Add" de la coleccin "CommandBars". Set cBar = CommandBars.Add("Barra Macedonia", msoBarTop, True) El primer argumento es el nombre de la barra de comandos que vamos a crear. El segundo argumento es la posicin de la nueva barra de comandos, y puede ser uno de los siguientes valores: msoBarLeft, msoBarRight, msoBarTop, msoBarBottom: izquierda, derecha, arriba o abajo. msoBarFloating: queremos que la nueva barra de men sea flotante. msoBarPopUp: la nueva barra de mens ser contextual, como las que salen cuando pulsamos el botn derecho.

El tercer argumento (verdadero o falso) indica si queremos que la nueva barra de men reemplace a la barra de mens activa o no. Una vez que tenemos nuestra barra de men utilizamos el cdigo que hemos aprendido antes para crear los mens desplegables y sus opciones. La siguiente rutina crea una barra de men y varios mens 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 ms de un sitio del cdigo 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 todava 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:

Curso Visual Basic para Aplicaciones

32 de 33

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. 4. Crear una barra de herramientas: Como hemos visto al principio, en VBA las barras de men y las barras de herramientas estn representadas por el mismo objeto (CommandBar), y su funcionamiento es prcticamente igual. Crear una barra de herramientas es exactamente igual que crear una barra de men: Set cBar = CommandBars.Add(NOMBREBARRA, msoBarFloating, False) En este caso hemos creado una barra "flotante", pero podamos haber utilizado cualquiera de los otros parmetros que hemos visto antes. Ahora vamos a crear un botn de la barra de herramientas. La nica diferencia entre crear un botn y crear un men desplegable es el tipo de control, el parmetro del mtodo Add. En este caso utilizaremos "msoControlButton": Set cButton = cBar.Controls.Add(msoControlButton) With cButton .Caption = "&Macedonia " & i .OnAction = "MiMacro" .FaceId = Int(Rnd * 1000) End With El cdigo utilizado para crear, activar, desactivar y borrar una barra de herramientas es el mismo que para una barra de mens. De hecho no hay ninguna diferencia entre ellas, en Excel las dos son una barra de comandos (CommandBar). Adems, tambin podemos mezclar botones y mens dentro de una barra de comandos: slo hay que crear la barra y luego aadir controles tipo "msoControlPopup" para los mens 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.

Curso Visual Basic para Aplicaciones

33 de 33

También podría gustarte