Está en la página 1de 69

Programacin con Visual Basic para Aplicaciones en Excel

Introduccin
Artculos
Macros
Funciones
Proyectos paso a paso
Complementos (Add-ins)
Otros Lenguajes
Vinculos

Introduccin
Programar sobre cualquier lenguaje es fascinante, en la mayora de ellos, el limite esta ms de parte del
programador que del lenguaje, no tengo elementos para decir cual es mejor o peor, creo que cada uno tiene
diferentes propsitos y que el bueno o malo, es el programador. Aprend a programar de forma emprica, esto
tiene sus pros y sus contras, como desventaja esta que te tardas un poco ms de tiempo en aprender y como
ventaja esta que te vuelves un muy buen investigador, estas, solo por nombrar algunas, se que tal vez tenga
muchas deficiencias y muchos otros "vicios" de los cuales, tal vez, ni cuenta me de, pero confo en que algn
buen samaritano que tenga ms experiencia que yo en la programacin, me los har notar, por lo pronto, es
mi deseo que este camino que para mi ha sido de ms de cinco aos, sea mas corto y ms leve para ti, esta
es la razn principal de estas pginas. Como notaras la seccin que esta ms completa es la de Excel, fue de
los primeros programas que use y en que empec con el VBA y aun me sigue sorprendiendo y cada vez que
escribo unas lneas de cdigo, me surgen nuevas interrogantes, pero eso me gusta y te sugiero que no te
desanime si este es tu caso, veras que poco a poco se va aclarando el camino.
Si bien en un principio no era mi intencin hacer un manual, sino tan solo una gua, la verdad es que se ha
impuesto mi espritu pedaggico, pues te cuento que una de mis actividades favoritas es dar clases, as que
lo que empez como unos apuntes se esta convirtiendo en este pequeo manual, as que aprovecha,
estudia, lee, investiga, lee, practica y lee, lee mucho...
Artculos

Preguntale a la Grabadora de macros


Publica o Privada, cual usar?
Option Explicit, Dim, que es eso?
Cmo puedo proteger un trabajo intelectual desarrollado en Excel? COLABORACION de Hctor
Miguel Orozco Daz, GRACIAS...
Variables y objetos, como nombrarlos?

Macros

Grabando mi primer macro en Excel


Escribiendo mi primer macro en Excel
Escribiendo mi primer macro en Excel II
Escribiendo mi primer macro en Excel III

Funciones
Las funciones personalizadas de Excel, trabajan igual que las incorporadas, con la diferencia de que estas
las creamos nosotros y nos sirven para obtener valores que no nos devuelven las incorporadas o para unir en
una sola, el resultado de varias funciones, su uso y manipulacin es muy semejante a las macros, pero como
sabes estas nos devuelven valores, esto no lo pierdas de vista.

Escribiendo mi primer funcin en Excel


Como dejar disponibles mis funciones?
Funcin Numeros a Letras

Proyectos Paso a Paso


Esta seccin esta pensada para que, aunque no tengas gran experiencia en la programacin, seas capas de
seguir una secuencia de pasos para lograr un propsito, un proyecto completo de alguna tarea, puedes
proponer el desarrollo de algn proyecto, y si es de inters para varios, tal vez se pueda desarrollar entre
todos.
Proyecto de Facturacin (en preparacin)

Complementos (Add-ins)
En esta seccin explicaremos que son, cual es su propsito y como se usan, as como la forma de
"instalarlos" dentro de Excel, tambin agregaremos complementos probados y terminados para su libre uso y
estudio del cdigo.
Que son?
Exportador de macros

Otros Lenguajes
Controlar Excel desde otros lenguajes, es sumamente fcil, ademas de que pones a disposicin de tu
programa, todas las herramientas de este, basicamente hay dos formas de hacerlo, trataremos de ver ambas,
aunque ms adelante solo me concentrare en una de ellas, tambin, para esta seccin, estoy suponiendo
que ya tienes bases de programacin...

Preguntale a la Grabadora de Macros


Rara vez, la grabadora de macros, nos deja una macro tal como la queremos, en la mayora de los casos, hay
que editarla, agregndole o quitndole lneas, complementndola, mejorndola. En mi experiencia, la
grabadora de macros funciona muy bien como profesora, es decir, nos ensea el "como" de casi todo el trabajo
sobre Excel y "casi" nunca se equivoca. Concretamente lo que te quiero decir, es que cuando no sepas como
hacer X tarea, graba una macro, ve el cdigo, checa la ayuda acerca de las lneas que haya agregado y veras
como se aprende bastante, tambin esto sirve para que cuando realices una consulta, aqu o en cualquier otro
lugar, ya tengas una idea, con cdigo, de lo quieres, veamos estos dos casos con un ejemplo:
En la pgina de Todo Expertos, un usuario me hizo la siguiente pregunta, que pongo solo con animo ilustrativo,
no se nos vaya a ofender:
Esta duda me trae de cabeza...... (26/3/2002 18:44:0)
Hola Valedor, es la primera vez que pregunto, supongo que ser facil pero a mi me resulta muy
complicado, la pregunta en resumen es la siguiente: como puedo hacer para que con una
macro,funcin, o lo que sea, me copie solo las celdas que contengan texto del rango de celdas
A1:A20 y me coloque el resultado en el rango C1:C20 ordenados una debajo de la otra, es
decir que no copie las celdas vacas, teniendo en cuenta que el rango de la columna A son
celdas vinculadas desde otras hojas y solo se rellenan si hay algn dato que consignar, si me

puedes ayudar para realizar esa macro con te lo agradecera muchsimo y me solventaras un
gran problema....
Grabar macro... (27/3/2002 11:35:0)
Lo primero que tienes que probar es a grabar una macro, yo lo hice y me dio esto
Sub Macro2()
Range("A1:A20").Select
Selection.SpecialCells(xlCellTypeFormulas, 2).Select
Selection.Copy
Range("C1").Select
ActiveSheet.Paste
End Sub
que hace lo que quieres...
Primero, este amigo, no sabe la diferencia entre una Macro, una Funcin o lo que sea, que son tres cosas
diferentes, pero tu ya los sabes verdad?... Segundo, si el hubiese grabado la macro, tal vez no le hubiese
dado el mismo cdigo que a mi, pero tendra "algo", que ya es ganancia, si antes de preguntar grabas tu
macro, yo pensar que tienes inters en aprender y me dar ms gusto ayudarte, pero que pasos hubisemos
seguido para grabar esta macro, veamos algunas opciones, supongamos el escenario que nos propone el
amigo, una serie de valores en las celdas A1:A20, pero que son formulas, las cuales pueden ser texto o algo
ms que no especifica, de estos datos, hay que seleccionar los que son texto y copiarlos a la celda C1,
eliminando los espacios vacios, para este ejemplo, use los siguientes datos:

Observa la barra de formulas, ve como los datos estan vinculados a otra hoja, observa tambin, que tenemos
textos y nmeros, ahora, grabaremos nuestra macro con estos pasos :
1. Activamos la grabadora de macros
2. Seleccionamos los datos de nuestro inters, en este caso de la celda A1:A12
3. Presionamos la tecla F5
4. Presionamos el botn de comando Especial...
5. Seleccionamos Celdas con formulas y solo dejamos activada la opcin Texto.
6. Presionamos el botn de comando Aceptar
7. Copia estos datos, por el mtodo que quieras, tienes como cuatro o ms opciones
8. Selecciona la celda C1
9. Pega los datos
10. Detenemos la grabacin
Si seguimos estos pasos al pie de la letra, la macro grabada tiene que quedar as...
Sub Macro1()
Range("A1:A12").Select
Selection.SpecialCells(xlCellTypeFormulas, 2).Select

Selection.Copy
Range("C1").Select
ActiveSheet.Paste
End Sub
Si ejecutas esta macro en la hoja donde estn las formulas, en nuestro ejemplo dentro de la Hoja1 tendrs que
ver algo como la siguiente imagen:

No te preocupes tanto si tienes algo diferente, seguro algo hiciste de otra manera, en este tema, esto no es lo
relevante, lo importante, es ver y notar como la grabadora de macros, nos ayuda mucho...
Ahora, vamos a darle una pequea variante para que observes las diferencias, estos son los pasos:
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.

Activamos la grabadora de macros


Seleccionamos la celda A1
Presionamos la tecla F5
Presionamos el botn de comando Especial...
Seleccionamos Region actual
Presionamos el botn de comando Aceptar
Presionamos la tecla F5
Presionamos el botn de comando Especial...
Seleccionamos Celdas con formulas y solo dejamos activada la opcin Texto.
Presionamos el botn de comando Aceptar
Copia estos datos, por el mtodo que quieras, tienes como cuatro o ms opciones
Selecciona la celda C1
Pega los datos
Detenemos la grabacin

Para estos pasos, la grabadora nos crea el siguiente cdigo:


Sub Macro2()
Range("A1").Select
Selection.CurrentRegion.Select
Selection.SpecialCells(xlCellTypeFormulas, 2).Select
Selection.Copy
Range("C1").Select
ActiveSheet.Paste
End Sub
Ejecuta cada una de estas macros y nota las diferencias, dale variantes, por ejemplo, agrega mas datos por
debajo de la celda A20 y vuelve a probar cada una de las dos macros, agrega valores diferentes que no sean
texto o nmeros, agrega constantes, o sea, valores que NO provengan de formulas, prubalas en otras hojas o
libros. Cierto, esta macro no se adapta a todos los casos, de hecho, hace un trabajo muy especifico, pero notas
que ahora sabemos como seleccionar la regin actual Selection.CurrentRegion.Select o tambin aprendimos
como seleccionar las celdas con formulas que contengan solo texto
Selection.SpecialCells(xlCellTypeFormulas, 2).Select que ms aprendiste con esta pequeisima macro?.

Por ultimo haremos algo que se hace con la "mayora" de las macros, editarla, si, editarla, es decir, agregarle
lneas que no haya agregado la macro, eliminando las que no nos sirven o mejorando lo que sea posible y
mira que casi siempre es posible.
Como primer paso, entra al Editor VBA y copia la macro que se llama (si no le pusiste otro nombre) Macro2, y
cmbiale el nombre a Macro3, recuerda que NO puedes tener dos macros con el mismo nombre dentro del
mismo mdulo, esta macro tres ser la que modificaremos y tal vez te sorprenda lo que se puede hacer,
sigamos...

Como primer paso comentare la macro para que sepas que hace cada lnea...
Sub Macro3()
'Se selecciona la celda A1
Range("A1").Select
'A partir de la seleccion actual, se selecciona la REGION ACTUAL
Selection.CurrentRegion.Select
'Seleccionamos las celdas con formulas que sean texto
Selection.SpecialCells(xlCellTypeFormulas, 2).Select
'Copiamos la seleccion
Selection.Copy
'Se selecciona la celda C1
Range("C1").Select
'Copiamos el contenido del portapapeles en la hoja activa
ActiveSheet.Paste
End Sub
El siguiente paso ser unificar las dos primeras lneas, es decir desde la celda A1 seleccionaremos la
regin actual, para que se vea as...
Sub Macro3()
'Se selecciona la celda A1 y su REGION ACTUAL
Range("A1").CurrentRegion.Select
'Seleccionamos las celdas con formulas que sean texto
Selection.SpecialCells(xlCellTypeFormulas, 2).Select
'Copiamos la seleccion
Selection.Copy
'Se selecciona la celda C1
Range("C1").Select
'Copiamos el contenido del portapapeles en la hoja activa
ActiveSheet.Paste
End Sub
Ejecuta la macro con cada modificacin que le hagamos, para que compruebes que sigue realizando
las mismas acciones y finalizamos con el mismo resultado. Siguiente paso; unificamos la lnea de
seleccin de la celda A1 y la regin actual, con la lnea de seleccin de formulas que contengan texto...
Sub Macro3()
'Se selecciona la celda A1 y su REGION ACTUAL y las
'las celdas con formulas que sean texto
Range("A1").CurrentRegion.SpecialCells(xlCellTypeFormulas, 2).Select
'Copiamos la seleccion
Selection.Copy
'Se selecciona la celda C1
Range("C1").Select
'Copiamos el contenido del portapapeles en la hoja activa
ActiveSheet.Paste
End Sub
Siguiente paso; unificaremos la lnea de seleccin y la lnea del mtodo Copy...
Sub Macro3()

'Se selecciona la celda A1 y su REGION ACTUAL y las


'las celdas con formulas que sean texto y copiamos
Range("A1").CurrentRegion.SpecialCells(xlCellTypeFormulas, 2).Copy
'Se selecciona la celda C1
Range("C1").Select
'Copiamos el contenido del portapapeles en la hoja activa
ActiveSheet.Paste
End Sub
Siguiente paso; le agregamos el argumento "opcional" al mtodo Copy, donde se le indica el destino
donde queremos dejar lo que estamos copiando, tiene que ser un argumento tipo Range, o sea un
rango, para nuestro ejemplo, ser la celda C1
Sub Macro3()
'Se selecciona la celda A1 y su REGION ACTUAL y las
'las celdas con formulas que sean texto y copiamos
'le agregamos el argumento "opcional" al metodo Copy
'el DESTINO donde queremos copiar, un Rango
Range("A1").CurrentRegion.SpecialCells(xlCellTypeFormulas, 2).Copy Range("C1")
End Sub
Cmo vez?, has ejecutado la macro?, observas como con UNA sola lnea podemos hacer lo que se
hacia con SEIS?, interesante no crees?, no siempre es as, pero "casi" siempre, la grabadora de
macros, graba lneas de ms, que es muy bueno depurar, pues nos da mucha practica y cdigo ms
limpio y ordenado...

Para terminar, te comento que todava, hago uso de esta tcnica, si no se o no recuerdo como se hace
determinada tarea, simplemente grabo una macro y listo, me muestra como es y en poco tiempo te
sorprenders como cada vez menos, tienes que consultar la ayuda, saludos...
Creiste que esta vez no habia tareita, pues te fallo, prueba a grabar una macro con alguna accin que te
interese como se hace con cdigo y nos cuentas a todos en la lista de correo, si vemos alguna interesante la
podemos publicar aqu...

Descargar el archivo grabando_macros.zip que contiene el archivo Preguntale a la grabadora de macros.xls


con todo el cdigo mostrado en este artculo.

Publica o Privada, cual usar?

Para este tema, doy por sentado que algunas vez has grabado, al menos, una macro, que has leido al menos
la Introducin que hay en esta pgina...
Cuando grabamos una macro, la grabadora nos crea un cdigo como este:
Sub Macro1()
'
' Macro1 Macro
' Macro grabada el 03-04-2002 por Tecnico1
'
ActiveCell.FormulaR1C1 = "Hola"
Range("A2").Select
End Sub

en algunas de mis pginas, en algunas otras pginas o en algn otro lado, habrs visto que algunas macros
tienen una palabra ms, detrs del Sub, como se que eres curioso, presionaste F1 y en la ayuda leste cuales y
para que sirven estas palabras: Public y Private, as que supongo que lo dicho aqu ya lo sabes, pero sigue
leyendo, tal vez encuentres algo nuevo o tal vez me notes algo que me falto y que por supuesto hars el favor
de decirme, verdad?, gracias. Bien, entonces la macro anterior tambin puede estar escrita as...
Public Sub Macro1()
ActiveCell.FormulaR1C1 = "Hola"
Range("A2").Select
End Sub
o tambin as
Private Sub Macro1()
ActiveCell.FormulaR1C1 = "Hola"
Range("A2").Select
End Sub
pero, cul es la diferencia?, de eso se trata este pequeo articulo...
Veamos que dice la ayuda acerca de estas palabras
Public
Opcional. Indica que el procedimiento Sub es accesible para todos los dems procedimientos de todos
los mdulos.
Private
Opcional. Indica que el procedimiento Sub es accesible slo para otros procedimientos del mdulo en
el que se declara.
A ver si entendimos, probemos con unos ejemplos, realiza los siguiente pasos:
Entra a Excel
Entra al EditorVBA (Alt+F11)
Men Insertar | Modulo
En la ventana de cdigo escribe lo siguiente
Sub Pruebas1()

MsgBox "Esta macro es PUBLICA"


End Sub
A lo que acabamos de hacer se le llama, declarar un procedimiento.
Ejectala desde el EditorVBA presionando F5 (recuerda que el cursor debe estar dentro de la macro) y
nos mostrara este bonito mensaje.

Ahora quiero que la vuelvas a ejecutar, pero desde Excel, regresa a Excel, ve al men Herramientas |
Macro | Macros... o si lo prefieres Alt+F8, selecciona la macro Pruebas1 y presiona el botn Ejecutar
para confirmar que, de nuevo, se ejecuta correctamente.
Ahora, agrgale la primer palabrita que estamos estudiando, para que se vea as.
Public Sub Pruebas1()
MsgBox "Esta macro es PUBLICA"
End Sub
Vuelve a ejecutar la macro, de las dos formas que hemos visto y felizmente, nos muestra nuestro
mensaje.
Conclusin: las macros o procedimientos son Publicas por omisin y como dice la ayuda que es
opcional, entonces es lo mismo poner o no poner la palabra Public antes de la instruccin Sub.

Muy bien, muy bien, veo que eres buen estudiante, ahora creamos una segunda macro que se llame
Pruebas2 (te quemaste el coco para pensar este nombre Mauricio), por que recuerda que no puedes
tener dos procedimientos que se llamen igual, prueba a ponerle el mismo nombre y veraz que el
EditorVBA te dir algo medio feo. Ahora, le ponemos nuestra segunda palabrita.
Private Sub Pruebas2()
MsgBox "Esta macro es PRIVADA"
End Sub
Ejectala desde el EditorVBA, vers que nos sigue mostrando el mensaje, claro, ahora nos dice que es
PRIVADA (ni tanto verdad?, la seguimos viendo), pero la siguiente prueba ser ejecutarla desde Excel
(Alt+F8).
Qu paso?, mande...?!, que!!, que no se ve!!, cmo que no se ve!?, pero si estamos declarandolo
como debe ser, aaahhh ya recuerdo, le agregamos una palabrita mgica, verdad?, Private, si, esta
palabrita es muy til, en este caso, la macro ya no aparece listada en el cuadro de lista, del cuadro de
dialogo Macros, como lo acabamos de demostrar, pero entonces, no se puede ejecutar desde aqu,
tiene que ser desde el EditorVBA?, para probarlo entra de nuevo al cuadro de dialogo macros y por
ahora solo veras la macro anterior Pruebas1, ah, donde dice Nombre de la macro, escribe Pruebas2
y observa que pasa...
Interesante no?, la macro de todos modos la podemos ejecutar con solo saber su nombre y estars
de acuerdo que si no queremos que las ejecuten no les diremos como se llaman, sssssshhhh...
Te puede suceder que, por error de dedo, hayas escrito mal el nombre de la macro, qu pasa?, qu
es lo que hace Excel?, te dejo de tareita que me cuentes que pasa en estos casos.
Y eso es todo?..., no, cmo crees?, sigamos haciendo pruebas, como sabes, y si no sabias, ahora
vas a saber, puedes ejecutar una macro desde otra macro, a esto lo nombramos llamar a la macro y
para comprobarlo, modifica nuestra primer macro para que se vea as.
Public Sub Pruebas1()
MsgBox "Esta macro es PUBLICA"
Pruebas2
End Sub
Por supuesto ejectala y observa, interesante, muy interesante... verdad que si?... A la vista de este
efecto, que deduces?, para que te imaginas que pueda servir el llamar a una macro desde otra?,
que utilidad tiene el que unas se vean y otras no?...
Antes de responder, algunas, por que otras de estas preguntas tu las tienes que responder, hagamos
otras pruebitas. Insertemos otro modulo en nuestro archivo, men Insertar | Mdulo, nuestro
Explorador de proyectos se tiene que ver as.

En este mdulo crearemos una tercer macro Publica, en este momento ya tienes lo elementos para
hacer tu propio ejemplo, pero por supuesto puedes seguir con los que propongo...
Public Sub PruebasA()
MsgBox "Esta macro es PUBLICA y esta en un otro Mdulo"
End Sub

Ahora, trata de llamar a la macro Pruebas1 que se encuentra en el primer mdulo, la macro se tiene
que ser as...
Public Sub PruebasA()
MsgBox "Esta macro es PUBLICA y esta en un otro Mdulo"
Pruebas1
End Sub
La macro se ejecuta, o se debera ejecutar sin problemas, si no es as, revisa alguno de los pasos que
hemos seguido, ahora, trata de llamar a la segunda macro del primer mdulo, es decir, trata de llamar
a la macro que declaramos Privada en el primer mdulo y que nombramos Pruebas2.
Public Sub PruebasA()
MsgBox "Esta macro es PUBLICA y esta en un otro Mdulo"
Pruebas2
End Sub
Qu sucedi?, se ejecuta?, creo que no, pero el EditorVBA nos muestra un mensaje de error, ms
especficamente el siguiente error.

Despus de presionar el botn Aceptar, el Editor nos regresa a la ventana de cdigo, selecciona la
palabra donde esta el error y nos muestra una lnea de un color amarillo bastante distinguible.

Muy bien pensado, la razn de que no podamos llamar a una macro de otro mdulo, es por que esta
macro la declaramos Privada (Private), entonces si es cierto lo que dice la ayuda, -indica que el
procedimiento Sub es accesible slo para otros procedimientos del mdulo en el que se declara-,
verdad?, de ah la importancia de leer la ayuda "siempre". Antes de que detengas la ejecucin de la
macro, observa la barra de titulo, por ah tiene una palabrita que dice [interrupcin], ya la viste, bueno,
por ahora solo lo menciono, pero ms adelante se ver un poco ms a detalle, cuando ejecutamos
cdigo, este se puede detener, tanto por errores de sintaxis (como en este caso) o cuando nosotros
queramos, esto es algo muy til cuando depuramos nuestras macros, as que lo veremos en otro
articulo. Ahora si, puede detener la ejecucin de la macro, de hecho, no tenemos otra alternativa, esto
lo haces con el icono Restablecer de la barra de herramientas, que es como el botn Detener de la
mayoria de los reproductores de musica, o bien, ve al men Ejecutar | Restablecer y listo, la macro se
detendra al momento.
Concluyendo: las macros pueden ser Publicas (Public) o Privadas (Private), es igual poner el Public o
no, pero no es lo mismo si ponemos o no el Private, la recomendacin es, declara explcitamente si
tu macro es Publica o Privada.

Para terminar te comento que lo visto aqu, acerca de las macros Publicas y Privadas es aplicable,
tambin, para las funciones, es decir, tambin tenemos funciones Publicas y funciones Privadas, pero
parte de la tareita de esta seccin es esa.
o Crea una segunda macro Privada en el segundo Mdulo y realiza todas las pruebas que
hemos hecho con las dems, incluyendo, el tratar de ejecutarlas desde la ventana de Excel
o Crea todas las macros y has todas las pruebas que consideres suficientes para que no queden
dudas de este tema, incluso agrega un tercer o cuarto mdulo para esto.
o Crea varias sencillas funciones, tanto Publicas como Privadas y quiero que me digas, donde se
ven y donde no, te dare una pista, usa el Asistente para funciones para observarlo. Para crear
las funciones, si no lo has hecho, lee el tema Escribiendo mi primer funcin en Excel y despus
haces estas pruebas.
o Una lneas ms arriba, nos hicimos la siguiente cuestin: para que te imaginas que pueda
servir el llamar a una macro desde otra?, la respuesta a esta pregunta es importantisima,
tiene mucho que ver con lo que pensaba el seor Descartes, ya lo recuerdas?...
Como complemento a este artculo, veremos que diferencia hay entre una funcin Publica y una
funcin Privada
La siguiente funcin personalizada nos devuelve un texto con informacin del tipo de contenido de la
celda pasada como argumento y nos dice si la celda esta VACIA, si es un NUMERO, si es una FECHA
o si contiene TEXTO...
Option Explicit
Public Function TipoValor(Celda As Range) As String
If Celda.Value = "" Then
TipoValor = "VACIA"
ElseIf IsNumeric(Celda.Value) Then
TipoValor = "ES NUMERO"
ElseIf IsDate(Celda.Value) Then
TipoValor = "ES FECHA"
Else
TipoValor = "ES TEXTO"
End If
End Function

Para usar esta funcin, regresa a la ventana de Excel, en este caso, usaremos el Asistente para
funciones, que seguro ya dominas, entonces, los pasos serian...
o
o
o
o
o
o

Escribe en la celda A1 un valor cualquiera


Posiciona el cursor en la celda B1
Inicia el Asistente para funciones
En el Cuadro de lista Categora de la funcin, busca la ultima opcin que dir, Definidas por el
usuario
En el Cuadro de lista Nombre de la funcin, tendrs que ver nuestra funcin TipoValor, por
supuesto si tienes ms funciones que hayas creado aqu las veras
Seleccionamos esta funcin y presionamos el Botn de comando Aceptar

Como bien sabes, el Asistente te presenta una ventanita con el nombre de la funcin y un
cuadro de texto solicitndote el argumento Celda necesario para que la funcin trabaje
(bueno, realmente no es un cuadro de texto, sino un control muy especial y muy til que
aprenderemos a usar ms adelante)
Puedes usar el botn Contraer o escribir directamente la referencia a la celda A1, tras lo cual
presionaras el botn Botn de comando Aceptar y el Asistente introducir por nosotros, el signo
igual, la funcin y el argumento que le establecimos

Al terminar, mi celda B1 se tendr que ver como en la siguiente imagen y verificaremos que la
funcin haga el trabajo para la cual la programamos, as es?...

o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o

Ahora, cambiaremos la palabra Public de nuestra funcin por la palabra Private, o bien,
puedes copiar la funcin y hacer una segunda, por supuesto, con otro nombre, yo usare el
primer mtodo...
Option Explicit
Private Function TipoValor(Celda As Range) As String
If Celda.Value = "" Then
TipoValor = "VACIA"
ElseIf IsNumeric(Celda.Value) Then
TipoValor = "ES NUMERO"
ElseIf IsDate(Celda.Value) Then
TipoValor = "ES FECHA"
Else
TipoValor = "ES TEXTO"
End If
End Function
Regresa a la ventana de Excel y copia la formula existente en la celda B1 a la celda B2, qu
pasa?..., as es, la funcin sigue trabajando, entonces!..., cul es la diferencia?, para notarlo,
trata de agregar un valor cualquiera en la celda A3, posicionate en la celda B3 y trata de usar el
Asistente para funciones como en nuestro primer ejemplo y observa...

Efectivamente, la funcin no aparece, de hecho, la categora que usamos Definidas por el


usuario, ya no aparece (claro, siempre y cuando no tengas otra funcin declarada), pero trata
de escribir la funcin directamente en la celda, funciona?, si, si funciona, es algo similar a lo
que pasa en las macros, que, como leiste ms arriba, cuando la pasas a Privada, ya no se lista
en el cuadro de dialogo, pero aun la puedes ejecutar si sabes su nombre, del mismo modo, si
sabes el nombre de alguna funcin personalizada, la puedes llamar o hacer uso de ella,
siempre y cuando te sepas su nombre y los argumentos que necesita, tan solo, con escribirla
directamente en la celda.

Como con las macros, nos preguntamos, para que servir tener funciones Publicas y
funciones Privadas?..., observa la funcin Nmeros a letras para que te des una idea, aunque
de nuevo, el seor Descartes nos puede ayudar...

Ahora si, Fin...

Descargar el cdigo de este artculo.


Option Explicit, Dim, que es eso?

Para este tema, doy por sentado que algunas vez has grabado, al menos, una macro, que has leido al menos
la Introducin que hay en esta pgina...
En la mayora de cdigo que veas en estas pginas, y en muchas otras macros que has visto, habrs notado
que al inicio de estas, casi siempre hay una pequea lnea de dos simples palabras, Option Explicit, las
seleccionaste, presionaste F1 y leste esto:
Se usa en el nivel de mdulo para forzar declaraciones explcitas de todas las variables en dicho
mdulo.
Esta comprendido?, si?, bueno, Fin del articulo...
Pero que antiptico te estas poniendo Mauricio, anda, explcalo mejor...
-De acuerdo, de acuerdo, tratar...Primero los ejemplos y despus las explicaciones

Entra Excel
Entra al EditorVBA
Inserta un nuevo mdulo y asegrate que este en vaco, si tiene las palabras que estamos estudiando,
brralas.
Teclea o copia la siguiente macro y pruebala
Public Sub Sumas()
Numero1 = Val(InputBox("Dame un nmero"))
Numero2 = Val(InputBox("Dame otro nmero"))
Suma = Numero1 + Numero2
MsgBox "La suma es: " & Format(Suma)
End Sub
Que bien, funciona verdad, ahora, vamos a suponer que tecleamos mal un nombre, por ejemplo, en
vez de teclear Numero1, tecleamos Numer1, para que nuestra macro quede as, por esta vez, pondr
en negritas los nombres que hay que probar...
Public Sub Sumas()
Numero1 = Val(InputBox("Dame un nmero"))
Numero2 = Val(InputBox("Dame otro nmero"))
Suma = Numer1 + Numero2
MsgBox "La suma es: " & Format(Suma)
End Sub
Prubala, funciona?, si, si funciona, solo que NO da el resultado correcto, en este caso, siempre nos
mostrara el valor del segundo nmero que le hayamos proporcionado, por qu?, sigamos con las
pruebas, ahora supondremos que los nmeros estn bien y que la que tecleamos mal es la palabra
Suma, la cual la tecleamos as; Sum
Public Sub Sumas()
Numero1 = Val(InputBox("Dame un nmero"))
Numero2 = Val(InputBox("Dame otro nmero"))
Sum = Numero1 + Numero2
MsgBox "La suma es: " & Format(Suma)
End Sub
Que bien!, tambin funciona, solo que tampoco nos da el resultado correcto, esta vez es peor, pues
siempre nos muestra cero, verdad?, bueno, la causa es ms que obvia, los nombres no los hemos
escrito correctamente y por correctamente me refiero a como escribimos esas mismas palabras en las
lneas anteriores o posteriores, pues aqu no vale la ortografa, para muestra una macro...
Public Sub Gardim()
arvol1 = Val(InputBox("Dame un nmero"))
lovo2 = Val(InputBox("Dame otro nmero"))
frrutas = arvol1 + lovo2
MsgBox "La suma es: " & Format(frrutas)

End Sub
Observa como alucine con los nombres de estas palabras, a parte de que estn mal escritas, no tienen
nada que ver con el propsito de nuestra macro, ya volveremos sobre este asunto ms adelante, por
ahora quise mostrarte el sentido de la palabra correctamente, y seguimos... Ahora, vuelve a nuestra
primer macro y agrega, en la parte superior, las palabras mgicas Option Explicit y trata de ejecutarla.
Option Explicit
Public Sub Sumas()
Numero1 = Val(InputBox("Dame un nmero"))
Numero2 = Val(InputBox("Dame otro nmero"))
Suma = Numero1 + Numero2
MsgBox "La suma es: " & Format(Suma)
End Sub
Que paso?, no te dejo?, porque?, que te aparece?... efectivamente, nos muestra un bonito
mensaje, que dice..

Y no solo eso, tambin nos colorea de amarillo la macro donde esta el error y nos selecciona la palabra
que esta mal, mejor dicho, la variable, djame repetirlo, la variable que NO hemos declarado.

Ahora tenemos una nueva palabra, variable ya sabes que tienes que hacer, presionar F1, buscar esta
palabra para encontrar...
Variable
Un lugar de almacenamiento con nombre que puede contener cierto tipo de datos. Cada variable tiene
un nombre nico que la identifica. Nombres de variable deben comenzar con un carcter alfabtico,
deben ser nicos dentro del mismo mbito, no deben contener ms de 255 caracteres y no pueden
contener un punto

Si leste la ayuda, notaras que no esta todo lo que dice ah, pues estoy haciendo un poco de trampita
como dira un amigo, la trampita es que no transcrib todo, si no solo lo que a mi juicio, es relevante
para este tema, as que vamos por partes...

Entonces, una variable es un lugar de almacenamiento con nombre, por ahora, es suficiente que
recuerdes esto, es muy importante, y... dnde esta es lugar de almacenamiento?, seoras y seores,
les presento a la seora RAM, bueno, no hace falta, todos la conocemos y la usamos, siempre que
prendemos nuestra maquina, verdad?, si, esa cosa llamada memoria RAM que por cierto ha subido
mucho de precio, pero en fin, ah, en al memoria RAM es el lugar de almacenamiento de nuestras
variables, pero tenemos que comunicarle al VBA que nos aparte un pedacito de memoria y que
adems le de un nombre para que sepamos donde esta, a la accin de reservar memoria para
nuestras variables, se le denomina Declaracin de variables o Dimencionar variables, para ello,
usamos otra nueva palabrita mgica, la instruccin Dim, modifica la macro para que se vea as...
Option Explicit
Public Sub Sumas()
Dim Numero1
Numero1 = Val(InputBox("Dame un nmero"))
Numero2 = Val(InputBox("Dame otro nmero"))
Suma = Numero1 + Numero2
MsgBox "La suma es: " & Format(Suma)
End Sub
Ejecutala y..., tampoco nos deja, y ahora que paso?, se detuvo de nuevo, pero ahora en otra variable,
pero nos muestra el mismo error, no es as?, bueno, pues ni modo, vamos a declarar nuestras
restantes variables..
Option Explicit
Public Sub Sumas()
Dim Numero1
Dim Numero2
Dim Suma
Numero1 = Val(InputBox("Dame un nmero"))
Numero2 = Val(InputBox("Dame otro nmero"))
Suma = Numero1 + Numero2
MsgBox "La suma es: " & Format(Suma)
End Sub
Y esta vez?, claro, ahora si funciona de nuevo, pero... qu ventaja percibes al declarar las
variables?, no es teclear ms solamente?, en este ejemplo manejamos tres variables y seria algo
difcil el escribir mal alguna, pero cuando empiezas a manejar, diez, veinte, cincuenta variables y no se
diga cuando empieza a combinar ms de una macro, funciones y otras cositas que ya veremos,
notaras todas las ventajas de Declarar explcitamente las variables pues el uso de Option Explicit
nos evita que usemos variables que antes, no las hayamos declarado.
Si lees la ayuda acerca de la instruccin Dim, leers que no solo es esta, sino que tiene muchas otras
variantes, tantas que nos saldramos del tema central de este articulo, pero te recomiendo que lo leas,
analices y ponga en practica, lo que si veremos es algo de suma importancia, transcribo...
Dim
Declara variables y les asigna espacio de almacenamiento

De esta definicin, ya debes de tener comprendida la primer parte Declara variables, la segunda no es
tan complicada asigna espacio de almacenamiento. Quedamos que nuestras variables quedan en la
memoria RAM, como sabes esta memoria es limitada y conforme se usa, hay la posibilidad de que se
acabe, lo cual es muy malo, as como dice la fsica, que materia es todo lo que ocupa un lugar en el
espacio, aqu, diremos que toda variable ocupa un espacio en la memoria, la pregunta es cunto
espacio?, la respuesta es, depende, nueva pregunta de que depende?, nueva respuesta, del tipo de
variable, (expresin de asombro), pero que hay varios tipos de variables?, respuesta si, cmo
cuales?, aqu van algunos: Byte, Boolean, Integer, Long, Currency, Single, Double, Date, String,
Object, Variant, cada uno de estos tipos, ocupa un lugar, tiene un tamao y puede contener una cierta
cantidad de informacin, cul es la mnima unidad de almacenamiento?, as es, 1(un) byte, entonces,
las variables, dependiendo su tipo, usan desde un byte y hasta?, esa es tu tarea...

Te estars preguntando, pero como le decimos que tipo de variable quiero usar?, y la respuesta es
muy sencilla, solo usamos otra palabrita mgica, As, seguida del tipo de variable que queramos
declarar, para muestra, declararemos correctamente nuestras variables...
Option Explicit
Public Sub Sumas()
Dim Numero1 As Integer
Dim Numero2 As Integer
Dim Suma As Integer
Numero1 = Val(InputBox("Dame un nmero"))
Numero2 = Val(InputBox("Dame otro nmero"))
Suma = Numero1 + Numero2
MsgBox "La suma es: " & Format(Suma)
End Sub
Todava ms preguntas, qu pasa si no le indico de que tipo es?, en nuestro ejemplo anterior funciono
bien, entonces?, cul es la diferencia?, la respuesta a esta interrogante, esta en la ayuda, as que
nuevamente, busca y lee un poquito, por lo pronto, acostmbrate a declarar explcitamente tus
variables, reitero, declara explcitamente TODAS tus variables y acostumbrate a que como primer
lnea, en cualquier mdulo de cdigo, tengas un Option Explicit, entre ms variables uses y mas
lneas de cdigo tengas, notaras cada vez ms, las grandes ventajas de esto.

Descargar el cdigo de este artculo.


Cmo puedo proteger un trabajo intelectual desarrollado en excel?.
Por Hctor Miguel Orozco Daz
La pregunta anterior se hace con cierta frecuencia en los foros pblicos de discusin y consulta (tanto en los de
Microsoft como en los "independientes"). Las respuestas siempre sern en relacin con el tipo y grado de
proteccin "deseada". La forma ms "fcil" de proteger en Excel (sin utilizar macros), es asignar una
contrasea ( "password") ya sea a la hoja, al libro, al archivo. Para los dos primeros casos, "basta" con usar el
comando Herramientas | Proteger | Proteger hoja... o Proteger libro...

Para proteger un archivo ("completo") contra apertura y/o escritura, usa el comando Archivo | Guardar como... |
Herramientas (BOTN AL FINAL) | Opciones generales.... En los dilogos mostrados por estos comandos,
podrs asignar la contrasea de tu preferencia y a los componentes que se habrn de incluir en la proteccin
que creas ms "convenientes" (se te solicitar una confirmacin).

Nota:

Las contraseas en Excel (y textos en VBA) son "sensibles" a la capitalizacin (maysculas


minsculas). NO ES LO MISMO "abc" QUE "aBc". Por lo tanto, si usas contraseas para proteccin de
tu trabajo... " QUE NO SE TE OLVIDE... RECORDARLAS !!!" (EXACTAMENTE COMO Y EN DONDE
LAS ASIGNASTE).

Sin embargo, brincar ( "crackear") las protecciones para la hoja y el libro (NO al archivo) es "sumamente fcil",
mediante macros que pueden inclusive ser usadas "desde otro" libro cualquiera (ohh... desilusin !!!).
Los siguientes cdigos hacen el "trabajo sucio":
Option Explicit
'** Para quitar password en protecciones a hojas ... **
Public Sub RemoverPasswordEnHoja()
ActiveSheet.Protect "", , , , True
ActiveSheet.Range("a1").Copy ActiveSheet.Range("a1")
End Sub
'** Para quitar password en protecciones a libros ... **
Public Sub RemoverPasswordEnLibro()
Dim Protecciones As Integer
If ActiveWorkbook.ProtectStructure = True Then Protecciones = Protecciones + 1
If ActiveWorkbook.ProtectWindows = True Then Protecciones = Protecciones + 2
Select Case Protecciones
Case 0: ActiveWorkbook.Protect "", False, False
Case 1: ActiveWorkbook.Protect "", True, False
Case 2: ActiveWorkbook.Protect "", False, True
Case 3: ActiveWorkbook.Protect "", True, True
End Select
ActiveWorkbook.Unprotect
End Sub

Para quitar password en protecciones a archivos ....


Esta proteccin "ya empieza" a ser difcil de brincar. Se requiere "apoyo" de algn software especializado (que
generalmente cuesta dinero) cuyas "versiones de prueba" (lase gratis) "rompen" contraseas con hasta un
mximo de 4 caracteres. Te sugiero que utilices contraseas "ms largas", inclusive puedes usar "mezclas" de
maysculas y minsculas, nmeros y caracteres especiales, como los que se obtienen de la combinacin de
las teclas {Alt} + teclado numrico como: {Alt}+174 = , {Alt}+0140 = , {Alt}+225 = , {Alt}+
(la_que_te_encuentres_simptica). Los caracteres que se "visualizan" dependen del tipo de letra que se usa.

USO DE MACRO-CDIGOS CON APOYO DE VBA.


Si quieres "llegar" a protecciones ms "sofisticadas", tendremos que "echar mano" de las macros, para lo cual,
enseguida se explicarn algunos "trucos" que, haciendo una "buena" combinacin de ellos te podrs acercar a
lo que pudiera considerarse como un "Sistema de Proteccin (casi) Perfecto".
Requisito INDISPENSABLE: Asignar tambin al proyecto VBA (macros) una contrasea.
SIGUE LAS SUGERENCIAS INDICADAS ANTERIORMENTE... Y OJO! CON LOS ACENTOS.
Toma en consideracin que una de las tareas ms "quema-neuronas" en cuestiones de programacin es:
o
o
o

"Anticipar" (en la medida de lo posible) las acciones del usuario para poder.
"Evaluar" las consecuencias de ejecutar un cdigo y finalmente.
"Disear" prevenciones o correcciones de errores "involuntarios" (o premeditados?).

La tcnica empleada para este ejemplo, es precisamente el uso combinado de varios "trucos", los cuales se
irn explicando en el curso de estos textos y cuya base principal es: "Mantener" el archivo grabado (en la
unidad de almacenamiento) SIEMPRE OCULTO Y CON CONTRASEA, para lo cual es imprescindible contar
con el apoyo de los eventos de la aplicacin para "detectar" algunas acciones del usuario y "actuar en
consecuencia".

ANALIZANDO LOS "INCONVENIENTES" (Y SOLUCIONES) DE USAR MACROS:>


Dado que el usuario tiene la opcin de decidir si un archivo se abre o no "con permiso" de usar macros puede
inclusive "mantener inoperables" los eventos (esto NO lo puedes evitar), las primeras acciones "preventivas"
sern:
1. Si se ha de abrir sin permiso de usar macros (por eleccin o alto nivel de proteccin) los eventos son
"inoperables" (en ese momento), hemos de asegurarnos que el archivo "se mantiene" OCULTO y con
"password" (en la unidad de almacenamiento).
2. Si las macros y los eventos "estn en operacin" (y se va a "permitir" su uso), hemos de EVITAR que
pueda grabarse el archivo (a la unidad de almacenamiento) de la manera "convencional", ya que podra
"volverse visible" y quedar completamente "desprotegido" para la siguiente vez que se abra (lo
haremos por cdigo mediante un procedimiento "especial").
3. Hemos tambin de prevenir (y corregir en su caso) que durante el curso de la sesin los eventos sean
"des-habilitados".
Estas acciones nos permiten darle al usuario "permiso de usar" el archivo "prcticamente" sin restricciones y
"tomar" el control de lo que podr o no "hacer" con l (y en l).
Algunas opciones que el usuario puede usar para "impedir" el uso de macros son:
o
o
o

"Tener" un nivel alto de proteccin "contra" archivos con macros.


"Elegir" NO ejecutar las macros del archivo (si el nivel es medio bajo).
"Mantener presionada" la tecla {Mays} (al abrir el archivo y "permitir" las macros).

En cualquiera de estos casos, las macros NO se ejecutan o "se omiten" las de apertura. Otra "forma" que
podra emplearse es: abrir el archivo mediante macros (en otro archivo) usando previamente la instruccin
Application.EnableEvents = False
"Contra" estas (y otras) opciones, nuestra primer accin preventiva prevalecer: el archivo (desde la unidad de
almacenamiento) "permanece" OCULTO Y CON CONTRASEA.
Ahora bien, cuando las macros "son permitidas" y los eventos "estn operables", podemos verificar que "se
cumplan" ciertas condiciones para permitir o no el uso de nuestro archivo.
Tales condiciones pueden ser -entre otrasA. Que el archivo est ubicado en algn directorio especfico -o uno "alterno"B. El nombre del usuario
C. Si existe algn archivo en ese u otro directorio
D. La fecha del sistema
E. El nombre mismo del archivo
F. Etc., etc., etc.
Podrs encontrar otras que "acomoden" mejor a tus necesidades. En caso de que las condiciones ("mnimas
necesarias") estn cumplidas, se dar acceso al archivo, en caso contrario, se tomarn otras acciones (como
permitirle "verlo sin usarlo" definitivamente cerrar el libro -entre otras-).
Si se permite el acceso al libro (total "restringido") para evitar que lo grabe de la manera "tradicional"
(segunda accin preventiva), "forzamos" a la aplicacin para que los mtodos "convencionales" de grabado "no
funcionen" y le proveemos de un "comando especial" que se encargar de que el archivo se grabe (a la unidad
de almacenamiento) SIEMPRE OCULTO Y CON CONTRASEA. Es por esto es que "nos tenemos que
asegurar" de que los eventos estn "siempre operables" (tercera accin preventiva).

ALGUNOS "TRUCOS" (COMBINABLES) POR CDIGO:


Para continuar con la exposicin de los ejemplos, "se dar por entendido" que se tiene al menos un
conocimiento "esencialmente bsico" en cuanto al uso del lenguaje Visual Basic para Aplicaciones (VBA) -la
plataforma en la que "trabajaremos"-, as como de los objetos, propiedades, mtodos, eventos, instrucciones y
"otros".
Para verificar que el archivo se encuentre ubicado en un directorio especfico, usamos la propiedad Path de un
objeto Workbook, que "devuelve" una cadena de texto indicando la ruta (unidad y directorio):
If ThisWorkbook.Path = "C:\Mis documentos\Otro directorio" Then
Para verificar el nombre del usuario, usaremos la propiedad UserName del objeto Application ("forzada" a
minsculas - maysculas-), que "devuelve" una cadena de texto con el nombre "registrado":
If StrConv(Application.UserName, vbLowerCase) = "fulanito de tal" Then
Para verificar si existe algn archivo en ese u otro directorio, existe el mtodo Dir("Ruta_ Archivo"), que
"devuelve" una cadena de texto con el nombre del archivo una cadena vaca ("") si no existe:
If Dir("Unidad:\Ruta1\Ruta2\NombreArchivo.ext") <> "" Then
Para comparar dos fechas, primero "tendremos" que identificar el orden de los elementos con la propiedad
International(xlDateOrder) del objeto Application, que "devuelve" un tipo de datos Long (0 = mes-da-ao; 1
= da-mes-ao; 2 = ao-mes-da), de lo contrario, un dato de fecha podra "significar" FECHAS DISTINTAS (en
sistemas "diferentes").
P.e.: La fecha "25 de Mayo de 2002" de un sistema "de origen" del orden 1 (da-mes-ao) si se quiere comparar
en un sistema "de destino" del orden 0 (mes-da-ao) "indicando" la fecha como "25/5/02" significar "Mayo 2
de 2025". Una estructuracin "confiable" sera:
Dim Fecha_x As Date
Select Case Application.International(xlDateOrder)
Case 0: Fecha_x = DateValue("5/25/02")
Case 1: Fecha_x = DateValue("25/5/02")

Case 2: Fecha_x = DateValue("02/5/25")


End Select
If Now <= Fecha_x Then

PRIMER PUNTO: TERCERA ACCIN "PREVENTIVA".


Una vez que "obtuvimos permiso" de usar las macros y estando los eventos "operables", puesto que uno de
ellos "detecta" la intencin del usuario de grabar el archivo "de manera convencional", aseguramos que los
eventos "permanezcan operables", utilizando para ello el mtodo OnTime del objeto Application, haciendo
una llamada "recursiva" al mismo mtodo una y otra vez (por el tiempo que dure la sesin) para "monitorear"
los eventos.
PRECAUCIN !!! - La ejecucin del mtodo OnTime de manera recurrente y programada, NO ES
CANCELADA "automticamente" por la aplicacin. Si el libro que la ejecuta es cerrado SIN CANCELAR LA
SIGUIENTE "LLAMADA", Excel volver a abrir el libro y continuar su ejecucin. ES NECESARIO
CANCELAR AL SALIR !!!.
Para lograr el efecto de "re-llamado" al mtodo, usaremos las variables Pblicas:
'Para el "siguiente monitoreo" de los eventos
Public MonitorEventos As Double
'Para monitorear los eventos cada 20 segundos (p.e.)
Public Const IntervaloMonitor As String = "0:00:20"
'Es el nombre de la macro que mantiene activos los eventos
Public Const MacroEventos = "MantenerEventos"
En los siguientes procedimientos:
'Macro de "prevencin" contra "suspensin" de eventos
Public Sub MantenerEventos()
'Mantiene siempre Activos los eventos
Application.EnableEvents = True
'(Re)-Inicia un bucle de "Activacin" cada "X" tiempo
ComenzarLoopDeEventos
'Fin del procedimiento
End Sub
'Macro de monitoreo "permanente" de Eventos
Public Sub ComenzarLoopDeEventos()
'Se determina el "siguiente monitoreo" de los eventos
MonitorEventos = Now + TimeValue(IntervaloMonitor)
'Una vez "llegado" el tiempo, "lanza" nuevamente el mtodo OnTime haciendo referencia
'a la variable pblica constante "MacroEventos" (macro "MantenerEventos") especificando
'que el siguiente "loop" se ejecute (Schedule:=True)
Application.OnTime _
EarliestTime:=MonitorEventos, _
Procedure:=MacroEventos, _
Schedule:=True
'Fin del procedimiento
End Sub
'Macro para "cancelar" el siguiente mtodo OnTime
'Este procedimiento se llamar "al cierre" del libro.
Public Sub DetenerLoopDeEventos()
'Necesariamente es igual al procedimiento de re-llamada, con excepcin de que

'"la siguiente vez" que el mtodo debiera ejecutarse se especifica como Falso.
MonitorEventos = Now + TimeValue(IntervaloMonitor)
Application.OnTime _
EarliestTime:=MonitorEventos, _
Procedure:=MacroEventos, _
Schedule:=False
End Sub
Una vez definidos los procedimientos, los "llamamos" en alguna macro de evento como Auto_Open (
Auto_Close) o los procedimientos de evento del objeto Workbook.
'Para iniciar (y mantener) el mtodo:
Private Sub Workbook_Open()
MantenerEventos
End Sub
'Para detener (y cancelar) el mtodo:
Private Sub Workbook_BeforeClose(Cancel As Boolean)
DetenerLoopDeEventos
End Sub

SEGUNDO PUNTO: SEGUNDA ACCIN "PREVENTIVA".


Ahora que los eventos "permanecern" activos, vamos a "impedir" que el archivo se grabe (a la unidad de
almacenamiento) de la manera "convencional" (ya sabemos que de esta manera podra "volverse visible" y
quedar completamente "desprotegido" para la siguiente vez que se abra).
Para esto ser necesario declarar una variable pblica del tipo Boolean (Verdadero Falso) como:
PermisoParaGrabar, que ser la que "impida" ( "permita") que el archivo sea grabado y usaremos el evento
Before_Save del objeto ThisWorkbook con una lnea como:
If Not PermisoParaGrabar = True Then Cancel = True
As le estamos "indicando" a Excel que siempre y cada vez que el usuario "pretenda" grabar el archivo, "NO se
lo permita". La variable ser usada como "candado" en el cdigo de nuestro "comando especial" para "abrir" el
permiso, grabar (de manera "correcta") y "cerrar" nuevamente el candado.

TERCER PUNTO: PRIMER ACCIN "PREVENTIVA".


Con los eventos activos y los comandos convencionales de grabacin "fuera del alcance" del usuario,
procederemos a "instruir" a Excel para que, a travs de un comando especial nos asegure que el archivo
SIEMPRE "permanecer" OCULTO Y CON CONTRASEA.
'Macro para guardar los cambios (slo por cdigo)
Public Sub GuardarEspecial()
'Congelamos la actualizacin de la pantalla
Application.ScreenUpdating = False
'La variable que "permite" o "impide" grabar el archivo
PermisoParaGrabar = True
'Ocultamos la ventana del libro protegido
Windows(ThisWorkbook.Name).Visible = False
'Protegemos el libro con Contrasea
'(inclusive su estructura y "arreglo" de ventanas)
ThisWorkbook.Protect Password:="X_Contrasea", _
Structure:=True, Windows:=True
'Grabamos el libro (a la unidad de almacenamiento)
ThisWorkbook.Save

'"Cancelamos el permiso" que da la variable


PermisoParaGrabar = False
'Fin del procedimiento.
End Sub
Una macro como la anterior har "un excelente trabajo", slo faltara "detectar" si el libro "contina en
operacin" (para volverlo a "presentar" al usuario cerrarlo si fuera el caso).
El siguiente paso es: "Agregar" el comando a algn men (o submen), "aprovechando" el evento Open del
objeto ThisWorkboook, agregando la siguiente lnea: AgregarComando., que "hace referencia" a la siguiente
macro:
'Macro para agregar el Comando "Especial"
Public Sub AgregarComando()
'Se agrega un comando TEMPORAL en la posicin # 8 del men de "Archivo" y ...
Set MiComando = CommandBars("File").Controls.Add _
(Type:=msoControlButton, Before:=8, Temporary:=True)
With MiComando
.BeginGroup = True
.Style = msoButtonCaption
.Caption = "Guardar &especial"
.FaceId = 1
'Lo mandamos ejecutar la macro de "GuardarEspecial"
.OnAction = "GuardarEspecial"
End With
'Fin del procedimiento
End Sub
Finalmente (y slo "por si las dudas"), al salir del libro eliminaremos este comando usando el evento
Before_Close del objeto ThisWorkbook con la siguiente instruccin:
If Application.CommandBars("File").Controls(8).Caption = "Guardar &especial" _
Then Application.CommandBars("File").Controls("Guardar &especial").Delete (True)

NOMBRE Y POSICIN DE LOS OBJETOS.


Generalmente se usan las propiedades Name Index (posicin) para "referirnos" por cdigo a las hojas de un
libro, p.e.
Worksheets("Resumen")
Worksheets(3)
Si el usuario "modifica" estas propiedades (cambiando nombre o posicin), el cdigo fallar lanzando "el
temido" mensaje de: "Subndice fuera del intervalo", estaremos "afectando" a la hoja que "qued" en la
posicin #3 y "creamos" que era... "la que estaba antes???".
Para efectos "prcticos", es mejor el uso de la propiedad "Name", inclusive puedes "regresar" la hoja a su
nombre "original" en algn evento (como Worksheet_Deactivate) con una lnea como la siguiente:
If Hoja3.Name <> "Resumen" Then Hoja3.Name = "Resumen"
Habrs notado que se utiliza Hoja3.Name. Hoja3 es el nombre-cdigo (propiedad CodeName) que cada objeto
tiene en el proyecto de VBA (en este caso "veras" en la ventana de exploracin del proyecto, un objeto
Worksheet como - Hoja3 (Resumen) y en la ventana de propiedades, las propiedades: (Name) = Hoja3 y
Name = Resumen.
Pues bien, la propiedad CodeName es an ms "conveniente" que la "simple" propiedad "Name" para el caso
de "asegurarnos" que no afecte al cdigo si el usuario cambia las propiedades "Name" e "Index" de los objetos
sobre los que necesitamos un "control total".

PROTECCIONES "ADICIONALES" PARA "CELDAS ESPECIALES".

Si ya has usado Herramientas | Proteger | Proteger hoja... y/o Proteger libro..., te habrs dado cuenta de que
"se debe quitar" la proteccin cuando necesitas hacer modificaciones por cdigo a las hojas "protegidas" por
este comando.
Otra manera de "evitar" que el usuario modifique "celdas importantes" es (aprovechando nuevamente los
eventos y cdigo), "detectar" si el usuario selecciona alguna de esas celdas y "pedirle una clave" (para
"permitirle estar ah" "remitirlo" a otra celda). El siguiente cdigo en el evento SelectionChange de un objeto
Worksheet le pedir esa clave al usuario si selecciona alguna de las celdas que se indiquen como
"especiales":

Private Sub Worksheet_SelectionChange(ByVal Target As Range)


Dim Permiso As String
Select Case Target.Address
'Si el usuario selecciona "B6" "B18"...
Case Range("B6").Address, Range("B18").Address
'Se le "pide" una clave.
Permiso = InputBox("Cul es tu clave?")
'Si la clave es "incorrecta" lo "mandamos" arriba.
'(Podras "avisarle" que... NO es la clave K !!!)
If Permiso <> "Hocus Pocus" Then Target.Offset(-1, 0).Select
End Select
End Sub

IMPEDIR QUE EL USUARIO UTILICE "ALGUNOS" COMANDOS.


Habr ocasiones en las cuales "quisieras" que el usuario no pueda "copiar | cortar | pegar" datos "de" ni "a"
ciertas celdas, hojas o libros.
1. - Una manera sera "inhabilitar" el modo "Cortar/Copiar" de la aplicacin ("imperceptible" para el
usuario), usando algn evento (SelectionChange, Activate, Deactivate) de los objetos Worksheet
Workbook con la siguiente lnea:
2. Application.CutCopyMode = False
para "simular" el efecto de presionar {Esc} ("al momento de" copiar cortar) "cancelando" de la
memoria el contenido del "porta-papeles".
3. - Otra manera sera "inhabilitar" los "atajos de teclado" como {Ctrl}+C, {Ctrl}+X, {Ctrl}+V utilizando para
ello el mtodo OnKey del objeto Application en cualquiera (o varios) de los eventos mencionados en
el prrafo anterior.
La sintaxis del mtodo es:
Application.OnKey "Tecla", "Procedimiento"
Donde: argumento Tecla es la tecla (o combinacin de teclas) que al ser presionada(s) "ejecutar(n)" la macro
especificada por el argumento Procedimiento. Si se omite el procedimiento, la(s) tecla(s) "vuelve(n)" a su
accin natural.
Por ejemplo, para impedir que se usen esas combinaciones de teclado en una hoja en especfico, los
siguientes cdigos "trabajan" bien:
'Cuando el usuario "activa" la hoja (con el cdigo)...
Private Sub Worksheet_Activate()
'Los "atajos de teclado" {Ctrl}+C, {Ctrl}+X, {Ctrl}+V
'para "copiar", "cortar" y "pegar" quedan "inhabilitados"
'puesto que se especifica un argumento "vaco" para "la macro".

Application.OnKey "^c", ""


Application.OnKey "^x", ""
Application.OnKey "^v", ""
End Sub
'Cuando el usuario "des-activa" la hoja (con el cdigo)...
Private Sub Worksheet_Deactivate()
'Los "atajos de teclado" {Ctrl}+C, {Ctrl}+X, {Ctrl}+V
'para "copiar", "cortar" y "pegar" quedan "re-habilitados"
Application.OnKey "^c"
Application.OnKey "^x"
Application.OnKey "^v"
End Sub
Nota: El mtodo OnKey (usado de la manera anterior) NO IMPIDE el uso de los comandos (por mens o
botones) para efectuar las mismas acciones de "copiar", "cortar" y "pegar".
Si quieres "impedir" que se usen "tambin" comandos "integrados" de Excel, entonces...

OPCIONES "AVANZADAS" PARA TRABAJAR CON MENS Y COMANDOS


"Asegurar" un control de los comandos (sean barras de mens y/o herramientas) implica "averiguar" que tanto
se han personalizado en el "entorno" de cada usuario. Considerando que los mens pueden contener
submens y stos a su vez ms submens se debe desarrollar una macro que pueda "ir descendiendo" a todos
los niveles de todos los elementos existentes. Una vez "detectados" los comandos "objetivo", una propiedad
(Enabled o Visible) habr de permitir (o no) su uso.
Utilizaremos las siguientes variables Pblicas:
'Declaramos las variables del tipo "necesario"...
Public Barra As CommandBar, _
Comando As CommandBarControl, _
Contenedor As CommandBarControl, _
Siguiente As Integer
En los siguientes procedimientos | funciones:
'Macro para "Des-Habilitar" comandos
Private Sub DesHabilitarComandos()
'Por si existiera algn error
On Error Resume Next
'Para buscar en TODAS las barras (Herramientas Mens)
For Each Barra In Application.CommandBars
'Para buscar en TODOS los controles (Comandos Submens)
For Each Comando In Barra.Controls
'Inicia un "bucle" de bsqueda (a travs de una funcin "recursiva")
Siguiente = AtenuarProhibidos(Comando)
'"Busca" en el siguiente botn
Next Comando
'"Busca" en la siguiente Barra de Comandos
Next Barra
'Fin del procedimiento
End Sub
'Funcin "recursiva" para "bajar" por los mens
Private Function AtenuarProhibidos(Comando As CommandBarControl) As Integer
'Por si existiera algn error
On Error Resume Next

'"Inicializa" la variable del bucle


Siguiente = 0
'Para "afectar" slo a Comandos Mens
Select Case Comando.Type
Case 1, 2, 4, 6, 7, 13, 18
'Si es un botn de comando...
Select Case Comando.ID
'"Ver" cul es
Case 19, 21, 22
'Si es "copiar", "cortar" "pegar"
Comando.Enabled = False 'Lo "DES-HABILITA"
End Select
Case Else
'Si es un Men ( Submen)
'... seguir buscando "ms abajo"
For Each Contenedor In Comando.Controls
'... haciendo una "Re-Llamada" de la funcin
Siguiente = Siguiente + AtenuarProhibidos(Contenedor)
Next Contenedor
'(continuar con el "bucle")
Siguiente = Siguiente - 1 '(regresar al bucle en el mismo control)
End Select
'y ...
'continuar "la llamada" a la funcin con "el siguiente"
AtenuarProhibidos = Siguiente + 1
'Fin de la funcin
End Function
Aunque es posible que este procedimiento sea "auto-alternante" (podra cambiarse en la funcin la sentencia:
Comando.Enabled = False
por una que "auto-invierta" el estado del botn +/- as:
If Comando.Enabled = True Then Comando.Enabled = False Else Comando.Enabled = True
para un control "ms estable" es mejor "definir" procedimientos "separados" (uno para inhabilitar y otro para rehabilitar los botones de comando). Dejo a tu criterio "la contra-parte".
Complementariamente (y para NO "perjudicar" la interaccin con el usuario) puedes usar los eventos
WindowActivate y WindowDeactivate del objeto ThisWorkbook para que, los comandos queden
inhabilitados "solamente" cuando la ventana "activa" sea "el libro".
Private Sub Workbook_WindowActivate(ByVal Wn As Window)
DesHabilitarComandos
End Sub
Private Sub Workbook_WindowDeactivate(ByVal Wn As Window)
ReHabilitarComandos
End Sub
Puedes incluir adems en los procedimientos, las opciones del usuario para "personalizar" las barras de mens
y herramientas para que "sufran" el mismo efecto que lo botones. De esta manera, podr agregar ms barras
(con los botones y mens que "no funcionan") siempre y cuando la ventana "activa" sea "otro libro", pero... al
"regresar" a nuestro libro... dejarn de "funcionar" tambin!!!
Para mayor informacin acerca de las "ID's" ( nombres) de otros comandos y mens que pudieras considerar
como "necesarios" de inhabilitar para proteccin de tu trabajo, visita la pgina:
http://support.microsoft.com/support/kb/articles/Q213/5/52.ASP
Otra accin "conveniente" de controlar es el uso del comando "especial" de guardar, para lo cual puedes
aprovechar los mismos eventos WindowActivate para "permitir su uso slo en el libro" con la lnea:
Application.CommandBars("File").Controls("Guardar &especial").Visible = True
y el evento WindowDeactivate para "inhabilitar" su uso "fuera del libro" con otra lnea "inversa" como:
Application.CommandBars("File").Controls("Guardar &especial").Visible = False
Bueno... dejemos de momento tanta "palabrera", y pasemos a un...

CASO "PRCTICO" DE LA COMBINACIN DE ALGUNOS TRUCOS

El archivo "descargable" (al final de este artculo) contiene algunos ejemplos de cmo proteger (por cdigo) los
libros de Excel. Te explico "brevemente" como funciona y cuales son las condiciones, contraseas y "opciones"
consideradas.
1. Condiciones
A. Con las macros "habilitadas" y los eventos "operables", el libro se abrir "sin problemas" si se
cumple cualquiera de las dos primeras condiciones siguientes:
I.
Que el directorio donde se encuentra sea: "C:\Mis documentos" o...
II.
Que el directorio "alterno" sea: "D:\Personales\..." (el que yo utilic). (Obviamente
puedes definir tus propias condiciones como se explic antes.)
III.
O, si se abre desde otro directorio, avisar que las condiciones de operacin no se
cumplen y sugerir "No Continuar" (aunque da la opcin de "seguir adelante", se abrir
en modo de "slo lectura", y... NO "se puede" guardar).

B. Si las macros NO estn "habilitadas" (por eleccin o nivel alto de proteccin), o se "abre por
cdigo" pero los eventos NO estn "operables" (Open, Change, etc.), el libro se abrir, pero
estar OCULTO y con Contrasea.
Una vez abierto el libro "sin problemas", solo puede grabarse a travs del comando que se
agrega automticamente ("Guardar especial" en el men "Archivo"), de esta manera (an
cuando la PC "-???-...se apag!!!") siempre queda "bien" guardado.

2. Contraseas (Recuerda lo de maysculas, minsculas, acentos y/o signos)


A. Para el libro y la hoja "Protegida", la contrasea es: Contrasea (el signo es la combinacin
de teclas {Alt}+174).
B. Para el proyecto de macros (VBA) es: Contrasea (mismo signo).
C. En la hoja "Protegida", algunas de las celdas "libres" requieren de un "Permiso especial" (con
un formulario). La clave: Abrete Ssamo
D. Existe una hoja oculta en el libro (podras manejar ah datos "Ultra-Secretos") que SOLO puede
mostrarse mediante una imagen (con macro) en la hoja "Normal" y tambin requiere de un
"Permiso especial". La clave: Abracadabra.

3. Como proteccin adicional, todos los cdigos son Privados (no se pueden ver en la "lista de macros"
men Herramientas | Macro | Macros teclas {Alt}+{F8}. El mtodo OnTime "monitorea" que los
Eventos "permanezcan activos", por si a algn "vivillo" se le ocurriera des-habilitarlos para "ver como
funciona". Puedes eliminar ste mtodo si te resulta "engorroso" ver un ligero parpadeo del cursor cada
20 segundos ( el tiempo que determines) si lo consideras no necesario. Slo "asegrate" de hacerlo
"correctamente".
4. La estructura de cdigos es "modulada" (y en orden de aparicin) para que se puedan usar
"interactivamente" y son "funcionales" (si los ejecutas desde la ventana del VBE). Cada lnea est
"comentada" para que sea entendible y clara su intencin. Espero que no tengas problemas para
entenderlo.
5. Nota 1.- Cuando la ventana activa es este libro, TODOS los comandos "peligrosos" se des-habilitan (se
restablecen cuando el libro deja de ser la ventana activa).
Nota 2.- Si creas nuevas barras con comandos "prohibidos" (o los agregas a las ya existentes), de
cualquier forma al activar de nuevo la ventana del libro se des-habilitarn.
6. La lista que consider como comandos "peligrosos" es la siguiente (puede modificarse a tu criterio):
En el men (o Sub-men)
Estos comandos SE INHIBEN DE TODAS LAS BARRAS
"Edicin"...
Eliminar hoja; Copiar o mover hoja
"Edicin"... "Eliminar"...
Eliminar (celdas); Eliminar filas; Eliminar columnas
"Formato"...
Formato de celdas (por la pestaa de "proteccin")
"Formato"... "Hoja"...
Cambiar nombre; Ocultar; Mostrar
"Herramientas"...
Ver Nota 2 Personalizar (por si creas barras con "ms prohibidos")
"Herramientas"... "Proteger"... Proteger hoja; Proteger libro; Proteger y compartir
"Datos"...
Ordenar; Validacin
"Ventana"...
Ocultar; Mostrar
La lista de barras
"Toolbar List" (por aquello del comando "Personalizar")
7. Visita la pgina de Microsoft indicada anteriormente para ver una lista de otros comandos que pudieras
considerar como "peligrosos".
8. Saludos cordiales, y espero "haber sido de utilidad" para tus propsitos.
9. Hctor Miguel Orozco Daz. hemiordi@hotmail.com
10.
11. Descargar el archivo Proteger.zip que contiene el archivo Proteger.xls con todo el cdigo
mostrado en este artculo.
12.
13. Nota de Mauricio: Les agradeceria mucho a mis visitantes y como agradecimiento por el gran
trabajo de Hctor, le notificaran a su correo, de cualquier error, duda, mejora, observacin o
comentario en relacin con el presente artculo, GRACIAS Hctor...
Variables y objetos, como nombrarlos?

Supongamos una sencilla macro como la siguiente


Option Explicit
Public Sub Preguntas()
Dim Nombre As String
Dim Edad As Integer

Nombre = InputBox("Cul es tu nombre?")


Edad = InputBox("Cuantos aos tienes?")
MsgBox "Hola " & Nombre & " tienes " & Edad & " aos"
End Sub
Public Sub Preguntas1()
Dim Coche As String
Dim Sol As Integer
Coche = InputBox("Cul es tu nombre?")
Sol = InputBox("Cuantos aos tienes?")
MsgBox "Hola " & Coche & " tienes " & Sol & " aos"
End Sub

Descargar el cdigo de este artculo.


Grabando mi primer macro en Excel
Te sugiero que primero realices los pasos que menciono aqu y despus, con toda libertad y confianza haz
todas las pruebas que consideres pertinentes
o
o
o

Entra a Excel
Ve al men Herramientas | Macro | Grabar nueva macro...
Te saldr el siguiente cuadro de dialogo...

Los datos que hay que introducir son:


Nombre de la macro

Con este nombre identificaremos a la macro, con este la podemos "ejecutar" y "llamar" desde otras
macros, por default te saldr Macro1 la primera vez y, si no cambias este nombre, a las sucesivas
macros las ira nombrando Macro2, Macro3, Macro'n, etc, propongo que se llame Mi_Primer_Macro ,
las recomendaciones son: usa un nombre corto, pero suficientemente claro en relacin con la tarea o
tareas que har la macro, NO uses espacios, por ejemplo, si tienes una macro que realiza un reporte,
podras llamarla:
1. hacerreporte
2. HACERREPORTE
3. hacer_reporte
4. HACER_REPORTE
5. Hacer_Reporte
6. HacerReporte

Comnmente, y lo veraz en estas pginas, uso la opcin 5 o 6 pues me parecen mas claras de leer,
pero no te detengas en hacer uso de tu libre derecho de usar el que te de la gana.
Mtodo abreviado
Si sabes para que nos sirve Ctrl + C o Alt + F4 , entonces ya sabes para que es esta opcin, as es,
bien pensado, sirve para relacionar una combinacin de teclas con la macro que estamos grabando y
ejecutarla con solo presionar estas teclas, en lo personal no lo uso, pues ya tengo bastante con las
decenas de mtodos abreviados que tiene Windows, prefiero "asignarlas" a un botn o un men (te
enseare a hacer esto), pero estas en todo tu derecho de usarla si as lo deseas.
Guardar macro en
Toda la informacin ocupa un lugar, verdad?, pues las macros son informacin y ocupan lugar y hay
que guardarlas en algn lado, este lado, son los archivos de Excel, es decir, "dentro" del archivo, se
guardan las instrucciones en un lugar especial que se llama modulo , que aprenderemos a dominar, si
observas la imagen, tenemos un Cuadro de lista desplegable o ComboBox (as se llama este "objeto")
que tiene tres opciones: Libro de macros personal, Libro nuevo y Este libro, como veras, los tres son
libros o sea, archivos de Excel, las macros de Excel solo pueden estar dentro de archivos de Excel.
Para nuestro ejemplo escogeremos Este libro.
Descripcin
Creo que el nombre es bastante "descriptivo", aqu puedes poner toda la informacin que consideres
conveniente acerca de tu macro, su funcin ms til, es comentar brevemente cual es el propsito de
nuestra macro, algunos ponen la fecha y el nombre del autor.
Damos un clic en el Botn de Comando (CommandButton) ACEPTAR , a partir de este momento, casi
cualquier accin, lo repito, casi cualquier accin que realices sobre la ventana de Excel, se grabar en
nuestra macro, por eso las recomendaciones antes de grabar una macro son:
1. Planea lo que hara tu macro, las correcciones que hagas, tambin se grabaran.
2. Casi nunca una macro queda a la primera, no importa que repitas de nuevo los pasos, pero
hazla bien, cuando aprendas a editarlas, veremos como quitar lo que no sirve.
3. Procura no grabar demasiadas instrucciones, es mejor grabar pequeas macros y despus
llamarlas desde otras o entre si, esto, ya veremos como se hace.

Realiza los siguientes pasos tal cual...


Selecciona la celda A1
Escribe "Esta es mi primer macro" (o lo que gustes).
Presiona Enter, si tu seleccin se movi abajo (normalmente), entonces vuelve a seleccionar la
celda A1
Dale formato de Negritas , Cursiva , cambia el tamao de la fuente, el estilo de la fuente y
por ultimo el color de la fuente
Al final se tiene que ver algo muy parecido a esto:

Da un clic en el botn Detener grabacin , este botn (que aparece en la imagen de arriba) se
encuentra dentro de la barra de herramientas Detener Grabacin, esta barra se visualiza (o deberia de
aparecer) en cuanto empiezas a grabar una macro, si no la vez, ve al men Ver | Barra de
Herramientas y activa la barra Detener Grabacin o si lo prefieres, en el men Herramientas | Macro
veraz, en vez de Grabar Macro , la opcin Detener Grabacin , esto solo cuando tienes activada la
grabadora de macros.
Ahora, probemos la macro, borra o mejor, elimina la celda donde escribiste el texto Esta es mi primer
macro, en nuestro ejemplo, se trata de la celda A1.
Ve al men Herramientas | Macro | Macros... o presiona el mtodo abreviado de teclado Alt + F8 , por
cualquiera de estos dos mtodos, te saldr el siguiente cuadro de dialogo.

La imagen lo dice todo, tendras una lista de las macros que esten disponibles en los libros (archivos de
Excel) abiertos, es decir, para que puedas ejecutar una macro, el libro que la contiene debe estar

abierto. Este cuadro de dialogo tiene ms opciones que el anterior, as que las que no se vean aqu, te
dejo de "tareita" investigues para que sirven.

Selecciona la macro que acabamos de grabar, si no le cambiaste el nombre debe decir Macro1 , si
usaste el propuesto ser Mi_Primer_Macro o en su defecto el que hayas escogido, si tienes ms libros
abiertos que tengan macros, aqu las veraz (no todas, ya te explicare por que), da un clic en el Boton
de Comando (CommandButton) EJECUTAR .
Que pas?, se ve bonito no?, ahora, con un solo paso, hacemos varias instrucciones de Excel, si fue
as?, bien, ahora ya tenemos el 0.01 % de lo necesario para dominar las macros y no te estoy
desanimando, al contrario, pretendo, con estas pginas, subir un poco mi 5% de dominio y tambin
pretendo, que lo hagamos juntos, si estas de acuerdo sigue leyendo y sino tambin sigue leyendo.
Este es un buen momento para guardar tu archivo, propongo que se llame Mis macros , pero, como
antes, puedes usar el nombre que gustes como podra impedrtelo?.
Ahora van las preguntas, lo siento pero te tendrs que acostumbrar a ellas, aun cuando veas que trato
a detalle los temas, no es as, por que el tema es bastante extenso y muchas cosas las tendrs que
buscar, descubrir y mejor aun, razonar por tu cuenta.
Todo sali bien ?
Que pasa si ahora pongo el cursor, o sea la seleccin en otra celda, por ejemplo la C15 y
ejecuto la macro?
Prueba a grabar otra macro, pero activa el botn que aparece al lado del Detener grabacin y
que se llama Referencia relativa y haz la prueba anterior, que pasa ahora?
Si cambias de hoja en el libro puedes ejecutar la macro?
Y si cambias de libro aun la puedes ejecutar?
Prueba a grabar una macro que cambie a otras ventanas fuera de Excel o abra otros
programas es posible?
Graba una macro un poco mas larga y ejectala que observas?, como se ve la pantalla
cuando se esta ejecutando?
Tal vez pienses que son muchas preguntas para la primera vez, ya veraz que solito te saldrn mas,
ahora mismo yo tengo ms preguntas que respuestas, pero no importa, sigue siendo muy divertido
crear y grabar macros. Cuando tengas contestadas las preguntas anteriores y cuando hagas las
"tareitas" que propongo, entonces, pasamos al siguiente punto.
Esto es ms interesante, veamos las instrucciones que graba Excel a estas instrucciones se le conoce
como cdigo fuente , para esto ve la men Herramientas | Macro | Macros... o presiona el mtodo
abreviado de teclado Alt + F8 y ya sabes que sale verdad?, si, el cuadro de dialogo Macro , de nuevo,
selecciona la primer macro que grabaste y que ejecutaste, pero ahora, en vez de ejecutarla, presiona el
Botn de Comando (CommandButton) MODIFICAR . Esta accin abrir una nueva ventana (la notaras
en la barra de tareas de Windows) y nos llevara a una ventana que tal vez nunca has visto, esta
ventana se llama Microsoft Visual Basic y es una nueva aplicacin, un programa, correctamente es un
Editor, un Editor del lenguaje Visual Basic para crear nuestras macros, tambin puedes abrir esta
ventana desde el men Herramientas | Macro | Editor de Visual Basic o presiona el mtodo abreviado
de teclado Alt + F11 , este Editor tienes que dominarlo si quieres obtener ms provecho de tus macros,
ms adelante veremos las partes principales de este Editor, por lo pronto y si grabaste la macro de
ejemplo, veraz algo muy similar a la siguiente imagen.

Las ventanitas que estn a la derecha de la imagen, tal vez las tengas a la izquierda en tu ventana,
pero no importa, estas ventanas las puedes mover como la mayora de las ventanas de Windows
(desde la barra de titulo) y posicionar donde gustes, te recomiendo dejarlas como en la imagen de
arriba, para que nos entendamos mejor.

Te pongo el cdigo aqu por si en la imagen no se ve bien, adems de que le faltan unas lneas abajo.
Sub Mi_Primer_Macro()
'
' Macro1 Macro
' Macro grabada el 09/01/2002 por Tecnico1
'
Range("A1").Select
ActiveCell.FormulaR1C1 = "Esta es mi primer macro"
Range("A1").Select
Selection.Font.Bold = True
Selection.Font.Italic = True
With Selection.Font
.Name = "Arial"
.Size = 20

.Strikethrough = False
.Superscript = False
.Subscript = False
.OutlineFont = False
.Shadow = False
.Underline = xlUnderlineStyleNone
.ColorIndex = xlAutomatic
End With
With Selection.Font
.Name = "Comic Sans MS"
.Size = 20
.Strikethrough = False
.Superscript = False
.Subscript = False
.OutlineFont = False
.Shadow = False
.Underline = xlUnderlineStyleNone
.ColorIndex = xlAutomatic
End With
Selection.Font.ColorIndex = 5
End Sub
Ya la viste bien, verdad que hay lneas repetidas?, porque crees que sea esto?, observa muy bien
los colores, nos dicen mucho, pero lo primero que te enseare de los colores es que las lneas que
estn en verde no se "ejecutan" , esto quiere decir, que el VBA se las salta olmpicamente, las ignora
completamente, esas lneas verdes se llama comentarios y sirven para documentar nuestras macros
para poner notas acerca del propsito o funcionamiento del cdigo, algo muy importante, pues despus
de algunos cientos de lneas, ya ni sabes donde vas o para que serva determinada lnea, por ejemplo,
observa la primer lnea despus de la ultima verde, si quisiramos comentarla, o sea, establecerla de
modo que no se "ejecute", tenemos dos formas, agregando una comilla simple a la izquierda de la lnea
o escribiendo, tambin a la izquierda la palabra REM, me parece ms fcil la comilla no crees?.
Sub Mi_Primer_Macro()
'
' Macro1 Macro
' Macro grabada el 09/01/2002 por Tecnico1
'
Range("A1").Select
'Range("A1").Select
Rem Range("A1").Select
Ahora que sabes como se comentan las lneas para que el VBA no las ejecute, te recomiendo que
cuando ests probando cdigo, no lo borres, mejor solo comenta la lnea, pues algunas veces pasa
que regresamos a la lnea original y si la borramos en ocasiones ya no sabemos como iba, as que te
pregunto, que lneas de este cdigo fuente, se podran comentar, de modo que no se ejecuten, pero
que la macro siga haciendo lo mismo?... muy bien, podra quedar as...
Sub Mi_Primer_Macro()
' Macro grabada el 09/01/2002 por Tecnico1
'
Range("A1").Select
ActiveCell.FormulaR1C1 = "Esta es mi primer macro"
Range("A1").Select
Selection.Font.Bold = True
Selection.Font.Italic = True

'With Selection.Font
' .Name = "Arial"
' .Size = 20
' .Strikethrough = False
' .Superscript = False
' .Subscript = False
' .OutlineFont = False
' .Shadow = False
' .Underline = xlUnderlineStyleNone
' .ColorIndex = xlAutomatic
'End With
With Selection.Font
.Name = "Comic Sans MS"
.Size = 20
.Strikethrough = False
.Superscript = False
.Subscript = False
.OutlineFont = False
.Shadow = False
.Underline = xlUnderlineStyleNone
.ColorIndex = xlAutomatic
End With
Selection.Font.ColorIndex = 5
End Sub
Pero todava se puede mejorar ms, prueba a comentar las lneas que terminen en la palabra False
para que nuestro cdigo quede as:
Sub Mi_Primer_Macro()
' Macro grabada el 09/01/2002 por Tecnico1
'
Range("A1").Select
ActiveCell.FormulaR1C1 = "Esta es mi primer macro"
Range("A1").Select
Selection.Font.Bold = True
Selection.Font.Italic = True
'With Selection.Font
' .Name = "Arial"
' .Size = 20
' .Strikethrough = False
' .Superscript = False
' .Subscript = False
' .OutlineFont = False
' .Shadow = False
' .Underline = xlUnderlineStyleNone
' .ColorIndex = xlAutomatic
'End With
With Selection.Font
.Name = "Comic Sans MS"
.Size = 20
' .Strikethrough = False
' .Superscript = False
' .Subscript = False
' .OutlineFont = False
' .Shadow = False
.Underline = xlUnderlineStyleNone
.ColorIndex = xlAutomatic
End With
Selection.Font.ColorIndex = 5
End Sub

Sigue haciendo lo mismo la macro?, si?, pues entonces vamos bien, con esto te dars cuenta que, la
mayora de las veces, la grabadora de macro nos escribe mucha "basura", es decir, cdigo de ms,
cdigo innecesario para nuestra macro, lo complicado es saber que quitar y que no, incluso que
agregar y que no, ojal que con todos los ejemplo que haya aqu, te sea ms leve esta tarea. Por
ultimo, te escribir una segunda versin de esta macro, la llamaremos Mi_Primer_Macro2 , regla, no
puede tener dos macros en el mismo modulo de cdigo, que tengan el mismo nombre , no lo
olvides, esta segunda versin, esta basada completamente en la original, tu "tareita" es decirme cuales
son las diferencias, claro, aparte del nmero de lneas, hice lagunas "trampitas", observa las primeras
lneas, observa las lneas que se quitaron y las que se modificaron, las que se movieron y las que se
dejaron tal cual, de acuerdo?...
Sub Mi_Primer_Macro2()
' Macro modificada por mi
ActiveCell.FormulaR1C1 = "Esta es mi primer macro, claro, con algunos cambios"
With Selection.Font
.Bold = True
.Italic = True
.Name = "Comic Sans MS"
.Size = 20
.ColorIndex = 5
End With
End Sub
Se me pasaba comentarte que puedes hacer todas las macros que quieras dentro de un mismo
modulo, lo nico que tienes que hacer es procurar separarlas por una lnea, como se que eres
observador, habrs notado que todas las macros empiezan con Sub y terminan con End Sub , pues as
son las macros, por ejemplo, podras tener esto:
Sub CopiarDatos()
' Aqui va el cdigo de esta macro
End Sub
Sub HacerReporte()
' Aqui va el cdigo de esta macro
End Sub
Sub HacerGrafico()
' Aqui va el cdigo de esta macro
End Sub

Ahora hagamos algo muy interesante, grabaremos nuestra segunda macro, pero con una pequea
variante, iremos viendo como es que Excel, va grabando las instrucciones dentro de un modulo en el
Editor de Visual Basic, para lograrlo abramos el Editor de Visual Basic, ya sabes como verdad?,
redimensiona y manipula las ventanas, tanto de Excel como del Editor, para que ocupen,
aproximadamente la mitad de la pantalla cada una, cuida , que la pantalla de Excel quede en primer
plano y en segundo plano el Editor de Visual Basic, cuidado , si en la ventana del Editor, no esta
visible el MODULO donde se estn grabando las macros no veraz nada, tienes que poner el cursor
dentro del modulo actual para que veas la grabacin, para que no haya duda, ve la siguiente imagen:

Observa como Excel esta en primer plano y el Editor en segundo plano, si estas en la misma sesin de
trabajo, donde grabaste Mi_Primer_Macro , entonces solo deja el cursor dentro del modulo donde est,
esta macro, si estas usando otra sesin de trabajo, te grabara esta segunda macro, dentro de un
segundo modulo y tal vez no lo veas, en resumen, el modulo visible debe ser el actual, donde veas que
Excel esta grabando actualmente tus macros.
Descargar el cdigo de este artculo.
Escribiendo mi primer macro en Excel
Esta vez no usaremos la grabadora de macros, esta vez escribiremos nuestra propia macro desde cero, para
este tema, considero que ya sabes entrar al EditorVBA y que ya sabes ejecutar cualquier macro, estas listo?...
o
o
o
o

Entramos a Excel
Aqu podemos usar un nuevo libro o si lo prefieres abre tu libro de pruebas favorito.
Entra el Editor de Visual Basic Alt + F11 .
Puedes usar, si ya lo tienes, un modulo existente, o mejor aun, agregamos uno, esto lo hacemos desde
el men Insertar | Modulo , nuestro Explorador de Proyectos se tiene que ver as.

El cursor de escritura debe de quedar dentro de la ventana de cdigo, observa que estoy usando el
mismo archivo que hice en el tema anterior Grabando mi primer macro, pero reitero, puedes usar
cualquier otro que gustes, observa la barra de ttulo, observa si tengo alguna nueva barra de
herramientas, observa la Ventana de Propiedades, en fin, observa lo ms que puedas.
El siguiente paso es importante, qu har nuestra macro?, bueno, realmente al entrar al EditorVBA ya
"deberamos" de haber tenidos resuelta esta cuestin, pero debes de recordar que esta es la primera y
ms importante pregunta que debemos hacernos, cuando empecemos a crear una macro, para nuestro
ejemplo, como estamos considerando que ser nuestra primera macro, tendremos que escoger algo
sencillo, se me ocurre hacer una macro que nos solicite nuestro nombre y el nombre de algn mes,
despus solicitaremos los importes de algunos conceptos "predefinidos" como: transporte, alimentos,
diversin, por ultimo sumar estos importes, entonces, los pasos que har nuestra macro son:
Solicitar nuestro nombre
Escribirlo en una celda
Solicitar el nombre de algn mes
Escribirlo en alguna celda
Solicitar un importe para el gasto de Transporte
Escribirlo en alguna celda
Solicitar un importe para el gasto de Alimentos
Escribirlo en alguna celda
Solicitar un importe para el gasto de Diversin
Escribirlo en alguna celda
Introducir la formula que sume estos conceptos
Esto que acabamos de hacer es muy importante, siempre que te sea posible y repito, siempre,
procura tratar de escribir la secuencia de pasos necesarios para lograr el proposito establecido, detras

o
o
o
o
o

o
o
o
o
o
o
o
o
o

o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o

de esto, hay miles de lneas de teora, as que puedes investigar los siguientes temas: Analisis de
sistemas, algoritmos, seudocdigo, entre ms domines estos temas y entre ms claros sean estos
pasos, ms fcil te ser, pasarlos el lenguaje que quieras, en nuestro caso, al VBA.
Vamos a la ventana de cdigo y escribimos, ojo, no lo copies, quiero que lo teclees en la ventana de
cdigo...
Public Sub Gastos_Mes()
End Sub
Puntos importantes: Toda macro tiene un nombre, para este caso, decid que se llamar Gastos_Mes,
pero si tu consideras que otro nombre es adecuado, adelante, no dejes de usarlo, observaste que
paso, cuando finalizaste con la lnea Public Sub Gastos_Mes() y presionaste la tecla Enter?, ayudas
como esta, nos la da el EditorVBA, en este caso, solito agrego el final de la macro, End Sub, y poco a
poco te mostrare y te iras dando cuenta de que el EditorVBA, nos da muchas otras ayudas ms, que
hacen un poco ms fcil la escritura de cdigo, si observas alguna otra, durante el proceso de esta
macro, no dejes de comentarla, tambin observa que despus del nombre de la macro, terminamos la
lnea con un abriendo y cerrando un par de parntesis, ms adelante, veremos que podemos introducir
dentro de estos parntesis, por lo pronto, las macros que haremos deben de terminar con estos.
Recuerda que todo lo que escribamos de aqu en adelante, ser entre las lineas Public Sub y End Sub,
y de acuerdo a los pasos que establecimos, debemos de solicitar un nombre y escribirlo en una celda
verdad?...
Public Sub Gastos_Mes()
Dim strNombre As String
'Declaramos nuestra variable
strNombre = InputBox("Cual es tu nombre?")
Range("A1").Value = strNombre

'Preguntamos el nombre
'Lo escribimos en la celda A1

End Sub
Esta muy fcil verdad?, conforme vayamos esribiendo nuestra macro, ve la probando, y, por ahora, te
sugiero proporcionarle todos los datos que solicitamos, ya veremos que pasa cuando no es as. Ahora
trata de solicitar un nombre de mes y escrbelo en la celda A2, como se que no hars trampa, aqu esta
la solucin...
Public Sub Gastos_Mes()
Dim strNombre As String
'Declaramos nuestra variable
Dim strMes As String
'Declaramos otra variable
strNombre = InputBox("Cual es tu nombre?") 'Preguntamos el nombre
Range("A1").Value = strNombre
'Lo escribimos en la celda A1
strMes = InputBox("Cual es el mes?")
'Preguntamos el mes
Range("A2").Value = strMes
'Lo escribimos en la celda A2
End Sub
Que fcil esta esto, ahora solicitaremos el importe de cada uno de los conceptos, en este caso son tres
y estos, los escribiremos en las celdas B5, B6 y B7 respectivamente, por qu ah?, bueno, ya lo
notaras ms adelante, sigue, sigue leyendo por favor, veamos como quedara para el primer caso...
Public Sub Gastos_Mes()
Dim strNombre As String
'Declaramos nuestra variable
Dim strMes As String
'Declaramos otra variable
Dim sngImporte As Single
'Declaramos la variable para los Importes
strNombre = InputBox("Cual es tu nombre?") 'Preguntamos el nombre
Range("A1").Value = strNombre
'Lo escribimos en la celda A1
strMes = InputBox("Cual es el mes?")
'Preguntamos el mes
Range("A2").Value = strMes
'Lo escribimos en la celda A2
'Preguntamos por el importe para el concepto Transporte
sngImporte = InputBox("Cual es el importe para Transporte?")

o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o

Range("B5").Value = sngImporte

'Lo escribimos en la celda B5

End Sub
Solo nos resta solicitar los restantes dos importes, de las restantes categoras, y esta es mi pregunta,
declararemos otras dos variables para "guardar" los valores de estos importes?, o podemos usar la
misma?, y tu, qu crees?...
Public Sub Gastos_Mes()
Dim strNombre As String
'Declaramos nuestra variable
Dim strMes As String
'Declaramos otra variable
Dim sngImporte As Single
'Declaramos la variable para los Importes
strNombre = InputBox("Cual es tu nombre?") 'Preguntamos el nombre
Range("A1").Value = strNombre
'Lo escribimos en la celda A1
strMes = InputBox("Cual es el mes?")
'Preguntamos el mes
Range("A2").Value = strMes
'Lo escribimos en la celda A2
'Preguntamos por el importe para el concepto Transporte
sngImporte = InputBox("Cual es el importe para Transporte?")
Range("B5").Value = sngImporte
'Lo escribimos en la celda B5
sngImporte = InputBox("Cual es el importe para Alimentos?")
Range("B6").Value = sngImporte
'Lo escribimos en la celda B6
sngImporte = InputBox("Cual es el importe para Diversin?")
Range("B7").Value = sngImporte
'Lo escribimos en la celda B7
End Sub
Y por ultimo, introducimos la formula que nos sume el importe de estas tres categoras, esto lo
haremos en la celda B8
Public Sub Gastos_Mes()
Dim strNombre As String
'Declaramos nuestra variable
Dim strMes As String
'Declaramos otra variable
Dim sngImporte As Single
'Declaramos la variable para los Importes
strNombre = InputBox("Cual es tu nombre?") 'Preguntamos el nombre
Range("A1").Value = strNombre
'Lo escribimos en la celda A1
strMes = InputBox("Cual es el mes?")
'Preguntamos el mes
Range("A2").Value = strMes
'Lo escribimos en la celda A2
'Preguntamos por el importe para el concepto Transporte
sngImporte = InputBox("Cual es el importe para Transporte?")
Range("B5").Value = sngImporte
'Lo escribimos en la celda B5
sngImporte = InputBox("Cual es el importe para Alimentos?")
Range("B6").Value = sngImporte
'Lo escribimos en la celda B6
sngImporte = InputBox("Cual es el importe para Diversin?")
Range("B7").Value = sngImporte
'Lo escribimos en la celda B7
'Sumamos las celdas B5 a B7, pero introduciendo una formula
Range("B8").FormulaLocal = "=SUMA(B5:B7)"
End Sub

o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o

En sentido estricto, lo que tenemos hasta ahora, realiza el propsito para lo que fue creada, pero...
(siempre hay un pero), como la vez?, te gusta?, qu le agregamos?, qu le quitamos?, siempre
funciona, en cualquier libro y hoja? (ya sabes a donde contestar estas preguntas). La primer mejora,
ser agregar algunos encabezados para identificar cada valor y la segunda, ser darle un poco de
formato a los datos...
Public Sub Gastos_Mes()
Dim strNombre As String
'Declaramos nuestra variable
Dim strMes As String
'Declaramos otra variable
Dim sngImporte As Single
'Declaramos la variable para los Importes
strNombre = InputBox("Cual es tu nombre?") 'Preguntamos el nombre
Range("A1").Value = strNombre
'Lo escribimos en la celda A1
strMes = InputBox("Cual es el mes?")
'Preguntamos el mes
Range("A2").Value = strMes
'Lo escribimos en la celda A2
'Preguntamos por el importe para el concepto Transporte
sngImporte = InputBox("Cual es el importe para Transporte?")
Range("B5").Value = sngImporte
'Lo escribimos en la celda B5
sngImporte = InputBox("Cual es el importe para Alimentos?")
Range("B6").Value = sngImporte
'Lo escribimos en la celda B6
sngImporte = InputBox("Cual es el importe para Diversin?")
Range("B7").Value = sngImporte
'Lo escribimos en la celda B7
'Sumamos las celdas B5 a B7, pero introduciendo una formula
Range("B8").FormulaLocal = "=SUMA(B5:B7)"
'Agregamos los encabezados necesarios
Range("A4").Value = "Concepto"
Range("B4").Value = "Importe"
Range("A5").Value = "Transporte"
Range("A6").Value = "Alimentos"
Range("A7").Value = "Diversin"
Range("A8").Value = "Total"
'Le damos formato a las celdas
Range("A1:A2").Font.Bold = True
'Negritas
Range("A4:B4").Font.Bold = True
Range("A8:B8").Font.Bold = True
Range("A4:B4").HorizontalAlignment = xlCenter 'Alineacion horizontal central
Range("B5:B8").NumberFormat = "#,##0.00"
'Formato nmerico
End Sub
Muy importante , como mencionamos, por lo pronto, proporcinale, a la macro, todos los datos que
pedimos, no dejes nada vaco, teclea texto donde te pida texto y nmeros donde te pida nmeros, la
tareita es: modifica la macro, de modo que se vea como la siguiente imagen...

o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o

Por ultimo, y como preparacin para la segunda parte de este tema, prueba, ahora s, a NO darle todos
los valores a la macro, a darle texto donde deberan ir nmeros y ver que es lo que hace la macro, se
muy observador, el EditorVBA, de nuevo nos va a ayudar mucho, LEE la ayuda, investiga ms acerca
de la funcin InputBox y ve investigando para que sirve la funcin Val, todo esto, lo encuentras en la
ayuda, as que solo es cuestin de leer, razonar y comprender un poquito, nos vemos...
Como se que hiciste tu tarea, aqu esta la solucin a la macro, si no te resulto, verifica en donde estn
las diferencias, recuerda que esto es solo una propuesta...
'*****************************************
'Esta es la funcin que TU tenias que hacer
Public Sub Gastos_Mes_2()
Dim strNombre As String
'Declaramos nuestra variable
Dim strMes As String
'Declaramos otra variable
Dim sngImporte As Single
'Declaramos la variable para los Importes
strNombre = InputBox("Cual es tu nombre?") 'Preguntamos el nombre
Range("B3").Value = strNombre
'Lo escribimos en la celda A1
strMes = InputBox("Cual es el mes?")
'Preguntamos el mes
Range("B4").Value = strMes
'Lo escribimos en la celda A2
'Preguntamos por el importe para el concepto Transporte
sngImporte = InputBox("Cual es el importe para Transporte?")
Range("B7").Value = sngImporte
'Lo escribimos en la celda B5
sngImporte = InputBox("Cual es el importe para Alimentos?")
Range("B8").Value = sngImporte
'Lo escribimos en la celda B6
sngImporte = InputBox("Cual es el importe para Diversin?")
Range("B9").Value = sngImporte
'Lo escribimos en la celda B7
'Sumamos las celdas B5 a B7, pero introduciendo una formula
Range("B10").FormulaLocal = "=SUMA(B7:B9)"
'Agregamos los encabezados necesarios
Range("A1").Value = "Reporte de gastos"
Range("A3").Value = "Nombre"
Range("A4").Value = "Mes"
Range("A6").Value = "Concepto"
Range("B6").Value = "Importe"
Range("A7").Value = "Transporte"
Range("A8").Value = "Alimentos"
Range("A9").Value = "Diversin"

o
o
o
o
o
o
o
o
o
o
o
o
o
o

Range("A10").Value = "Total"
'Le damos formato a las celdas
Range("A1").Font.Bold = True
'Negritas
Range("A3:A4").Font.Bold = True
Range("A6:B6").Font.Bold = True
Range("A10:B10").Font.Bold = True
Range("A1:B1").HorizontalAlignment = xlHAlignCenterAcrossSelection
Range("A3:A4").HorizontalAlignment = xlRight 'Alineacion horizontal derecha
Range("A6:B6").HorizontalAlignment = xlCenter 'Alineacion horizontal central
Range("B7:B10").NumberFormat = "#,##0.00"
'Formato nmerico
End Sub

Descargar el cdigo de este artculo.


Escribiendo mi primer macro en Excel

II

Para este tema doy por entendido que has leido y comprendido la primer parte de este articulo, que, como
recordaras, la dejamos trabajando perfectamente, la ultima versin quedo as...

'*****************************************
'Esta es la funcin que TU tenias que hacer
Public Sub Gastos_Mes_2()
Dim strNombre As String
'Declaramos nuestra variable
Dim strMes As String
'Declaramos otra variable
Dim sngImporte As Single
'Declaramos la variable para los Importes
strNombre = InputBox("Cual es tu nombre?") 'Preguntamos el nombre
Range("B3").Value = strNombre
'Lo escribimos en la celda A1
strMes = InputBox("Cual es el mes?")
'Preguntamos el mes
Range("B4").Value = strMes
'Lo escribimos en la celda A2
'Preguntamos por el importe para el concepto Transporte
sngImporte = InputBox("Cual es el importe para Transporte?")
Range("B7").Value = sngImporte
'Lo escribimos en la celda B5
sngImporte = InputBox("Cual es el importe para Alimentos?")
Range("B8").Value = sngImporte
'Lo escribimos en la celda B6
sngImporte = InputBox("Cual es el importe para Diversin?")
Range("B9").Value = sngImporte
'Lo escribimos en la celda B7
'Sumamos las celdas B5 a B7, pero introduciendo una formula
Range("B10").FormulaLocal = "=SUMA(B7:B9)"
'Agregamos los encabezados necesarios

Range("A1").Value = "Reporte de gastos"


Range("A3").Value = "Nombre"
Range("A4").Value = "Mes"
Range("A6").Value = "Concepto"
Range("B6").Value = "Importe"
Range("A7").Value = "Transporte"
Range("A8").Value = "Alimentos"
Range("A9").Value = "Diversin"
Range("A10").Value = "Total"
'Le damos formato a las celdas
Range("A1").Font.Bold = True
'Negritas
Range("A3:A4").Font.Bold = True
Range("A6:B6").Font.Bold = True
Range("A10:B10").Font.Bold = True
Range("A1:B1").HorizontalAlignment = xlHAlignCenterAcrossSelection
Range("A3:A4").HorizontalAlignment = xlRight 'Alineacion horizontal derecha
Range("A6:B6").HorizontalAlignment = xlCenter 'Alineacion horizontal central
Range("B7:B10").NumberFormat = "#,##0.00"
'Formato nmerico
End Sub
o

o
o

o
o

Tambin quedamos que en esta ocasin, no le vamos a proporcionar los datos esperados, si no que
pondremos a prueba la "solidez" de nuestra macro, asignndole valores incorrectos o simplemente
cancelando la operacin, esto ultimo muy importante, en la mayora de los casos, tienes que
proporcionarle al usuario una forma de cancelar la macro en ejecucin...
Como primer prueba le pasaremos una cadena vaca en donde nos solicite un dato, veamos que hace
la macro y que mejores le podemos hacer, empecemos...
Cuando nos solicite el primer dato, prueba a; directamente dar un clic en el botn Aceptar o a
introducir puros espacios con la tecla Barra espaciadora, observa como en la imagen siguiente el
cursor esta unos caracteres adelante, pues se introdujeron algunos espacios.

Al dar clic en el botn Aceptar, la macro continua como si nada, es decir, nos muestra el siguiente
cuadro donde nos solicita el siguiente dato, pero?, es esto correcto?, no verdad, el dato Nombre es
un dato (lo pondr en maysculas) REQUERIDO, esta palabra es muy importante, nos indica que el
valor que estamos solicitando es OBLIGATORIO proporcionarlo para que nuestra macro haga el
trabajo encomendado, si un dato es o no REQUERIDO es algo que Tu tienes que decidir y que es muy
fcil determinar, tan solo pregntate; la macro puede resolver el trabajo sin este dato?, si la respuesta
es NO, entonces es REQUERIDO, si la respuesta es SI, entonces es OPCIONAL, para nuestro caso,
el dato Nombre es un dato REQUERIDO, por lo que tenemos que garantizar que el usuario
proporcione este valor, la pregunta del milln cmo lo hacemos?...
Como sabes (y si no lo sabes aqu te lo dijo), la funcin InputBox "siempre", lo repito, "siempre", nos
devuelve un String, es decir, una cadena de texto y esta cadena de texto, ser de longitud cero,
cuando: presione inmediatamente el botn Aceptar o cuando presione el botn Cancelar, aun cuando
ya haya introducido algn texto en el cuadro, con este conocimiento, solo tenemos que medir el
nmero de caracteres para saber si el usuario escribi algo en el cuadro de texto, para eso, usamos la
funcin Len, que nos devuelve un Long, un nmero con el nmero de caracteres de una cadena...
Dim Largo As Long

o
o
o
o
o
o
o

o
o
o
o
o
o

strNombre = InputBox("Cual es tu nombre?") 'Preguntamos el nombre


Largo = Len(strNombre)
En la variable Largo, tenemos el nmero de caracteres que el usuario escribi, si este valor es cero,
entonces ya sabes que significa verdad?, pero, como sabemos si es o no cero?, para esto lo
preguntamos de esta manera
If Largo = 0 Then
MsgBox "El dato Nombre es requerido"
End If
Lo que acabamos de hacer, es crear una estructura condicional, o sea, que dependiendo de una
condicin, podemos ejecutar determinado cdigo, en esta caso, nuestra condicin es: Largo = 0, que,
como observas, esta entre las palabras If y Then, es decir, entre estas dos palabras claves de VB,
pondremos la condicin necesaria, como condicin, puedes usar "cualquier expresin que se pueda
evaluar como VERDADERA o FALSA", esta estructura tiene muchas variantes, pero empezaremos por
su forma ms sencilla, en nuestro ejemplo, si la condicin es VERDADERA, entonces se ejecuta la
lnea o lneas inmediatas a la condicin, en este caso la lnea: MsgBox "El dato Nombre es
requerido", que tan solo le notifica al usuario que no proporciono un dato, pero si continuamos, la
macro sigue como antes, es decir, nos muestra el siguiente mensaje, lo cual no es correcto, pues
buscamos obligar al usuario a introducir el dato, para esto, podemos volver a preguntar, pero con esto
corremos el riesgo de que vuelva a proporcionar una cadena de longitud cero, con este inconveniente,
decidimos mejor, salir de la macro con la instruccin Exit Sub, con la cual el cdigo quedara as...
If Largo = 0 Then
MsgBox "El dato Nombre es requerido"
Exit Sub
End If
Prubala y verifica como, cuando presionas Cancelar o inmediatamente presionas Aceptar,
efectivamente nos informa de ello y termina la macro, la instruccin Exit Sub hay que usarla con
mesura, no abuses mucho de ella, ya aprenderemos otras alternativas para minimizar su uso.
Bien, muy bien, ahora prueba a introducir espacios cuando te solicite el nombre, qu paso?, nos deja
continuar verdad?, esto es por que recuerda que aunque nosotros no veamos los espacios, para la
computadora son un carcter ms, as que cuando evala el largo de la cadena, esta devuelve el
nmero de espacios vacos que el usuario tecleo, pero esto tambin debemos de preverlo con una
funcin llamada Trim que elimina los espacios en blanco que tenga una cadena al principio y al final de
esta...
strNombre = Trim(strNombre)
en este ejemplo, primero le quitamos los espacios a la variable strNombre y despus reasignamos el
valor resultante a ella misma, tambin podramos haber usado la funcin Trim directamente en la
funcin InputBox de la siguiente manera...
strNombre = Trim (InputBox("Cual es tu nombre?"))
solo para que lo notaras, puse en negritas la funcin Trim, puedes usar cualquiera de las dos, al final el
resultado es el mismo. Vuelve a hacer las pruebas pertinentes.

o
o
o
o
o
o
o
o

Como siguiente paso, realizamos la misma evaluacin para el dato Mes, garantizaremos que el usuario
introduzca un dato.
strMes = Trim(InputBox("Cual es el mes?"))
Largo = Len(strMes)
If Largo = 0 Then
MsgBox "El dato Mes es requerido"
Exit Sub
End If
Una muy buena pregunta; podremos lograr evaluar que el usuario introduzca un nombre de Mes
vlido, es decir, garantizar que el usuario introduzca Enero, Febrero... Diciembre o cualquier mes
correcto?, te queda de tareita tratar de hacerlo, al fin y al cabo solo son doce meses, pero recuerda que
la respuesta ms obvia no siempre es la mejor.
El siguiente dato que tenemos que garantizar que el usuario introduzca es un valor, un nmero, ya no
una cadena, esto es importante, ms atrs se dijo la funcin InputBox "siempre", lo repito, "siempre",

nos devuelve un String, es decir, una cadena de texto, entonces, como es que podemos asignar un
String (cadena de texto) a una variable de tipo Single (nmero simple) como en la lnea siguiente?...
sngImporte = InputBox("Cual es el importe para Transporte?")
La respuesta es simple, cuando VB encuentra que queremos hacer una asignacin de un Tipo de dato
a otro Tipo de dato, si le es posible hace la conversin necesaria, si no le es posible ocurre un error
(mejor dicho un horror por que nuestro cdigo se detiene), veamos un ejemplo...

En la imagen anterior, cuando se nos solicita un importe, en vez de un nmero, introducimos un texto,
al presionar el botn Aceptar nos muestra un lindo e interesante mensaje, un mensaje de ERROR, nos
muestra el nmero de error (13) y nos muestra la causa del error (No coinciden los tipos), a que tipos...

Si presionamos el botn Finalizar simplemente la ejecucin de la macro termina, pero si presionamos


el botn Depurar pasa algo muy interesante, se abre la ventana del Editor del VBA y una lnea se
colorea de un forma bastante llamativa, para que ser?...

o
o
o
o
o
o
o
o
o
o

As es, como lo imaginaste en esa lnea ocurri el error (que brillante eres Mauricio...!!) y en ese
momento, podemos modificarla, pero antes, quiero que seas muy observador, aparte de la lnea
amarilla, hay otra cosa que quiero que observes, esta es, la barra de titulo del Editor, obsrvala y ve lo
que nos va mostrando conforme cambiamos y usamos el Editor VBA, por ahora, detn la ejecucin de
la macro, como?, ve al men Ejecutar | Restablecer o presiona el botn que encerr en un circulo rojo
(ya vieron que bien dibujo a mano alzada).
Entonces, el error fue que VB no pudo convertir el valor tipo String al tipo Single, pero nuestro trabajo
es garantizar que si pueda hacerlo, pues si a un usuario le sale el mismo mensaje de "horror" que
acabamos de ver, ten por seguro que se acordara de ti, pero para que no pase esto, veamos como
solucionarlo.
Como casi siempre, hay ms de una manera de resolverlo, probemos una de las ms sencillas,
haciendo uso de la funcin Val, que convierte "si le es posible" una cadena de texto en un nmero,
pero si no le es posible, ya no ocurre un error, sino que lo convierte en cero, su uso es simple...
sngImporte = Val(InputBox("Cual es el importe para Transporte?"))
Ahora, en la variable sngImporte tendremos el valor en "nmero" si fue posible hacer la conversin, y
tendremos un cero, si no fue posible hacer la conversin, pregunta; cmo evalas entonces que el
dato este correcto?...
sngImporte = Val (InputBox("Cual es el importe para Transporte?"))
If sngImporte = 0 Then
MsgBox "El dato Transporte es requerido"
Exit Sub
End If
Muy bien, veo que si estas aprendiendo, pero... qu crees?, pues si, tienes otra tareita, es sencilla,
solo tienes que responder la pregunta cmo solucionaras el caso, cuando un usuario introduzca un
nmero negativo?, ms fcil no es posible...
Ahora solo te resta hacer lo mismo para los restantes datos, pero... por qu siempre sales con un
pero?, observa la siguiente imagen, obsrvala muy bien...

o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o

En este cuadro, se nos esta solicitando el dato Importe (en rojo), que como sabemos debe ser un
nmero, pero le estamos proporcionando una cadena de texto (en azul), como ya previmos esto, la
macro simplemente nos avisara que no es un nmero vlido y se detendr, pero que pasa?, en el
fondo (en naranja) ya introdujimos por cdigo, los valores de las dos variables anteriores, pero al
cancelarse mi macro por la introduccin de un dato errneo, estos valores son obsoletos, es decir,
inservibles, intiles, estn de ms verdad?, solucin uno, los borramos antes de salir, solucin dos
(mejor), los escribimos hasta despus de haber evaluado todas las variables, pero... otro? (ya me
estoy cansando de los pero's...), esto es vlido para las dos primeras variables, pero en el caso de los
tres importes, estamos usando una sola variable para los tres, para resolver este pequeo
inconveniente, usaremos una variable para cada dato y te podrs preguntar y si mis datos a introducir
son muchos, tendr que declarar una variable para cada dato?, muy buena pregunta, ms adelante
veremos casos como ese, por lo pronto hazme caso y declara una variable para cada concepto o
cuntame que otras alternativas que se te ocurren.
Bien, nuestro cdigo completo se vera as...
Option Explicit
Public Sub Gastos_Mes_2()
'Declaramos las variables a usar
Dim strNombre As String
Dim strMes As String
Dim sngTransporte As Single
Dim sngAlimentos As Single
Dim sngDiversion As Single
Dim Largo As Long
'Solicitamos cada uno de los datos requerido y verificamos que sean correctos
strNombre = Trim(InputBox("Cual es tu nombre?"))
Largo = Len(strNombre)
If Largo = 0 Then
MsgBox "El dato Nombre es requerido"
Exit Sub
End If
strMes = Trim(InputBox("Cual es el mes?"))
Largo = Len(strMes)
If Largo = 0 Then
MsgBox "El dato Mes es requerido"
Exit Sub
End If

o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o

sngTransporte = Val(InputBox("Cual es el importe para Transporte?"))


If sngTransporte = 0 Then
MsgBox "El dato Transporte es requerido"
Exit Sub
End If
sngAlimentos = Val(InputBox("Cual es el importe para Alimentos?"))
If sngAlimentos = 0 Then
MsgBox "El dato Alimentos es requerido"
Exit Sub
End If
sngDiversion = Val(InputBox("Cual es el importe para Diversion?"))
If sngDiversion = 0 Then
MsgBox "El dato Diversion es requerido"
Exit Sub
End If
'Escribimos los valores ya correctos
Range("B3").Value = strNombre
Range("B4").Value = strMes
Range("B7").Value = sngTransporte
Range("B8").Value = sngAlimentos
Range("B9").Value = sngDiversion
'Sumamos las celdas B5 a B7, pero introduciendo una formula
Range("B10").FormulaLocal = "=SUMA(B7:B9)"
'Agregamos los encabezados necesarios
Range("A1").Value = "Reporte de gastos"
Range("A3").Value = "Nombre"
Range("A4").Value = "Mes"
Range("A6").Value = "Concepto"
Range("B6").Value = "Importe"
Range("A7").Value = "Transporte"
Range("A8").Value = "Alimentos"
Range("A9").Value = "Diversin"
Range("A10").Value = "Total"
'Le damos formato a las celdas
Range("A1").Font.Bold = True
'Negritas
Range("A3:A4").Font.Bold = True
Range("A6:B6").Font.Bold = True
Range("A10:B10").Font.Bold = True
Range("A1:B1").HorizontalAlignment = xlHAlignCenterAcrossSelection
Range("A3:A4").HorizontalAlignment = xlRight 'Alineacion horizontal derecha
Range("A6:B6").HorizontalAlignment = xlCenter 'Alineacion horizontal central
Range("B7:B10").NumberFormat = "#,##0.00"
'Formato nmerico
End Sub
Bien, muy bien, ahora nuestra macro es un poco ms profesional, los posibles usuarios "casi" no se
acordaran de nosotros y estamos contentos de saber un poco ms, recuerda que no es la nica
solucin, puede y hay ms, una de ellas la veremos en el prximo capitulo, no te despegues...

Descargar el cdigo de este artculo.


Escribiendo mi primer macro en Excel

III

Para este tema doy por entendido que has leido y comprendido la primer y segunda parte de este articulo, la
ultima versin es la siguiente...

Option Explicit
Public Sub Gastos_Mes_2()
'Declaramos las variables a usar
Dim strNombre As String
Dim strMes As String
Dim sngTransporte As Single
Dim sngAlimentos As Single
Dim sngDiversion As Single
Dim Largo As Long
'Solicitamos cada uno de los datos requerido y verificamos que sean correctos
strNombre = Trim(InputBox("Cual es tu nombre?"))
Largo = Len(strNombre)
If Largo = 0 Then
MsgBox "El dato Nombre es requerido"
Exit Sub
End If
strMes = Trim(InputBox("Cual es el mes?"))
Largo = Len(strMes)
If Largo = 0 Then
MsgBox "El dato Mes es requerido"
Exit Sub
End If
sngTransporte = Val(InputBox("Cual es el importe para Transporte?"))
If sngTransporte = 0 Then
MsgBox "El dato Transporte es requerido"
Exit Sub
End If
sngAlimentos = Val(InputBox("Cual es el importe para Alimentos?"))
If sngAlimentos = 0 Then
MsgBox "El dato Alimentos es requerido"
Exit Sub
End If
sngDiversion = Val(InputBox("Cual es el importe para Diversion?"))
If sngDiversion = 0 Then
MsgBox "El dato Diversion es requerido"
Exit Sub
End If

'Escribimos los valores ya correctos


Range("B3").Value = strNombre
Range("B4").Value = strMes
Range("B7").Value = sngTransporte
Range("B8").Value = sngAlimentos
Range("B9").Value = sngDiversion
'Sumamos las celdas B5 a B7, pero introduciendo una formula
Range("B10").FormulaLocal = "=SUMA(B7:B9)"
'Agregamos los encabezados necesarios
Range("A1").Value = "Reporte de gastos"
Range("A3").Value = "Nombre"
Range("A4").Value = "Mes"
Range("A6").Value = "Concepto"
Range("B6").Value = "Importe"
Range("A7").Value = "Transporte"
Range("A8").Value = "Alimentos"
Range("A9").Value = "Diversin"
Range("A10").Value = "Total"
'Le damos formato a las celdas
Range("A1").Font.Bold = True
'Negritas
Range("A3:A4").Font.Bold = True
Range("A6:B6").Font.Bold = True
Range("A10:B10").Font.Bold = True
Range("A1:B1").HorizontalAlignment = xlHAlignCenterAcrossSelection
Range("A3:A4").HorizontalAlignment = xlRight 'Alineacion horizontal derecha
Range("A6:B6").HorizontalAlignment = xlCenter 'Alineacion horizontal central
Range("B7:B10").NumberFormat = "#,##0.00"
'Formato nmerico
End Sub
o Esta versin funciona bien, pero como habrs notado, cuando el usuario no proporciona un dato
correctamente, la macro, si bien informa de esta falta, lo que hace es simplemente terminar la
ejecucin, no le da la oportunidad al usuario de intentarlo nuevamente, dicen por ah que -todos
merecemos una segunda oportunidad-, as que implementaremos una forma de que el usuario pueda
intentarlo nuevamente, para ello usaremos una nueva estructura condicional, veamos el ejemplo y
despus lo explicamos...
o
'Iniciamos la estructura condicional
o
Do
o
'Solicitamos el dato requerido quitandole los espacios sobrantes
o
strNombre = Trim(InputBox("Cual es tu nombre?"))
o
'Verificamos que exista el dato
o
If strNombre = "" Then
o
'Notificamos en caso de que no haya dato
o
MsgBox "El dato Nombre es requerido"
o
End If
o
'Volvemos a la lnea inmediata a Do si el dato es vacio
o
Loop While strNombre = ""
o Estos cambios, ya lo habrs notado, los haremos para solicitar el primer dato, para entender esta
nueva estructura, te pondr las instrucciones pero le agregare su interpretacin en espaol...
o
'Iniciamos la estructura condicional
o
Do(Hacer)
o
'Solicitamos el dato requerido quitandole los espacios sobrantes
o
strNombre = Trim(QuitaEspacios)(InputBox(SolicitaDato)("Cual es tu nombre?"))
o
'Verificamos que exista el dato
o
If(Si) strNombre = "" Then(Entonces)
o
'Notificamos en caso de que no haya dato
o
MsgBox(MuestraMensaje) "El dato Nombre es requerido"

o
o
o
o

o
o
o
o
o
o
o
o
o
o
o
o
o
o

o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o

End If(Fin Si)


'Volvemos a la lnea inmediata a Do si el dato es vacio
Loop While(Hacer Mientras) strNombre = ""
La estructura condicional Do...Loop... While, nos sirve para repetir una serie de instrucciones
mientras o hasta que se cumpla una condicin, fjate como es muy sencillo, solo hay que iniciar la
estructura con un Do y terminarla con un Loop While condicion, con esta estructura el cdigo se
ejecutara mientras la condicin sea verdadera, la otra variante es que el cdigo se ejecute hasta que
la condicin sea verdadera, veamos este ultimo ejemplo...
'Iniciamos la estructura condicional
Do
'Solicitamos el dato requerido quitandole los espacios sobrantes
strNombre = Trim(InputBox("Cual es tu nombre?"))
'Verificamos que exista el dato
If strNombre = "" Then
'Notificamos en caso de que no haya dato
MsgBox "El dato Nombre es requerido"
End If
'Volvemos a la lnea inmediata a Do si el dato es vacio
Loop Until strNombre <> ""
El cambio fue realmente simple, observa la siguiente lnea que fue la que se modifico...
Loop Until strNombre <> ""
Solo sustituimos While por Until e invertimos la condicin strNombre <> "" , esto es muy importante,
es decir, que la condicin la establezcas de manera correcta, sino, nuestra estructura no cumplira su
proposito. Esta estructura tiene otras variantes, por ejemplo, que la condicin la realices al principio de
la estructura, en la misma lnea del Do, pero como este no es un curso de programacin, te dejo de
tareita que investigues ms de esta estructura, en la ayuda del VBA, viene, creo yo, suficientemente
explicada, lo que si veremos ms adelante son ejemplos de su uso, pues es muy verstil y muy
poderosa esta estructura.
Solo nos resta complementar los restantes datos, para que queden en la misma estructura de la
siguiente manera, sintete en libertad de usar cualquier de las dos formas vistas...
Option Explicit
Public Sub Gastos_Mes_3()
'Declaramos las variables a usar
Dim strNombre As String
Dim strMes As String
Dim sngTransporte As Single
Dim sngAlimentos As Single
Dim sngDiversion As Single
Dim Largo As Long

'Iniciamos la estructura condicional


Do
'Solicitamos el dato requerido quitandole los espacios sobrantes
strNombre = Trim(InputBox("Cual es tu nombre?"))
'Verificamos que exista el dato
If strNombre = "" Then
'Notificamos en caso de que no haya dato
MsgBox "El dato Nombre es requerido"
End If
'Volvemos a la lnea inmediata a Do si el dato es vacio
Loop While strNombre = ""
Do
strMes = Trim(InputBox("Cual es el mes?"))
If strMes = "" Then

o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o

MsgBox "El dato Mes es requerido"


End If
Loop While strMes = ""
Do
sngTransporte = Val(InputBox("Cual es el importe para Transporte?"))
If sngTransporte = 0 Then
MsgBox "El dato Transporte es requerido"
End If
Loop While sngTransporte = 0
Do
sngAlimentos = Val(InputBox("Cual es el importe para Alimentos?"))
If sngAlimentos = 0 Then
MsgBox "El dato Alimentos es requerido"
End If
Loop While sngAlimentos = 0
Do
sngDiversion = Val(InputBox("Cual es el importe para Diversion?"))
If sngDiversion = 0 Then
MsgBox "El dato Diversion es requerido"
End If
Loop While sngDiversion = 0
'Escribimos los valores ya correctos
Range("B3").Value = strNombre
Range("B4").Value = strMes
Range("B7").Value = sngTransporte
Range("B8").Value = sngAlimentos
Range("B9").Value = sngDiversion
'Sumamos las celdas B5 a B7, pero introduciendo una formula
Range("B10").FormulaLocal = "=SUMA(B7:B9)"
'Agregamos los encabezados necesarios
Range("A1").Value = "Reporte de gastos"
Range("A3").Value = "Nombre"
Range("A4").Value = "Mes"
Range("A6").Value = "Concepto"
Range("B6").Value = "Importe"
Range("A7").Value = "Transporte"
Range("A8").Value = "Alimentos"
Range("A9").Value = "Diversin"
Range("A10").Value = "Total"
'Le damos formato a las celdas
Range("A1").Font.Bold = True
'Negritas
Range("A3:A4").Font.Bold = True
Range("A6:B6").Font.Bold = True
Range("A10:B10").Font.Bold = True
Range("A1:B1").HorizontalAlignment = xlHAlignCenterAcrossSelection
Range("A3:A4").HorizontalAlignment = xlRight 'Alineacion horizontal derecha
Range("A6:B6").HorizontalAlignment = xlCenter 'Alineacion horizontal central
Range("B7:B10").NumberFormat = "#,##0.00"
'Formato nmerico

End Sub

CONCLUSIONES
Casi siempre, hay ms de una forma de programar una solucin.
Las diferentes estructuras no estn para complicarnos el trabajo, al contrario, son para
adaptarlas a nuestras diferentes necesidades y sobre todo nuestras diferentes forma de
razonar una respuesta.
Estas estructuras tienen muchas variantes, por ejemplo, la capacidad de usar ms de una
condicin, si no se vio a fondo es por varias razones; la ayuda del lenguaje viene bastante bien
explicado y con buenos ejemplos de su uso, si no te gusta mucho la ayuda, en la red hay
cientos (y no exagero), cientos de pginas que te ensean a programar en el VB, busca, busca
un poquito y veras que as es.
En esta versin de nuestra macro, "obligamos" al usuario a introducir "algo", pero en el artculo
anterior, mencionamos que es importante, tratar de proporcionarle al usuario una forma de
cancelar la operacin o macro en proceso, de tareita te invito a que trates de hacer las
siguientes variantes...
1. Una versin de esta macro, que le de la oportunidad al usuario de cancelar el proceso,
OJO, que no sea la vista en la parte dos de este artculo, sino una combinacin
digamos de las dos, mira, sin querer ya casi te dije como hacerlo.
2. Otra versin de esta macro, que le demos, digamos, tres oportunidades de introducir
su dato y salga al llegar a este limite, claro, informando en todo momento al usuario de
que es lo esta pasando.

Descargar el cdigo de este artculo.


Escribiendo mi primer funcin en Excel
Para obtener el mejor provecho de esta seccin, estoy asumiendo que manejas con soltura el uso de las
funciones incorporadas de Excel, como SUMA, MAX, BUSCARV, entre otras, recuerda que Excel tiene mas de
300 funciones incorporadas y que tambin has usado el EditorVBA, sino lo has hecho te recomiendo leer la
Introduccin a esta pgina, bien, entonces, conoces la estructura de cualquier funcin, veamos cual es:

Las funciones personalizadas, "deben" seguir la misma estructura, si eres observador, notaras que los
argumentos estn separados por ";" (punto y coma), pero en la descripcin dice que debe ser "," (comas),
porque?, cual es la correcta? (esto te queda de tareita ).
Nuestras funciones "deben" de responder de la misma manera que las incorporadas, DEVOLVIENDO
VALORES , esto me parece la parte ms importante que algunos olvidan, has visto que alguna funcin de
Excel te de algn mensaje?, no, lo que hace, cuando no puede hacer resolver la operacin, es darnos un error
como #NULO!, #DIV/0!, #VALOR!, #REF!, #NOMBRE?, #NM!, #N/A, pero nada ms.
Entonces ya conocemos los siguiente trminos, Funcin y Argumentos, verdad?, otro punto importante es
saber que una funcin puede o no llevar argumentos como la funcin ALEATORIO y AHORA, una funcin
puede requerir argumentos de un Tipo y devolver valores de otro Tipo, como las funciones:
Funcin
LARGO
VALOR
FILA

Tipo de ARGUMENTO requerido


Texto
Texto
Rango

Tipo de VALOR devuelto


Numero
Numero
Numero

ESNUMERO
Numero
Booleano
Tareita: Excel, dentro de sus formulas, maneja diferentes Tipos de datos, como fechas y nmeros, que otros
TIPOS DE DATOS conoces que usen las funciones de Excel?, que otros ejemplos de funciones, podras dar,
que devuelvan un tipo de dato diferente del de su o sus argumentos?.
Como habrs notado, el nombre es importante, el nombre de la funcin nos sirve para en primera instancia
sepamos que hace o que valor o valores nos devuelve, entonces, una parte importante es saber QUE HARA
NUESTRA FUNCION es decir, que trabajo realizara, cual es su finalidad.
Resumiendo:

Conocer los trminos FUNCION, ARGUMENTO, VALOR DEVUELTO y TIPO DE DATO


Conocer la estructura de cualquier funcin
Conocer que trabajo realiza una funcin
TODA funcin devuelve un valor
Una funcin puede o no, tener argumentos
Una funcin puede devolver valores de diferente tipo del de sus argumentos
Los argumentos se separan por "comas" o "punto y coma", depende de??.

Ahora que sabemos lo que necesitamos, hagamos nuestra primer funcin, como ya dijimos, lo primero es
saber, que queremos que haga nuestra funcin, como ejemplo, haremos la superarchidificilisima formula para
calcular el rea de un tringulo:

Entramos a Excel
Entramos el EditorVBA
Insertamos un nuevo Mdulo y escribimos lo siguiente:
Option Explicit
Function AreaTriangulo(Base, Altura)
AreaTriangulo = (Base * Altura) / 2
End Function
Prubala..., como?, como cualquier funcin de Excel, que ya lo sabes, si usas el Asistente para
funciones, veras una nueva categora, al final de la lista que se llama, Definidas por el usuario, ah
encontraras nuestra funcin.
Ahora, comparemos la formula tradicional con nuestra funcin:

Bueno, nuestra formula funciona, pero no esta optimizada, es decir, estamos cometiendo omisiones
"tcnicas", es decir, no estamos escribiendo nuestra funcin como lo mandan los "santos cnones" de
la programacin y esto, si bien, no es obligatorio, es muy, muy conveniente hacerlo y ms aun, saberlo,
veamos cuales son esas omisiones...
Si no se especifica otra cosa, toda funcin es Publica, pero procura hacerlo explcitamente...
Public Function AreaTriangulo(Base, Altura)
AreaTriangulo = (Base * Altura) / 2
End Function
No le estamos diciendo de que TIPO son nuestros argumentos, en nuestro ejemplo, nuestra funcin
debe poder manejar nmeros grandes y con decimales, por lo tanto el Tipo de dato ms conveniente
es el Single (busca en la ayuda, los tipos de datos que se puedes usar en el VBA y me dices cuales
son), por lo tanto nuestra funcin quedara as:
Public Function AreaTriangulo(Base As Single, Altura As Single)
AreaTriangulo = (Base * Altura) / 2
End Function
Tampoco le estamos diciendo que tipo de valor es que nos devolver nuestra funcin, es muy
importante, escoger este tipo de dato muy bien, la recomendacin es, debe ser lo suficientemente
grande para contener el resultado de nuestra funcin, en la misma ayuda, encontraras cuando espacio
ocupa (en memoria) y que valores pueden contener los diferentes tipos de datos, para nuestro caso, si
estamos multiplicando un Single por un Single y aunque estemos dividiendo, el ms conveniente es un
Double, para que nuestra funcin quede as:
Public Function AreaTriangulo(Base As Single, Altura As Single) As Double
AreaTriangulo = (Base * Altura) / 2
End Function
Por ultimo, hay que agregarlo otra palabrita, que en otros ejemplos veremos a detalle, por lo pronto,
solo te menciono que sirve para que los valores que tengan los argumentos, no se puedan modificar
desde nuestra funcin y en la mayora de los casos se usa, esta palabrita se llama ByVal y me gustara
que buscaras ayuda de esta palabra, ya sabes donde...
Public Function AreaTriangulo(ByVal Base As Single, ByVal Altura As Single) As Double
AreaTriangulo = (Base * Altura) / 2
End Function
Y ahora s, estars de acuerdo conmigo, que se ve mucho ms bonita y presentable, pero sobre todo,
esta eficientemente codificada. Para terminar, te mostrare una variante, que te servir como ejemplo
para la tareita que te dejare.
Public Function AreaTriangulo(ByVal Base As Single, ByVal Altura As Single) As Double
Dim Area As Double
Area = Base * Altura
Area = Area / 2
AreaTriangulo = Area

End Function
Lo que te he querido decir con esta variante, es que "casi nunca", obtenemos el resultado de nuestra
funcin en una lnea, "casi siempre" se hace uso del proverbio que dice -divide y vencers-, recuerdas
lo que deca Descartes?, puedes hacer uso de VARIABLES intermedias, observa muy bien esta lnea
Dim Area As Double
te encontraras con lneas como esta muy seguido, lo que le estamos diciendo al VBA es -oye,
aprtame un cachito de memoria (recuerda que todo lo que hagas con tu maquina encendida, usa
memoria) para que la use-, estamos DECLARANDO UNA VARIABLE. Como se que eres una
personita muy observadora, notaras que es "casi" igual que con los argumentos, solo que aqu usamos
la palabra reservada (que es eso de palabra reservada?) Dim, pero para decirle el tipo de datos es
igual As Tipo_Dato

Ahora si, esta es la tareita , como sabes, tenemos los pelos de los griegos por cualquier lado que
mires, all por el ao 500 a.C., vivia el seor Hern que no se conformo con la funcin que hicimos un
poco ms arriba, as que se puso a investigar como obtener el rea, pero de cualquier tringulo con
solo conocer la longitud de sus lados, para llegar a deducir la siguiente formula...

En donde a, b y c, son los lados del tringulo y S es el Semipermetro o sea, la mitad del permetro y
hasta te voy a ayudar un poco ms, en VBA para obtener la raz cuadrada de un nmero, se usa la
funcin Sqr (nmero), en donde nmero es el nmero del cual queremos obtener la raz cuadrada,
adelante, empieza a codificarla que con gusto la revisar...

Como siempre, prubala, si tenemos el famoso tringulo 3,4,5 y le pasamos estos datos a nuestra
primer funcin, Base = 4 y Altura = 3, el rea obtenida sera 6, si le pasamos estos mismos datos, ms
el largo del tercer lado, a la funcin que escribas, te tiene que dar el mismo resultado, el poder de la
segunda, como ya se menciono, esta en que se puede obtener el rea de cualquier tringulo, tan solo
conociendo la longitud de sus lados.

Despus de haber recibido todas las pruebas que han hecho, aqu esta una de varias posibles
soluciones, prubala y verifica si esta correcta o cuntame que es lo que no te gusta o que otras
variantes podra tener...
'Funcin que obtiene el rea de cualquier triangulo, conociendo
'la longitud de sus lados, usando la formula de Hern
Public Function AreaTrianguloHeron(ByVal LadoA As Single, _
ByVal LadoB As Single, _
ByVal LadoC As Single) As Double
Dim Semi As Double
Dim Area As Double

'Obtenemos el semiperimetro
Semi = (LadoA + LadoB + LadoC) / 2

'Obtenemos los productos


Area = Semi * (Semi - LadoA) * (Semi - LadoB) * (Semi - LadoC)
'Obtenemos la RAIZ CUADRADA
Area = Sqr(Area)
'Asignamos el valor obtenido al nombre de nuestra funcin
AreaTrianguloHeron = Area
End Function
Recuerda que debes de probar las dos funciones, de modo que verifiques que te de el mismo
resultado, en la siguiente imagen, puedes observar los valores asignados a cada funcin, as mismo,
en rojo, estn las funciones que hemos creado...

Descargar el cdigo de este artculo.


Complementos... que son?

Complemento
Componentes que pueden instalarse en el equipo para agregar comando o funciones a Excel

Esto es lo que nos dice la ayuda, en otros trminos, un complemento es un archivo de Excel, con ciertas
caractersticas especiales (que veremos) en el cual podemos crear macros o funciones que extiendan las
posibilidades de Excel, veamos primero un complemento de los que incluye Excel y despus crearemos el
nuestro...

Entramos a Excel
Seleccionamos el men Herramientas | Complementos...

Nos mostrara el siguiente cuadro de dialogo

Observa la lista y selecciona Autoguardar. Nota: estos complementos se pueden instalar y desinstalar,
tal vez la lista no sea igual o tal vez no este instalados en tu equipo, para instalarlos checa la ayuda.
Despus de seleccionar el complemento Autoguardar y claro, despus de que hayas ledo la leyenda
que aparece en la parte inferior del cuadro de dialogo, para que te des una idea de lo que hace,
presionas el botn Aceptar
Si eres observador y si tu maquina no es muy rpida, observa la barra de estado de Excel, notaras que
dir Abriendo Autosave.xla... y como es comn al abrir libros, mostrara una barra de progreso, al
terminar "aparentemente" no notaras ningn cambio, pero ve al men Herramientas y este tendr una
nueva opcin, como se ve en la siguiente imagen.

Selecciona esta nueva opcin y te saldr el siguiente cuadro de dialogo...

Como este articulo no es para explicar el uso de este complemento, pues te queda de tarea probarlo,
que como imaginaras, te permite guardar cada X minutos el libro activo o todos los libros, adems de
que si esta bien instalado, tambin se instala la ayuda de los complementos.
Ahora, quiero que regreses a los complementos y busques en la lista uno que se llama Solver,
seleccinalo y de nuevo te agregara una nueva opcin al men Herramientas, esto es solo como

prueba de otro complemento y tambin como tarea te queda investigar como quitar estos
complementos.
Observa como la herramienta de Autoguardar NO esta implementada en Excel, sino que se agrego
esta funcionalidad con un complemento o Add-ins como tambin se les conoce, esto no lo pierdas de
vista, los complementos son para agregar nuevas funciones o herramientas a Excel, no para repetir
las ya existentes.
Ahora viene lo interesante, como creo mi propio complemento, antes de continuar, no pierda de vista lo
comentado en el punto anterior y veamos paso a paso como crear un sencillo complemento. Para lo
que veremos a continuacin, estoy suponiendo que ya trabajas, aunque sea muy bsico, con macros y
funciones, si no es as, te recomiendo los siguientes temas vistos en estas pginas:
Introduccin donde vemos como empezar desde cero con las macros y a familiarizarnos con el
Editor VBA
Grabando mi primer macro en Excel
Escribiendo mi primer funcin en Excel
Y los primeros tres temas de la seccin Articulos
Como ya se dijo, vamos a usar los complementos para agregar funcionalidades inexistentes en
Excel, para nuestro ejemplo, implementaremos la posibilidad de cambiar el contenido de las
celdas de MAYSCULAS a minsculas y viceversa.
Entramos a Excel.
Si tenemos ms de una hoja (normalmente 3) dejamos solamente una hoja, esto no es
indispensable, pero dado que no se van a ocupar, las eliminamos para que el complemento
resultante sea de menor tamao.
Guardamos nuestro archivo, por ahora, gurdalo como cualquier archivo de Excel y despus
veremos como hacerlo como complemento.
Entramos al Editor VBA, mtodo abreviado Alt + F11
Agregamos un mdulo de cdigo Estndar desde el men Insertar | Mdulo
Escribimos o copiamos las siguientes macros...
Option Explicit

Public Sub Mayusculas()


Dim c As Range

For Each c In Selection

c.Value = StrConv(c.Value, vbUpperCase)

Next c

End Sub

Public Sub Minusculas()


Dim c As Range

For Each c In Selection

c.Value = StrConv(c.Value, vbLowerCase)

Next c

End Sub

'NOTA la funcion StrConv solo esta disponible de Excel 2000 en adelante


'para versiones anteriores hacerlo de esta forma

Public Sub Mayusculas()


Dim c As Range

For Each c In Selection

c.Value = UCase(c.Value)

Next c

End Sub
Public Sub Minusculas()
Dim c As Range
For Each c In Selection
c.Value = LCase(c.Value)
Next c
End Sub
Comprobamos que trabajen bien, probndolas desde el Editor VBA o desde la interfaz de Excel
desde el men Herramientas | Macro | Macros... o con el mtodo abreviado de teclado Alt + F8
Estas macros las declaramos Publicas (para detalles de este tema lee el articulo Publica o
Privada, cual usar?), pero al guardar nuestro archivo como Complemento, estas macros no
las podrs ver y por consiguiente ejecutar, desde la interfaz de Excel, es como si las macros
pasaran a ser Privadas, entonces, para poder ejecutarlas tienes que asignarlas a alguna
elemento de la pantalla, un men, un botn o algn control, como notaste en los
Complementos Autoguardar y el Solver, estos agregaban una nueva opcin al men
Herramientas, esto no es obligatorio, ya que puedes agregar una opcin en cualquier parte de
los mens o submens existentes o de plano crear un nuevo men propio, para nuestro
ejercicio agregaremos un submen al men Herramientas que se llame Utilidades y dentro de
este las opciones Maysculas y Minsculas, para ello usaremos el siguiente cdigo...
Public Sub PonerMenu()
Dim NuevoMenu As Object
Dim OpcionMenu As Object
Dim MenuHerr As Object
' Busca si el men ya esta existe
Set NuevoMenu = CommandBars.FindControl(Type:=msoControlPopup, Tag:="Utilidades")
' Si no lo encuentra la variable es Nothing
If NuevoMenu Is Nothing Then
' Busca el men Herramientas y devuelve una referencia a el
Set MenuHerr = CommandBars.FindControl(ID:=30007)
' La posibilidad de que sea Nothing es remota pero hay que considerarla
If Not MenuHerr Is Nothing Then
' Agrega un sunmen al men Herramientas
Set NuevoMenu = MenuHerr.Controls.Add(Type:=msoControlPopup, Temporary:=True)
With NuevoMenu
' Le ponemos Titulo
.Caption = "&Utilidades"
' Usamos esta propiedad como utilidad para la busqueda
.Tag = "Utilidades"
'Garantizamos que este visible
.Visible = True
End With
Set OpcionMenu = NuevoMenu.Controls.Add(Type:=msoControlButton, _
Temporary:=True)
With OpcionMenu
.Caption = "Mayusculas"
'Le asignamos la macro que queramos ejecutar
.OnAction = "Mayusculas"
End With
Set OpcionMenu = NuevoMenu.Controls.Add(Type:=msoControlButton, _
Temporary:=True)
With OpcionMenu
.Caption = "Minusculas"

.OnAction = "Minusculas"
End With
End If
End If
'Liberamos la memoria
Set MenuHerr = Nothing
Set NuevoMenu = Nothing
Set OpcionMenu = Nothing
End Sub
Public Sub QuitarMenu()
Dim Menu As Object
'Busca el menu, si lo encuentra lo borra, si no, no hace nada
Set Menu = CommandBars.FindControl(Type:=msoControlPopup, Tag:="Utilidades")
If Not (Menu Is Nothing) Then
Menu.Delete
End If
End Sub
Ahora, para que la macro PonerMenu se ejecute de forma automtica al abrir el Complemento
y la macro QuitarMenu se ejecute automticamente al cerrar el Complemento, las "llamamos"
desde los eventos Open y BeforeClose del libro, respectivamente...
Desde el Editor VBA selecciona el objeto ThisWorkbook
Ve al men Ver | Cdigo o presiona la tecla F7
Copia o escribe el siguiente cdigo.
Option Explicit
Private Sub Workbook_BeforeClose(Cancel As Boolean)
QuitarMenu
End Sub
Private Sub Workbook_Open()
PonerMenu
End Sub
Ahora, antes de guardarlo como un Complemento, guarda el archivo con estos ltimos cambios
de modo que siempre tengas un "respaldo" de tu complemento como un libro normal XLS.
Ve al men Archivo | Guardar Como... y del cuadro de lista desplegable (ComboBox) Guardar
como tipo, buscas y seleccionas Complemento de Microsoft Excel (*.xla)

Establece el nombre del Complemento, normalmente ser el mismo de mi archivo XLS, pero
antes de aceptar y cerrar este cuadro de dialogo, observa como Excel, al decirle que queremos
guardarlo como Complemento, solito nos cambia la ruta de acceso, da un clic en el cuadro de
lista desplegable (ComboBox) Guardar en, y observa la ruta donde lo dejara, la cual
normalmente es
C:\WINDOWS\Application Data\Microsoft\Complementos
claro, en este momento, si lo deseas, puedes cambiar esa ruta y guardar tu complemento
donde gustes.

En este momento ya tienes dos archivos, uno XLS y otro XLA, aunque el XLA (el
Complemento) no queda abierto en estos momentos, hay que cargarlo para probarlo y es lo
que haremos a continuacin.
Cierra y vuelve a entrar a Excel, esto es con la finalidad de que reconozca el nuevo
complemento, NO es indispensable, pero ya te iras dando cuenta, cuando es conveniente
hacerlo y cuando no.
Ve al men Herramientas | Complementos, la lista de complementos esta en orden alfabtico,
as, que si has usado los nombres propuestos, desplzate hasta la letra U y debe de aparecer
el Complemento Utilidades como se ve en la siguiente imagen, en caso de que hayas
guardado tu complemento en otro lugar, tienes que usar el botn de comando
(CommandButton) Examinar... para localizarlo...

Ve al men Herramientas y observa como tenemos nuestro men personalizado, agregado


automticamente al cargar nuestro complemento y que ser eliminado automticamente al
cerrarse o descargarse.

Prubalo, llena algunas celdas con texto y convirtelas a MAYUSCULAS o minsculas, prueba
a hacerlo en cualquier otro libro, prueba a cargar y descargar el complemento para verificar
que se elimina el men correctamente.
Por ultimo, habrs notado en los complementos instalados que al seleccionar en la lista de
Complementos, en al parte inferior aparece una breve descripcin del propsito de dicho
complemento, si bien esto no puede sustituir a la documentacin que debe de acompaar a
todo cdigo o programa, es til para de primera mano, saber la utilidad del complemento,
agregumosle esta propiedad a nuestro complemento, para esto, descarga el complemento y
abre el archivo XLS original.
Ve al men Archivo | Propiedades... y selecciona la ficha Resumen, en esta, puedes llenar
todos los campos que quieras, pero los importantes son: Titulo y Comentarios, el campo
Titulo ser lo que aparezca en el cuadro de lista Complementos y el campo Comentarios se
ver en la parte inferior de dicho cuadro, compltalos a tu gusto, te muestro lo que yo escrib...

Vuelve a realizar el proceso de guardar como Complemento, por supuesto, al querer guardarlo
con el mismo nombre, te preguntara si quieres reemplazarlo, respondes que si y cierras y
vuelves a entrar a Excel, vas al men Herramientas | Complementos buscas tu complemento y
veras que corresponde lo que escribiste en los campos de las propiedades del archivo, con lo
que ves aqu...

Muy bien hecho, cierto, todava puede tener muchas mejoras y las tiene, sobre todo en lo que respecta
a controlar errores, pero eso se ver en otro capitulo, por lo pronto con esto basta...

La mayora de las macros y funciones que hagamos, son susceptibles de usarse desde un modulo
estndar y un libro comn como macro o incorporarse a un Complemento, con el uso y la experiencia,
tu mismo discernirs cuando es conveniente lo uno y cuando lo otro.
Para los miembros de la lista, el archivo original XLA esta disponible en el rea de archivos.

Descargar el cdigo de este artculo.


Exportador de macros
Este complemento, extrae de todos los libros abiertos, las macros o funciones que contenga, con la posibilidad
de Exportarlas a cualquir otro libro abierto, al cargarlo, te agrega una nueva opcin al men Herramientas,
llamada Exportar Macros... el cual, al ejecutarlo, te muestra el siguiente cuadro de dialogo

Su uso de detallar en esta pgina, aunque realmente es muy sencillo, el complemento esta disponible en el
rea de ficheros de la lista, o puedes descargarlo desde aqui, te aclaro que para que puedas ver el cdigo, el
archivo esta guardado como XLS, pero puedes guardarlo como complemento, pues esta pensado para que
funcione como tal...
Descargar el Complemento Exportar Macros de este artculo.

También podría gustarte