Macros de Excel y VBA - para Personas Ocupadas - Aprende en Poco Tiempo A Crear Macros Que Hagan El Trabajo Duro Por Ti. (Spanish Edition)
Macros de Excel y VBA - para Personas Ocupadas - Aprende en Poco Tiempo A Crear Macros Que Hagan El Trabajo Duro Por Ti. (Spanish Edition)
* * * * *
* * * * *
Si los pasos que sigues son siempre los mismos o muy similares, entonces
puedes crear una macro de Excel para que haga ese trabajo por ti.
Por otra parte, también puede ayudarte a ser mucho más productivo en tu
trabajo y sobresalir de entre todos tus compañeros.
Entonces cada vez que debes enviar la hoja de cálculo a alguien, pasas todas
las fórmulas a valores absolutos. Pero para ahorrarte ese trabajo, has creado
una macro.
Como aún no hemos visto como crear macros, puedes descargar la macro de
la que hablo haciendo clic aquí
Menú Archivo
Abre el archivo que descargaste y verás que en la celda C6 hay una formula
(es una formula muy sencilla, pero esto no es importante por ahora)
Si vas al nuevo menú Programador, luego presionas el botón que dice
Macros veras que se abre una ventana, selecciona la primera macro en la lista
y presiona el botón Ejecutar, esto hará que todas las fórmulas en esta hoja
sean reemplazadas por su valor en texto, eliminado su fórmula, pero no su
resultado
Existen otras formas para ejecutar una macro, pero por el momento vamos a
utilizar esta.
Tu primer macro
Ahora que ya ejecutaste tu primera macro es hora de que crees tú primer
macro. Crea un archivo nuevo de Excel y en el menú Programador presiona
el botón Grabar macro
Luego veras una ventana en la que tienes que colocar un nombre para la
macro, una descripción y presionar el botón Aceptar
Ahora Excel va a grabar todo lo que hagas, por ejemplo, selecciona primera
fila de la hoja de cálculo y coloca un color de fondo, puedes hacer cualquier
cosa que desees. Cuando termines presiona el botón Detener grabación
Detener grabación
Ya está, has creado tu primer macro. Puedes ejecutarla como lo hiciste con la
macro que descargaste, pero para poder ver que repite todo, puedes
seleccionar una hoja nueva.
Si intentas grabar este archivo, vas a recibir una advertencia, y es que las
hojas de cálculo “normales” no pueden contener macros. Para poder grabar y
conservar tu macro debes de elegir el formato de archivo Libro de Excel
habilitado para macros
Archivo con macros
Hasta ahora las macros que crees, son parte del archivo en que estas
trabajando, si el archivo no está abierto, la macro no está disponible. En
otros capítulos vamos a aprender a hacer que tu macro este siempre
disponible
Ejercicio
Ahora viene la parte práctica, imagina algo que has estado haciendo en Excel,
y que repites una y otra vez. Intenta crear una macro que automatice el
trabajo y lo haga por ti.
Tiene que ser algún muy sencillo como dar formato a algo, cambiar algún
nombre, borrar columnas que no usas o algo así, recuerda que estas
comenzando, luego podrás hacer cosas más difíciles.
Introducción a VBA
En este capítulo aprenderás qué es VBA, cómo usar el editor de VBA para
crear macros usando código de programación y a editar macros grabadas con
la grabadora de macros.
Qué es VBA
VBA significa Visual Basic for Applications, este es un lenguaje de
programación hecho por Microsoft para automatizar cualquier cosa en su
suite de oficina Office. Está basado en Visual Basic, por lo que sus comandos
son prácticamente los mismos.
Cada opción, cada botón que presionas, cada cosa que haces en Excel Puede
ser realizada mediante código de VBA, de hecho, cuando grabas una macro
usando la grabadora, cada acción que haces se guarda como código de VBA.
Editor de VBA
Existen varios menús y herramientas, pero los iremos viendo en detalle poco
a poco para no saturarte con información.
Macro a editar
Seleccionara la celda C1
Escribir el texto Teléfono
Comentarios en el código
Si has puesto atención, cuando observas el código que genera la grabadora de
macros de Excel, genera algunos textos, que no son comandos en las macros,
estos se llama comentarios y ayudan a que el código sea más fácil de leer y
entender por nosotros los humanos.
Todos estos problemas (y otros más) se resuelven al leer los comentarios que
has escrito en el código. Ahora que ya sabes por qué debes usar los
comentarios, veamos cómo puedes usarlos.
Si escribes una comilla simple ', eso indica que toda la línea es un
comentario y será ignorada como código. Y ya que los comentarios no se
ejecutan, entonces otro uso que se le da a los comentarios es el de deshabilitar
temporalmente un bloque de código.
Ahora para comentar un bloque, solo marcas el texto y presionas uno de los
botones en la barra de herramientas para comentar o descomentar el bloque.
Intenta hacerlo tú mismo.
Comentar bloque
Ejercicio
Tan solo hemos iniciado a conocer VBA, entonces el ejercicio de este
capítulo es sencillo, debes grabar una macro (usando la grabadora), haz algo
sencillo, por ejemplo una macro que escriba “Hola mundo” en la celda en
donde te encuentres, luego entra al editor de VBA y explora la macro, revisa
el código que se generó e intenta modificar “Hola mundo” por cualquier otro
texto, luego corre la macro y comprueba que lo hiciste bien.
Introducción a la programación
Como has visto hasta ahora, puedes crear macros sin necesidad de programar,
todo se ha hecho usando la grabadora de macros.
Pero para sacar el máximo provecho de las macros de Excel, necesitas crear
macros usando código de VBA. Por eso ahora vas a crear tu primer macro
desde cero y usando solo código de programación.
Lista de productos
Ahora presiona las teclas Alt+F11 para abrir el editor de VBA y haz clic
derecho sobre el proyecto VBAProject con el nombre de tu hoja de cálculo y
selecciona la opción de menú Insertar > Módulo
Insertar modulo
Ahora vas a crear una subrutina, todas las macros que creas en la grabadora
son subrutinas. Para crearla solo debes escribir algo como esto:
1 Sub calcula_precios()
2
3 End Sub
Acabas de crear una macro vacía, para que funcione necesita algo de código
(instrucciones de lo que debe hacer), ahora puedes modificarla de forma que
te quede así:
1 Sub calcula_precios()
2
3 Dim costo
4 Dim fila As Integer
5
6 'Coloca encabcezado
7 Range("D1").FormulaR1C1 = "Precio"
8
9 'Recorrer todas las filas
10 fila = 2
11 costo = Range("C" & fila).FormulaR1C1
12 Do While IsNumeric(costo) 'Procesar mientras el costo sea un numero
13 'Calcular el precio
14 Range("D" & fila).FormulaR1C1 = costo * 1.3
15
16 'Pasar a las siguiente fila y leer el costo
17 fila = fila + 1
18 costo = Range("C" & fila).FormulaR1C1
19 Loop
20
21 End Sub
Puedes descargar la hoja de Excel junto con su macro haciendo clic aquí.
Funciones o subrutinas
En VBA usualmente ingresas el código en una función o en una subrutina,
ambos términos se refieren a fragmentos de códigos que realizan una tarea
específica y puede ser llamados las veces que necesites. Realmente no hay
una limitante sobre la cantidad de tareas que pueda realizar una subrutina o
una función, esto es simplemente una buena práctica, ya que de esta forma
puedes reutilizar el código fácilmente, es menos propenso a errores y es más
fácil de modificar o mejorar.
El ejemplo más común de funciones son las funciones que vienen en Excel,
por ejemplo, la función SUMA que recibe un rango de celdas y regresa la
suma de todos sus valores. Un ejemplo de una subrutina es una macro que
genera un reporte de Excel, esta subrutina no regresa ningún valor, pero si
puede realizar cambios en una hoja de Excel. Las funciones también pueden
hacer cambios en una hoja de Excel, pero su uso habitual es devolver un
valor.
Otra diferencia importante es que solo puedes llamar macros desde una hoja
de Excel a aquellas que has creado como subrutinas que no lleven ningún
parámetro. Puedes hacer la prueba con la subrutina que acabas de crear.
Insertar modulo
Algunas de estas palabras que no puedes usar son: Function, Sub, Dim, etc.
Para una lista completa puedes consultar este artículo que detalla todas las
palabras reservadas.
Ahora, para declarar una variable utilizas la palabra Dim seguida del nombre
de tu variable y opcionalmente la palabra as seguida del tipo de datos, por
ejemplo, para declarar una variable llamada fila y de tipo numérico usamos
un código como este:
1 Dim fila As Integer
Si has intentado aprender VBA por tu cuenta, quizá sepas que no es necesario
declarar una variable para poder usarla, pero si es una buena práctica hacerlo.
Te recomiendo que siempre las declares, si no lo haces podrías crear errores
lógicos, los cuales son muy difíciles de corregir. Por ejemplo, imagina que
usas una variable llamada impuestos, luego haces algunos cálculos y tratas
de consultar su valor, pero te equivocas y escribes impuesto, es decir, olvidas
colocar la letra s al final. Lo que pasará es que no obtienes ningún error, pero
leerás el contenido de una variable sin declarar y sin el valor que esperas.
Para evitar este tipo de error puedes forzar a VBA a que siempre te pida
declarar las variables, para esto seleccionas el menú Herramientas >
Opciones y en la pantalla que se muestre debes marcar la opción Requerir
declaración de variables.
Ahora te verás obligado a declarar siempre cada variable que utilices, pero a
cambio ahorrarás mucho tiempo tratando de encontrar errores lógicos. Para
declarar una variable puedes usar cualquiera de estos tipos de datos:
Tipo de
Rango de valores
datos
Boolean True o False (Verdadero o Falso)
Integer números del –32,768 al 32,767
Long números del –2,147,483,648 al 2,147,483,647
Single números del –3.402823E38 al 1.401298E45
números del –1.79769313486232E308 al –
Double
4.94065645841247E-324
números del 4.94065645841247E–324 al
Double
1.79769313486232E308
Date Fechas del 1/1/100 al 31/12/9999
String Cualquier texto
Object Cualquier objeto
Variant Cualquier valor de cualquier tipo
Currency –922,337,203,685,477.5808 a 922,337,203,685,477.5807
Nota: El tipo Double está dos veces, por que posee dos rangos, uno para
valores negativos y otro para valores positivos.
Ya sabes cómo declarar una variable, ahora, para asignarle un valor solo
escribes el nombre de la variable y escribes un signo = y el valor que deseas
asignar, por ejemplo:
1 Dim fila as Integer
2 Dim texto as String
3
4 fila = 1
5 texto = "Hola mundo"
Como puedes notar los valores numéricos se colocan tal y como los ves, pero
los valores de texto se escriben entre comillas dobles. Ahora que tienes
valores definidos en tus variables, puedes utilizarlos en tu macro, veamos un
ejemplo sencillo del uso de variables, donde tendremos una macro que
actualiza el contenido de una celda.
1 Sub variables()
2 Dim texto As String
3
4 texto = "Hola mundo"
5
6 'Accedemos y cambiamos el contenido de la celda activa
7 ActiveCell.FormulaR1C1 = texto
8
9 End Sub
Intenta crear y ejecutar la macro anterior en una hoja de Excel, y verás que
una vez que hayas asignado un valor a la variable texto, podrás usarla y la
macro entenderá que debe usar el valor asignado en la variable. Modifica el
valor de la variable texto y revisa lo que pasa cuando la ejecutas de nuevo.
Para el caso anterior 0.13 es el factor para el IVA (un impuesto) y cuando
estas leyendo el código de tu macro es más fácil de entender cuando usas
constantes mira estos dos ejemplos idénticos y piensa cual es más legible:
1 impuesto = precio * 0.13
2
3 impuesto = precio * FactorIVA
Puedes ver los arreglos como una lista de cosas, por ejemplo, una lista del
supermercado, en la que puedes agregar más cosas que deseas o borrar algo
que ya no quieres, también puedes leer la lista de forma secuencial, es decir,
del primer ítem, hasta el último, o puedes consultar: “Cual es el primer
producto en mi lista” y leer solo ese, por que has dado su índice (el primero
en la lista).
En el código anterior usamos el signo >=, esta es una comparación entre dos
valores. Las comparaciones que puedes hacer son:
Operador Resultado
Verdadero, si ambos valores son iguales, sino regresa
=
Falso
Verdadero, si ambos valores son diferentes, sino regresa
<>
Falso
Verdadero, si el primer valor es mayor que el segundo,
>
sino regresa Falso
Verdadero, si el primer valor es menor que el segundo,
<
sino regresa Falso
Verdadero, si el primer valor es mayor o igual que el
>=
segundo, sino regresa Falso
Verdadero, si el primer valor es menor o igual que el
<=
segundo, sino regresa Falso
Tanto en la vida como en las macros, las decisiones no siempre son sencillas,
puedes necesitar hacer más de una evaluación y para esto necesitas
operadores lógicos para unir todas las evaluaciones que necesites.
Expresión Resultado
1 = 1 And Falso (el primero bloque es cierto, pero el segundo es falso
1=2 entonces todo es falso)
1 = 1 And
Verdadero (ambas expresiones son verdaderas)
2=2
1 = 1 Or 1 Verdadero (la primera expresión es verdadera, entonces no
=2 importa el resultado de la segunda)
1 = 2 Or 2 Verdadero (la segunda expresión es verdadera, entonces
=2 no importa el resultado de la primera)
1 = 2 Or 2
Falso (Ambas expresiones son falsas)
=1
Not 1 = 1 Falso (La expresión es verdadera, pero esta negada)
Not 1 = 2 Verdadero (La expresión es falsa, pero esta negada)
Cuando usamos una expresión if, la parte del else es opcional y también
debes de saber que puedes anidar sentencias if, para comprender mejor esto,
veamos un ejemplo:
1 Sub OperadoresLogicos()
2 Dim categoria As String
3 Dim cantidad As Single
4 Dim precio As Currency
5
6 cantidad = 10
7 categoria = "vip"
8 precio = 100
9
10 'Evaluar descuento
11 If cantidad >= 10 Then
12 'If anidado: es un if dentro de otro if
13 If categoria = "vip" Then
14 'Aplicar 30% de descuento
15 precio = precio * 0.7
16 MsgBox "El nuevo precio es " & precio
17 End If
18 End If
19 End Sub
El if anidado es un bloque if, dentro de otro bloque if, puedes utilizarlo para
tomar decisiones más complicadas, sin embargo, anidar muchos if puede
generar código difícil de leer. Para evitar este problema existe otra sentencia
llamada Select Case, en ella se evalúan varias condiciones y se puede
ejecutar un bloque de código por cada evaluación.
Para comprender mejor cuando usar una sentencia if o Select Case veamos
una misma macro en las dos versiones. Imagina que te piden una macro para
determinar el descuento que aplica a un producto en base a la cantidad que
compran aplicando estos criterios:
Como puedes observar, tantos if anidados puede ser algo confuso. También
debes notar que he introducido la función InputBox que permite preguntar al
usuario un valor y guardarlo en una variable, esto hará que sea más fácil
probar esta macro. Después de probar esta macro intenta probar la versión
Select Case y verás que el resultado es el mismo, pero el código es más
limpio y fácil de entender.
1 Sub DescuentoSelectCase()
2 Dim cantidad As Single
3 Dim descuento As Single
4 cantidad = InputBox("Ingrese cantidad")
5
6 Select Case cantidad
7 Case 0 To 20
8 descuento = 0
9 Case 21 To 30
10 descuento = 10
11 Case 31 To 40
12 descuento = 15
13 Case 41 To 50
14 descuento = 20
15 Case Else
16 descuento = 25
17 End Select
18
19 MsgBox "El descuento es de " & descuento & "%"
20 End Sub
Operador Descripción
+ Suma
* Multiplicación
/ División
- Resta
^ Exponenciación
\ División entera (regresa solo la parte entera, sin decimales)
Mod Regresa el residuo de una división, por ejemplo 5 mod 2 =
1
& Concatenar dos cadenas de texto (unir dos textos)
Ya hemos utilizado algunos de estos operadores de los ejemplos anteriores,
pero tener esta lista te servirá como referencia.
El ciclo for se usa cuando conoces la cantidad de veces que necesitas repetir
el bloque de código, la sintaxis (estructura) del bloque for es:
1 for variable = valorInicial to valorFinal Step 1
2 'Ejecutar codigo
3 Next variable
Debes declarar una variable que se usará como contador, luego defines un
valor inicial y un valor final, opcionalmente puedes definir el valor del
incremento con la instrucción Step que de forma predeterminada es 1, si
piensas hacer incrementos de 1 puedes no usarla.
Por ejemplo, imagina que debes generar una hoja de Excel que contiene el
número de filas en la columna A, y que inicia desde la celda A2, entonces la
celda A2 tendrá 1, la celda A3 tendrá 2 y así sucesivamente hasta llegar a 10.
Entonces el código para hacer eso sería este:
1 Sub CicloFor()
2 Dim fila As Integer
3
4 For fila = 1 To 10
5 Range("A" & fila + 1) = fila
6 Next fila
7
8 End Sub
La función Range se puede usar para hacer referencia a una celda de la hoja
actual, recibe como parámetro el nombre de la celda por ejemplo A1 pero
como sabemos que es la columna A, pero desconocemos el número de la fila,
entonces usamos una concatenación de la A y el contenido de la variable fila
+ 1 y le asignamos el contenido de la variable fila que en cada ciclo
contendrá 1, 2, 3…10
Usamos este ciclo en la macro que creamos al inicio del capítulo, aquí está de
nuevo para que la recuerdes:
1 Sub calcula_precios()
2
3 Dim costo
4 Dim fila As Integer
5
6 'Coloca encabcezado
7 Range("D1").FormulaR1C1 = "Precio"
8
9 'Recorrer todas las filas
10 fila = 2
11 costo = Range("C" & fila).FormulaR1C1
12 Do While IsNumeric(costo) 'Procesar mientras el costo sea un numero
13 'Calcular el precio
14 Range("D" & fila).FormulaR1C1 = costo * 1.3
15
16 'Pasar a las siguiente fila y leer el costo
17 fila = fila + 1
18 costo = Range("C" & fila).FormulaR1C1
19 Loop
20 End Sub
Hay algo muy importante que debes conocer, como ves este ciclo se repite un
valor indefinido de veces y al final de este ciclo, he actualizado el valor de la
variable costo, con el contenido de la siguiente fila, si no hago esto entonces
la comparación que hace el ciclo no va a cambiar nunca y el resultado será
siempre verdadero, no habrá forma de terminar el ciclo y esto se conoce
como ciclo infinito, tu computadora quedara atrapada en un ciclo sin fin hasta
que reinicies tu computadora o termines el proceso con el administrador de
tareas.
Repetir al menos una vez sin importar la condición, y luego repetir mientras
la condición sea verdadera.
1 Do
2 'Bloque de Codigo
3 Loop While Condicion
Repetir al menos una vez sin importar la condición, y luego repetir mientras
la condición sea falsa.
1 Do
2 'Bloque de Codigo
3 Loop Until Condicion
Ejercicio
El ejercicio de este capítulo es sencillo, con la macro que creamos al inicio y
con lo que has aprendido trata de hacer algunas modificaciones, por ejemplo:
1. Motor sobre calentado: Envía señal informando que el motor está muy
caliente.
2. Gasolina a nivel mínimo: Envía señal informando que la gasolina está
por terminarse.
Ahora veamos cómo se aplica esto a Excel, existe una clase llamada
Workbook (en español seria Libro, es decir un archivo de Excel) y cada vez
que se crea o se abre un archivo de Excel se crea un objeto con la definición
de esa clase. Este objeto va a tener muchos métodos, propiedades y eventos,
pero voy a mencionar solo un ejemplo de cada uno.
Objetos de Excel
Ahora que ya sabes que son los objetos, es hora de conocer los objetos más
importantes para trabajar con macros en Excel.
Application
Este objeto representa la aplicación de Excel, desde aquí puedes acceder a
todo, a los libros, las hojas de cada libro, las celdas y todo su contenido. Para
nuestra conveniencia hay algunos objetos que se puede acceder directamente
sin hacer referencia a este objeto, aunque todos estén dentro de este objeto
Application, sin embargo, hay algunas opciones de configuración que solo
puede ser utilizadas desde aquí.
Workbooks
Es en realidad una colección de objetos, aquí se encuentran todos los objetos
Workbook, los cuales a su vez representan un libro o archivo de Excel. Desde
aquí puedes acceder a todos los libros que están abiertos y crear o abrir otros.
Sheets
Se encuentra dentro de un objeto Workbook y es una colección que contiene
todas las hojas del libro al que pertenece, desde cada hoja individual puedes
acceder a todo lo relacionado ella, como su nombre y celdas, Además desde
esta colección puedes crear, eliminar o modificar las hojas del libro.
Range
Ya usamos anteriormente este objeto, y puede representar una celda
individual o un rango de celdas el cual puede abarcar todas las celdas de la
hoja a la que pertenece.
Para dejar todo más claro aquí hay una imagen con la jerarquía de cómo están
organizados todos estos objetos.
Representación de objetos en Excel
## Referencias a objetos
La buena noticia es que existen referencias o atajos para no tener que escribir
tanto para llegar al objeto que necesitamos, las referencias a objetos más
utilizadas son:
Eventos de Excel
Hasta ahora ya sabes cómo ejecutar una macro manualmente y como lo
mencione antes, los eventos de un objeto envían un mensaje de que algo ha
ocurrido. Lo que debes de saber ahora es que el evento también te permite
ejecutar una macro o cualquier código de VBA de forma automática en
respuesta a ese evento.
Agregar un evento
Al hacer eso, Excel va a generar una plantilla para el evento como esta:
1 Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
2
3 End Sub
En este caso hay algunos parámetros entre paréntesis, puedes notar que el
primero inicia con ByVal, eso significa que puedes hacer uso de lectura de ese
parámetro (ByVal significa por valor), el segundo parámetro no tiene esa
palabra, eso significa que tienes acceso total y puedes leerla y modificarla.
Entonces vamos a modificar ese parámetro Cancel, si lo hacemos igual a
True, entonces el proceso se cancela y Excel no va a guardar el documento,
esto puede ser útil para realizar alguna validación. Validemos que la celda A1
deba tener algún valor antes de guardar, escribiendo este código:
1 Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
2 If Range("A1").FormulaR1C1 = "" Then
3 MsgBox "Antes de guardar debe ingresar un valor valido, en la celda A1"
4 Cancel = True
5 End If
6 End Sub
Ejemplo practico
Ya tenemos bastante teoría hasta ahora, ya es tiempo de ver cómo aplicar
todo esto mediante un ejemplo. Imagina que tienes un libro de Excel con 3
listas de precios: Clientes regulares, Clientes al mayoreo y Clientes VIP.
Cada lista de precios está en una hoja diferente, pero en el mismo libro y si
un cliente te solicita la lista de precios no puedes enviarle las 3 listas, además
la lista contiene una columna de costo y no quieres que el cliente conozca tus
costos, pero si tus precios.
Puedes descargar una hoja con la macro ya hecha para que puedas
probarla, haciendo clic en este enlace
Primero vamos a necesitar una macro para poder solicitar al usuario en que
carpeta guardar los archivos nuevos, para esto vamos a usar una macro
genérica que podremos reutilizar en otros proyectos.
1 ' Pedir a usuario que seleccione una carpeta
2 Function SolicitarCarpeta() As String
3 Dim dialogoArchivo As FileDialog
4 Set dialogoArchivo = Application.FileDialog(msoFileDialogFolderPicker)
5
6 dialogoArchivo.Title = "Select a Folder"
7 dialogoArchivo.AllowMultiSelect = False
8 dialogoArchivo.InitialFileName = Application.DefaultFilePath
9 If dialogoArchivo.Show <> -1 Then
10 SolicitarCarpeta = ""
11 Else
12 SolicitarCarpeta = dialogoArchivo.SelectedItems(1)
13 End If
14
15 End Function
Ahora vamos a crear la macro que haga el resto del trabajo, el código es el
siguiente:
1 'Genera un archivo por cada hoja en este libro
2 Sub GeneraArchivosPrecios()
3 Dim carpeta As String
4 Dim i As Integer
5 Dim LibroNuevo As Workbook
6 Dim LibroActual As Workbook
7
8 'Preguntar en que carpeta colocar este archivo
9 carpeta = SolicitarCarpeta
10
11 If carpeta = "" Then
12 MsgBox "No selecciono la carpeta en donde se guardaran los archivos"
13 Else
14 Set LibroActual = ActiveWorkbook
15
16 'Se deshabilita la actualizacion de la pantalla
17 'para evitar ver un parpadeo en la pantalla
18 Application.ScreenUpdating = False
19 For i = 1 To LibroActual.Sheets.Count
20 'creamos un libro nuevo.....
21 Set LibroNuevo = Workbooks.Add
22
23 'Hacemos la copia de toda la hoja en el nuevo libro
24 LibroActual.Sheets(i).Copy Before:=LibroNuevo.Sheets(1)
25
26 'Eliminar columna de costo (C)
27 LibroNuevo.Sheets(1).Columns(3).EntireColumn.Delete
28
29 'Guardar libro en la carpeta definida y con el nombre de la hoja
30 LibroNuevo.SaveAs carpeta & "\" & LibroActual.Sheets(i).Name
31
32 'Cerrar el libro
33 LibroNuevo.Close
34 Next i
35 'Habilitar de nuevo la actualizacion de pantalla
36 Application.ScreenUpdating = true
37 End If
38
39 End Sub
Con el tiempo y la práctica vas a conocer muy bien todos estos objetos, pero
para comenzar puedes usar la documentación, para acceder a ella, desde el
editor de VBA presionas la tecla F2 y veras una pantalla como esta:
Examinador de objetos
En la parte izquierda se encuentra una lista de todas las clases (yo use la clase
Sheets para acceder a las hojas) y cuando seleccionas una clase, en la parte
derecha puedes ver la lista de propiedades (las que tienen un icono con una
mano) y métodos (los que tienen un icono con un rectángulo verde).
Si tienes dudas de cómo usar algún método, puedes hacer clic derecho y
seleccionara Ayuda del menú contextual. Eso te llevara a una página web
como ésta, con más detalle:
Ayuda de clases
Ejercicio
En el capítulo 3 hicimos una macro que calculaba el precio en base a un
costo, modifica esa macro para que además de generar la columna de precios,
también genere dos hojas más, en ese mismo archivo con diferentes precios
basados en márgenes de 30%, 25% y 20%.
Extendiendo Excel
Ahora que ya tienes conocimientos más profundos sobre VBA y los objetos
de Excel, es hora de extender un poco a Excel y agregar algunas cosas que
nos ayuden a trabajar más rápido, como empaquetar algunos cálculos que
realices con frecuencia y convertirlos en funciones o ir un poco más allá y
convertir macros en complementos de Excel que puedas usar en todas las
hojas de Excel.
Vamos a una función que haga eso, va a recibir un valor (el costo) y a hacer
el cálculo del precio final, crea un archivo de Excel y agrega un módulo y
este código:
1 Function calculaPrecio(costo As Currency)
2 Dim precio As Currency
3
4 'Agregar 30% de margen
5 precio = costo * 1.3
6
7 'Agregar 13% de IVA (Impuesto de ventas)
8 precio = precio * 1.13
9
10 'El mismo nombre de la funcion tambien funciona como
11 'variable en donde se asigna el valor a devolver
12 calculaPrecio = precio
13 End Function
Entonces para crear tus propias funciones, solo debes crear una función en
VBA que reciba los parámetros que necesites y que regrese un valor, ese
valor que regrese será el valor que se muestre en la celda que uses.
Ahora hay algunos problemas que debemos resolver, tú conoces muy bien la
fórmula que creaste y sabes para que sirve y que parámetros usas, pero otras
personas no lo saben y es por eso que debes agregar descripciones a la
función y a sus parámetros.
Descripción de funciones
Vamos a usar como ejemplo la función que ya creamos, sigue los pasos
anteriores y la macro debe de quedar de esta forma:
1 Private Sub Workbook_Open()
2 'Declarar un array para las descripciones de cada argumento
3 Dim Param(1 To 1) As String
4 'Asignar la descripcion
5 Param(1) = "Costo del producto"
6
7 'Registrar la descripcion de la macro y de los parametros
8 Application.MacroOptions Macro:="calculaPrecio", _
9 Description:="Calcula un precio en base a un costo y agrega el impuesto de
venta\
10 s", _
11 ArgumentDescriptions:=Param
12 End Sub
Ahora, como esta macro se creó en el evento Open, deberás cerrar el libro y
volver a abrirlo para que tome los cambios o ejecutar el evento manualmente
la primera vez.
Nota: VBA no tiene ningún signo que defina el fin de línea, como un
punto o punto y coma, entonces se entiende que la instrucción o
sentencia termina cuando haces un salto de línea, pero puedes escribir
una sentencia en varias líneas si escribes un guion bajo para indicar que
la sentencia continua en la siguiente línea, tal y como lo hice en la macro
anterior. Esto hace que la macro sea más legible en los casos en que el
código es demasiado largo para verse completamente en la pantalla.
Veamos como seria ahora, si tuviéramos que registrar dos o más macros y
con más de un parámetro. La forma más ordenada seria creando una macro
para generar las descripciones de cada macro y luego llamarlas desde el
evento Open de esta forma:
Puedes descargar este ejemplo con las dos funciones haciendo clic aquí.
Parámetros opcionales
En ocasiones podemos tener una función con parámetros opcionales,
imaginemos una función para aplicar un descuento que recibe el precio y el
tipo de cliente. Dependiendo de si el tipo de cliente es VIP o no, se aplicará
un descuento diferente, si no se define un tipo de cliente entonces se aplica el
descuento mínimo que es 5%.
Instalar complementos
Probar complemento
desinstalar-complemento
## Ejercicio
Toma la macro que hiciste en el ejercicio del capítulo 4 y convierte esa hoja
en un complemento, luego instala el complemento en tu Excel y prueba si
funciona correctamente.
Corrigiendo Errores
Somos humanos y siempre cometemos errores, lo importante es que
aprendemos de ellos y hacemos lo posible por no repetirlos, entonces es de
esperar que al inicio nuestras macros tengan muchos errores, pero con el
tiempo eso va a cambiar. Sin embargo, todo código escrito por humanos
podría contener errores y todos los lenguajes de programación nos proveen de
herramientas para minimizarlos.
En este capítulo voy a explicarte los tipos de errores que puedes esperar y
como encontrarlos y corregirlos.
Errores de sintaxis
Estos errores son los más sencillos de detectar y corregir, ya que el mismo
editor de VBA nos advierte y no permite ejecutar la macro hasta que lo
corregimos. Los errores de sintaxis se dan porque nos hemos equivocado al
usar alguna instrucción o no hemos seguido las reglas. Por ejemplo, observa
esta macro y trata de encontrar el error.
1 Sub TengoUnError()
2 Dim numero As Integer
3 If numero >= 0
4 'Hacer algo
5 End If
6 End Sub
Entonces nos equivocamos al omitir la palabra then. Para evitar estos errores
vamos a necesitar obtener un conocimiento de las sentencias de VBA y eso
solo nos lo puede dar la práctica, entre más código escribas, mejor te
volverás.
Una forma de eliminar estos errores es validando los datos antes de usarlos,
aquí está el código anterior con su corrección:
1 Sub divisionEntreCero()
2 Dim precio As Currency
3 Dim cantidadPagos As Single
4 Dim cuota As Currency
5
6 precio = 125
7
8 If cantidadPagos > 0 Then
9 cuota = precio / cantidadPagos
10 Else
11 cuota = precio 'Todo en una sola cuota
12 End If
13
14 End Sub
Errores lógicos
Estos son los errores más difíciles de detectar y corregir, se dan por que el
programa ha implemento un código equivocado, por ejemplo, imagina que
debes calcular el margen de un producto y sabes que la fórmula para eso es:
1 margen = ingresos - costos
Ahora has iniciado la ejecución de código paso a paso, para avanzar puedes
presionar las teclas F8, Mayus+F8, Cltr+Mayus+F8 o Ctrl+F8.
Opciones de ejecución
Puntos de interrupción
Los puntos de interrupción son líneas de código que marcas para que cuando
la ejecución del código llegue a esa línea, el programa se interrumpa e inicie
el modo de depuración justo desde esa línea. Para establecer un punto de
interrupción solo debes hacer clic en la barra gris que está a la izquierda del
código, cuando lo hagas se activará un punto de interrupción justo en la línea
de código que este en esa altura. Sabrás que hay un punto de interrupción
cuando veas un círculo rojo en esa barra.
Debes saber que solamente se pueden crear puntos de interrupción para líneas
de código ejecutables, es decir, no puedes hacerlo para líneas como
declaraciones de variables. Para desactivar un punto de interrupción solo
debes de hacer clic sobre el círculo rojo que corresponde al que deseas
eliminar. Has unas pruebas, para que veas como funciona esta parte
Punto de interrupción
Inspeccionar variables
La inspección de variables permite visualizar el contenido de las variables,
solo debes de estar en modo de depuración. Existen dos formas para ver el
valor de la variable, la primera es colocando el puntero del mouse sobre la
variable y esto hará que aparezca un mensaje tipo “tooltip” para mostrar la
variable y su valor actual, tal y como se ve en esta pantalla:
Inspeccionar un valor
Agregar inspección
Agregar inspección
Ahora se abrirá una ventana con todas las variables que estés inspeccionando
y mostrará su valor actual. De esta otra forma puedes monitorear un conjunto
de variables. Esto te ayudará a revisar si tu código está calculando los valores
de la forma en que tú esperas que lo haga.
Inspecciones
ventana-inmediato
En la función Debug.Print también puedes usar el signo & para unir textos y
variables, para crear mensajes más informativos, por ejemplo:
1 Debug.Print "El precio con descuento es: " & precioConDescuento
Error en ejecución
Tenemos dos opciones para tratar este problema, la primera es detener toda la
ejecución y mostrar un mensaje indicando el problema, y la segunda es,
ignorar el error y continuar con la ejecución del código restante. La decisión
que tomes va a depender de lo critico que consideres que sea el error, solo
responde esta pregunta: ¿El no haber ejecutado esta instrucción afectará el
comportamiento del código que hace falta ejecutar o dará un resultado
equivocado al usuario?
Una vez tomes la decisión, la forma para ignorar el error y continuar con la
ejecución es colocando esta instrucción al inicio de la subrutina o función:
1 On Error Resume Next
Si usas una función cambia las palabras Exit Sub por Exit Function, si
usaste otra etiqueta que no sea ControlErrores, recuerda también cambiarla
en esta parte dejando siempre los : en la parte derecha (ControlErrores:).
También debes personalizar el mensaje que se muestra con MsgBox, la
variable Err.Description contiene el mensaje de error que genera el
sistema, eso ayudara al usuario a saber cúal es el problema. El código final
deberá verse como este:
1 'Genera un archivo por cada hoja en este libro
2 Sub GeneraArchivosPrecios_MuestraError()
3 Dim carpeta As String
4 Dim i As Integer
5 Dim LibroNuevo As Workbook
6 Dim LibroActual As Workbook
7
8 On Error GoTo ControlErrores
9
10 'Preguntar en que carpeta colocar este archivo
11 carpeta = SolicitarCarpeta
12
13 If carpeta = "" Then
14 MsgBox "No selecciono la carpeta en donde se guardaran los archivos"
15 Else
16 Set LibroActual = ActiveWorkbook
17 Application.ScreenUpdating = False
18 For i = 1 To LibroActual.Sheets.Count
19 'creamos un libro nuevo.....
20 Set LibroNuevo = Workbooks.Add
21
22 'Hacemos la copia de toda la hoja en el nuevo libro
23 LibroActual.Sheets(i).Copy Before:=LibroNuevo.Sheets(1)
24
25 'Eliminar columna de costo (C)
26 LibroNuevo.Sheets(1).Columns(3).EntireColumn.Delete
27
28 'Guardar libro en la carpeta definida y con el nombre de la hoja
29 LibroNuevo.SaveAs carpeta & "\" & LibroActual.Sheets(i).Name
30
31 'Cerrar el libro
32 LibroNuevo.Close
33 Next i
34 Application.ScreenUpdating = True
35 End If
36
37 'Asegurarse que en ejecució normal
38 'no se llegue mas lejos de aqui
39 Exit Sub
40
41 ControlErrores:
42 MsgBox "Ocurrio este error al generar los archivos: " & Err.Description
43 End Sub
Puedes descargar una hoja con estos ejemplos, para que los pruebes y
veas la diferencia, existen 3 macros para que puedas observar cómo
funciona sin control de errores (GeneraArchivosPrecios), ignorando el
error (GeneraArchivosPrecios_IgnoraError) y mostrando el mensaje
de error (GeneraArchivosPrecios_MuestraError).
Ejercicio
¿Recuerdas el caso del error que mencionamos al inicio y que nunca
resolvimos?: “Imagina que te han reportado que en ocasiones no calcula el
descuento de forma correcta y los clientes se molestan, entonces te han
pedido que revises el código y resuelvas el problema. Como regla del negocio
todos los clientes vip tiene 30% de descuento, los clientes silver tienen un
15% y los demás tienen un 5% de descuento.”. Descarga esta hoja de Excel,
revisa la macro depurarFuncionDescuentos, encuentra y resuelve el
problema aplicando lo que has aprendido en este capitulo
Mensajes y cuadros de diálogo
En este capítulo aprenderás algunas formas en las que puedes comunicarte
con las personas que usan tus macros, veremos como mostrar mensajes y
cómo capturar información para utilizar en tus programas.
msgbox1
Ejercicio
Ahora necesitas practicar como comunicarte con los usuarios de tus macros.
Crea una macro que solicite seleccionar una carpeta, si el usuario completa el
proceso y selecciona una carpeta, debes mostrar la selección en la barra de
estados. Si el usuario presiona el botón cancelar y no selecciona ninguna
carpeta, debes mostrar un mensaje de error con el icono vbCritical e indicar
que no selecciono alguna carpeta.
Crear formularios avanzados
En este capítulo aprenderás a crear formularios; los formularios son ventanas
en las que puedes utilizar cajas de textos, botones, listas desplegables, etc.,
con todo lo que necesitas para crear interfaces de usuario muy avanzadas.
Puedes descargar las macros que veremos en este capítulo haciendo clic
en este enlace: https://my.pcloud.com/publink/show?
code=XZgSS4kZT0a9HhsI6bQOIk1dQwKvFQCQtCpy
Introducción a userforms
Este tema es bastante extenso y lleno de nuevos conceptos, es por eso que iré
explicando todo mientras ponemos cada concepto en práctica. Vamos a
desarrollar un formulario para el ingreso de productos, el cual tendrá estas
características:
Tu primer formulario
Para crear un formulario, debes hacer clic derecho sobre tu proyecto y
seleccionar el menú Insertar > UserForm
Crear un formulario
Ahora ya tienes tu primer formulario, hay algunas cosas básicas que debes de
saber: En los extremos del formulario verás unos pequeños cuadros, si
acercas el puntero del mouse a ellos y haces clic, puedes arrastrarlos para
cambiar el tamaño del formulario.
Cambiar el nombre
Cambiar el titulo
Como has visto, es muy sencillo adaptar el formulario por medio de sus
propiedades, algunas propiedades son sencillas de comprender, por ejemplo,
utilizando Font puedes modificar el tipo de letra que se usa. Intenta modificar
algunas propiedades y observa cómo afectan al formulario, así podrás
familiarizarte mucho mejor con todas estas opciones.
Para agregar los botones, haces clic sobre el icono de “Botón de comando”
para seleccionarlo y luego haces clic sobre el formulario, después debes usar
esos pequeños cuadros blancos del botón de comando para cambiar su
tamaño. Repite este proceso para crear un segundo botón.
Agregar un botón
Evento Click
Vamos a hacer que el formulario se cierre cuando alguien hace clic sobre este
botón, para eso debes completar el código de esta forma:
1 Private Sub cmdCancelar_Click()
2 Me.Hide
3 End Sub
Ejecutar un formulario
Ahora verás el formulario en acción, para cerrarlo solo debes hacer clic sobre
el botón cancelar y si se cierra es por qué has hecho todo bien hasta ahora.
Para insertar una etiqueta haces clic sobre el icono con una letra A, en el
cuadro de herramientas, y luego haces clic en el formulario.
Agregar una etiqueta
Propiedades de la etiqueta
Nombre Texto
lblNombre Nombre
lblCantidad Cantidad
lblUnidad Unidad
Para agregar un cuadro de texto, haces clic sobre el icono que se muestra en
la siguiente imagen, y luego haces clic sobre el formulario.
Agregar un cuadro de texto
En este caso, solo debemos cambiar el nombre del control, vamos a colocarle
txtCodigo, txt es por Texto y Codigo es para recordarnos que contiene el
código del producto.
Ahora debes agregar dos cuadros de texto adicionales con estos nombres:
txtNombre y txtCantidad
Agregar un marco
Ahora vamos a agregar dos botones de radio sobre este marco para esto
seleccionamos el icono que vemos en la figura de abajo, y luego hacemos clic
dentro del marco que creamos anteriormente. Es importante que agreguemos
el botón de radio dentro del marco, ya que de esta forma VBA va a saber que
todos los botones de radio dentro del marco, pertenecen a un mismo grupo.
Ejemplo de botones de
radio
Para crear una lista de selección, haz clic en el icono Cuadro Combinado y
luego haces clic sobre el formulario
Si has seguido todos los pasos, ya tienes todos los controles que necesitamos
para hacer funcionar el formulario. Si aún no has ordenado todos los
controles en su lugar y con su tamaño respectivo, aquí está de nuevo la
imagen de cómo debe de lucir:
Formulario
Hasta ahora nuestro formulario se ve muy bien, pero no hace nada útil.
Vamos a comenzar usando el evento Activate del formulario para llenar los
valores de la lista de unidades, el evento activate se dispara cada vez que el
formulario se “Activa” o se torna visible, usualmente porque lo llamas por
primera vez o por que estabas en otra aplicación y regresas a tu macro.
Para ingresar al evento, primero haces doble clic sobre cualquier parte del
formulario para ingresar al código, luego verás dos listas en la parte superior,
en la primera seleccionas UserForm, que es el formulario, y en la segunda
lista seleccionas Activate, que es el evento Activate del formulario.
Seleccionar un evento
Al ejecutar el evento
Entonces abrimos el editor de VBA y creamos una macro con este código:
1 Sub MostrarFormularioProducto()
2 Dim f As New frmProducto
3 f.Show
4 End Sub
Para este momento el código anterior debe ser bastante familiar para ti, pero
hay algunas partes que aún debo explicar. Primero declaro una variable
llamada fila, para encontrar y guardar el número de la primera fila vacía que
encuentre, debido a que la primera fila contiene el encabezado, entonces
inicio buscando desde la fila número 2.
Luego comienzo a llenar cada celda de esa fila, con los valores que recibí
como parámetro. La columna F contiene la fecha de creación, esta fecha no
se recibe como parámetro, así que se toma la fecha del sistema, usando la
función Now().
Primero declaro dos variables para poder leer los valores de los botones de
radio y de las casillas de selección. En general para leer el valor de un
control, usamos la propiedad Value de cada control. Por ejemplo,
txtCodigo.Value me regresa el código del producto.
Para validar los datos, vamos a reemplazar el código del botón Aceptar, por
este otro código:
1 Dim EsCorrecto As Boolean
2 Dim Estado As String
3 Dim Descuentos As String
4
5 EsCorrecto = True
6
7 If txtCodigo.Value = "" Then
8 MsgBox "Debe ingresar un codigo"
9 EsCorrecto = False
10 End If
11
12 If txtNombre.Value = "" Then
13 MsgBox "Debe ingresar un nombre"
14 EsCorrecto = False
15 End If
16
17 If txtCantidad.Value = "" Then
18 MsgBox "Debe ingresar la cantidad"
19 EsCorrecto = False
20 Else
21 If Not IsNumeric(txtCantidad.Value) Then
22 MsgBox "La cantidad debe ser numerica"
23 EsCorrecto = False
24 End If
25 End If
26
27 If cbUnidad.Value = "" Then
28 MsgBox "Debe ingresar una unidad"
29 EsCorrecto = False
30 End If
31
32 If obActivo.Value Then
33 Estado = "Activo"
34 Else
35 Estado = "Inactivo"
36 End If
37
38 If ckDescuentos.Value Then
39 Descuentos = "Si"
40 Else
41 Descuentos = "No"
42 End If
43
44 If EsCorrecto Then
45 InsertarProducto txtCodigo.Value, txtNombre.Value, Estado,
txtCantidad.Value\
46 , cbUnidad.Value, Descuentos
47 Me.Hide
48 End If
Ejercicio
Imagina que alguien te pide que agregues el precio del producto, a esta hoja
de cálculo. Observas detenidamente todo el desarrollo y miras que para hacer
eso debes realizar estos cambios (y por supuestos los realizas)
Puedes descargar las macros que veremos en este capítulo haciendo clic
en este enlace: https://my.pcloud.com/publink/show?
code=XZ2SS4kZLjL4xaQXM6pPKajhuCLDCyK59tEX
Vamos a crear un archivo que nos servirá para hacer los demás ejemplos,
para hacerlo puedes utilizar una macro como esta:
1 Sub CrearArchivo()
2 Dim NombreArhivo As String
3 Dim Libro As Workbook
4
5 'Nombre del archivo
6 NombreArhivo = "demo.xlsx"
7
8 'Crear un nuevo libro, usando metodo add
9 Set Libro = Workbooks.Add()
10
11 'Guardar el libro con el nombre que digamos
12 'Si no definimos una ruta, se guarda
13 'en la carpeta en donde esta este archivo con macros
14 Libro.SaveAs NombreArhivo
15
16 End Sub
Como puedes ver ahora el nombre del archivo se encuentra en una variable, y
usamos la función de VBA Dir para probar el nombre del archivo, si el
resultado es diferente de una cadena vacía entonces abrimos el archivo, si no
mostramos un error.
Vamos a necesitar una forma sencilla de pedir al usuario que nos de la ruta
completa del archivo que necesita, en nuestro caso es mejor crear una
función, de esta forma podemos reutilizar esta funcionalidad cuando lo
necesitemos. Vamos a crear una función con este código:
1 Function AbrirArchivo()
2 Dim Arch As Variant
3 Arch = Application.GetOpenFilename(FileFilter:="Excel, *.xlsx",
Title:="Archivos\
4 de Excel...")
5
6 If Arch <> False Then
7 AbrirArchivo = Arch
8 End If
9 End Function
La parte del filtro antes de la , es solo una descripción, lo que hace que el
filtro funcione es lo que va después, en este caso *.txt
Vamos a utilizar el ciclo For Each, este ciclo va a recorrer todos los
elementos que se encuentren en un conjunto de datos. En el código siguiente,
el ciclo For Each va a recorrer el contenido en Application.Workbooks y
guardará temporalmente cada elemento en la variable libro para que
podamos evaluar su contenido.
1 Function LibroAbierto(NombreLibro) As Boolean
2 Dim libro As Workbook
3
4 'Remover la ruta y dejar solo el nombre del archivo
5 NombreLibro = Dir(NombreLibro)
6
7 'Inicializamos a falso mientras no comprobar que existe
8 LibroAbierto = False
9 For Each libro In Application.Workbooks
10 If libro.Name = NombreLibro Then
11 LibroAbierto = True
12 'Salimos, ya no hay necesidad de seguir buscando
13 Exit For
14 End If
15 Next
16 End Function
Esta es una función que permite cerrar el libro que le enviemos como
parámetro, antes de intentar cerrarlo vamos a utilizar la función que creamos
anteriormente para verificar que el libro está abierto, antes de intentar
cerrarlo.
1 Sub CerrarLibro(libro As String)
2 'Remover la ruta
3 libro = Dir(libro)
4
5 'Verificar si el libro esta abierto antes de intentar cerrarlo
6 If LibroAbierto(libro) Then
7 Workbooks(libro).Close
8 End If
9 End Sub
Borrar un archivo
Para borrar permanentemente un archivo podemos utilizar la función Kill de
VBA, esta función recibe como parámetro el nombre del archivo que
necesitamos eliminar, si no especificamos la ruta completa (carpetas),
entonces buscara el archivo en la carpeta en donde está el archivo con la
macro que estamos ejecutando.
1 Sub BorrarArchivo()
2
3 Kill ("demo.xlsx")
4 End Sub
Parámetro Descripción
Nombre completo del archivo incluyendo la
FileName ruta completa. Si no incluyes la ruta, Excel
toma como referencia la carpeta actual.
Es una constate para indicar el tipo de
archivo que necesitamos usar para grabar la
hoja de cálculo, por ejemplo, xlsm, xlsx, txt,
FileFormat
etc. Para una lista completa, puedes consultar
esta dirección https://docs.microsoft.com/en-
us/office/vba/api/excel.xlfileformat
Puedes enviar aquí una clave de hasta 15
Password caracteres para proteger el archivo con
contraseña.
Puedes indicar una clave para poder abrir el
archivo en modo de escritura, si la persona
WriteResPassword
no tiene la clave, puede optar por abrirlo en
modo de solo lectura.
Si enviamos True, se mostrará un mensaje de
ReadOnlyRecommended que el archivo debería abrirse en modo de
solo lectura.
Si enviamos True, Excel creara una copia de
CreateBackup
respaldo.
Existen otras opciones, y los más probable es que nunca las uses en toda tu
vida, sin embargo, si aún sientes curiosidad puedes consultarlas en este
enlace: https://docs.microsoft.com/en-
us/office/vba/api/excel.workbook.saveas
Ejercicio
Ahora que ya sabes trabajar con el objeto Workbook, intenta crear una macro
que guarde una copia de cada archivo abierto, pero protegido con una
contraseña para poder abrirlo en modo de escritura (usa la opción
WriteResPassword)
Uso de WorkSheets
En este capítulo vamos a aprender a trabajar con Hojas de Excel, como ya
sabemos cada Libro de Excel está compuesto de Hojas y ahora veremos
varios ejemplos como agregar, borrar, imprimir, proteger hojas, etc.
Puedes descargar las macros que veremos en este capítulo haciendo clic
en este enlace: https://my.pcloud.com/publink/show?
code=XZRSS4kZFWYWuP7SIh03y8uk8CKVCuy7zmby
Parámetro Descripción
Un objeto de tipo Sheet, que indica que deseas agregar la
Before
nueva hoja, antes de esta hoja.
Un objeto de tipo Sheet, que indica que deseas agregar la
After
nueva hoja, después de esta hoja.
El número de hojas que deseas agregar, si omites este
Count
parámetro, se agrega una hoja.
Indica el tipo de hoja que deseas agregar, por ejemplo,
una hoja normal, un gráfico, etc. Para ver una lista
Type completa, puedes consultar esta dirección:
https://docs.microsoft.com/en-
us/office/vba/api/excel.xlsheettype
Si no definimos ninguno de los parámetros Before o After, la nueva hoja se
agrega antes de la hoja activa. Veamos un ejemplo de cómo agregar una hoja
al final de todas:
1 Sub AgregarHoja()
2 ActiveWorkbook.Sheets.Add
After:=ActiveWorkbook.Worksheets(ActiveWorkbook.Worksh\
3 eets.Count)
4 End Sub
Para poder decirle a Excel que necesitamos agregar una hoja al final de todas,
debemos usar el parámetro After. Como mencione en la tabla anterior,
debemos incluir una referencia a la hoja en los parámetros After y Before.
Ahora, veamos un ejemplo más, imagina que además de definir una hoja,
necesitas realizar algún cambio sobre ella, como escribir algo sobre sus
celdas o cambiar su nombre. En ese caso necesitas capturar una referencia a
la nueva hoja y luego trabajar usando sus propiedades y métodos. Aquí hay
un ejemplo sencillo:
1 Sub AgregarHoja2()
2 'Definir una variable de tipo Worksheet
3 Dim hoja As Worksheet
4
5 'Capturar una referencia a la nueva hoja
6 Set hoja = ActiveWorkbook.Sheets.Add()
7
8 'Cambiar el nombre de la hoja
9 hoja.Name = "Hoja con nombre"
10 End Sub
Debes de tener en cuenta que cuando vas a capturar una referencia de la hoja
que agregas, debes llamar al método Add usando paréntesis al final, si no vas
a capturar una referencia, entonces no debes usar los paréntesis.
Cada hoja puede ser referenciada por su nombre o por su número de índice
(un número desde 1 hasta la cantidad de hojas que existan), a continuación,
hay un ejemplo para borrar la hoja llamada “Hoja con nombre” del libro
activo.
1 Sub BorrarHoja()
2 ActiveWorkbook.Sheets("Hoja con nombre").Delete
3 End Sub
Aquí hay un ejemplo para mover la hoja actual hasta la primera posición.
ActiveSheet hace referencia al objeto de la hoja activa, podemos usarla con
el método Move y para hacer referencia a la que ya es la primera hoja, vamos
a usar el índice 1 de la colección de objetos Sheets del libro activo.
1 Sub MoverHoja()
2 ActiveSheet.Move Before:=ActiveWorkbook.Sheets(1)
3 End Sub
Aquí hay un ejemplo para copiar una hoja y colocarla justo después de la
hoja que copiamos.
1 Sub CopiarHoja()
2 ActiveSheet.Copy After:=ActiveSheet
3 End Sub
Una vez oculta, puedes volver a mostrar la hoja haciendo clic derecho sobre
cualquiera de las hojas visibles y luego seleccionando del menú, la opción
Mostrar...
Luego verás una lista de las hojas ocultas, entonces solo seleccionas una de la
lista y presionas el botón Aceptar.
Si no quieres que las personas puedan hacer visibles las hojas ocultas muy
fácilmente, puedes elegir la opción Muy Oculta, así, la única forma de hacer
visible la hoja, será haciendo uso de VBA o el editor de VBA.
Puedes hacer esto con una macro como esta y utilizando la constante
predefinida xlSheetVeryHidden.
1 Sub OcultarHoja2()
2 ActiveSheet.Visible = xlSheetVeryHidden
3 End Sub
Parámetro Descripción
Es la clave que deseas colocar para la hoja,
si la omites las personas podrán
desproteger la hoja sin escribir ninguna
Password
clave. Es importante saber que, si pierdes
esta clave, no hay forma de poder
recuperarla.
True para proteger las formas. El valor
DrawingObjects
predeterminado es True.
True para proteger el contenido. En un
gráfico, protege todo el gráfico. En una
Contents hoja de cálculo, protege las celdas
bloqueadas. El valor predeterminado es
True.
True para proteger los escenarios. Este
Scenarios argumento solo es válido para las hojas de
cálculo. El valor predeterminado es True.
True para proteger la interfaz de usuario,
pero no las macros. Si omite este
UserInterfaceOnly
argumento, la protección se aplica tanto a
las macros como a la interfaz de usuario.
True permite al usuario dar formato a
cualquier celda de una hoja de cálculo
AllowFormattingCells
protegida. El valor predeterminado es
False.
True permite al usuario dar formato a
cualquier columna de una hoja de cálculo
AllowFormattingColumns
protegida. El valor predeterminado es
False.
True permite al usuario dar formato a
cualquier fila de una hoja de cálculo
AllowFormattingRows
protegida. El valor predeterminado es
False.
True permite al usuario insertar columnas
AllowInsertingColumns en la hoja de cálculo protegida. El valor
predeterminado es False.
True permite al usuario insertar filas en la
AllowInsertingRows hoja de cálculo protegida. El valor
predeterminado es False.
True permite al usuario insertar
hipervínculos en la hoja de cálculo
AllowInsertingHyperlinks
protegida. El valor predeterminado es
False.
True permite al usuario eliminar columnas
en la hoja de cálculo protegida, donde todas
AllowDeletingColumns las celdas de la columna que se va a
eliminar se desbloquearán. El valor
predeterminado es False.
True permite al usuario eliminar filas en la
AllowDeletingRows hoja de cálculo protegida, donde todas las
celdas de la fila que se va a eliminar se
desbloquearán. El valor predeterminado es
False.
True permite al usuario ordenar la hoja de
cálculo protegida. Se deben desbloquear o
AllowSorting desproteger todas las celdas del rango de
ordenación. El valor predeterminado es
False.
True permite al usuario establecer filtros
en la hoja de cálculo protegida. Los
usuarios pueden cambiar los criterios del
AllowFiltering filtro, pero no puede habilitar o deshabilitar
un filtro automático. Los usuarios pueden
establecer filtros en un filtro automático
existente. El valor predeterminado es False.
True permite al usuario usar informes de
tabla dinámica en la hoja de cálculo
AllowUsingPivotTables
protegida. El valor predeterminado es
False.
Existe una gran cantidad de parámetros, pero para la mayoría de los casos
posiblemente solo vas a necesitar el parámetro Password y dejar todas las
demás opciones con sus valores predeterminados. Aquí hay una macro como
ejemplo:
1 Sub ProtegerHoja()
2 ActiveSheet.Protect Password:="123"
3 End Sub
Parámetro Descripción
Número de la página en la que comienza la
From impresión. Si no se especifica este argumento, la
impresión empieza por el principio.
Número de la última página que se va a imprimir.
To Si no se especifica este argumento, la impresión
finaliza en la última página.
Número de copias que se imprimirán. Si no se
Copies especifica este argumento, se imprime una sola
copia.
True para que Microsoft Excel invoque la vista
Preview preliminar antes de imprimir el objeto. False (u
omitido) para imprimir el objeto inmediatamente.
ActivePrinter Establece el nombre de la impresora activa.
True para imprimir a un archivo. Si no se
PrintToFile especifica PrToFileName , Excel solicita al usuario
que escriba el nombre del archivo de salida.
Collate True para intercalar varias copias.
Si PrintToFile se establece en true, este argumento
PrToFileName especifica el nombre del archivo en el que desea
imprimir.
True para omitir las áreas de impresión e imprimir
IgnorePrintAreas
todo el objeto.
Aquí hay un ejemplo de cómo imprimir la hoja actual mostrando la vista
previa:
1 Sub ImprimirHoja()
2 ActiveSheet.PrintOut Preview:=True
3 End Sub
Para poder ejecutar esta macro sin problemas, la hoja activa debe de tener
algún contenido. Si la hoja está vacía, entonces Excel simplemente no hace
nada.
Ejercicio
Para practicar un poco lo que has visto en este capítulo, intenta crear un
macro que recorra todas las hojas del libro activo (ActiveWorkbook) y oculte
todas las hojas excepto la primera.
Trabajando con Rangos
Ahora vamos a trabajar con rangos, un rango es un conjunto de celdas que
bien pueden ser columnas, filas, cualquier grupo de celdas o incluso una sola
celda.
Puedes descargar las macros que veremos en este capítulo haciendo clic
en este enlace: https://my.pcloud.com/publink/show?
code=XZJSS4kZJ85FEedg0qF8QXXloPVSkmO1I1ay
Usando Rangos
Para trabajar con rangos podemos usar el objeto Range, recordemos que este
es un conjunto de celdas, entonces al usarlo, también tenemos que decir con
cual celda vamos a trabajar, por ejemplo Range("A1:A3"). Select
selecciona las celdas A1 a la A3.
rango-inicial
Ahora veamos una macro que recorre todas las celdas seleccionadas y
muestra su contenido en un mensaje usando la función MsgBox
1 Sub RecorrerRango()
2 Dim celda As Range
3 For Each celda In Selection
4 MsgBox celda.FormulaR1C1
5 Next
6
7 End Sub
Como puedes ver en el código anterior usamos la instrucción Let para asignar
el valor a las variables por que se declararon como tipo Range el cual es un
objeto. Cuando trabajes con tipos de datos de objetos debes usar siempre la
palabra Let al asignarles un valor.
Otra parte que puede ser confusa, es la forma en que le asignamos un color,
en lugar de un código como Color = Amarillo, usamos Color = RGB(255,
255, 0). RGB es una función de VBA que permite definir un color como las
mezclas de rojo, verde y azul, la intensidad de cada color se representa como
un numero de 0 (ausencia del color) a 255 (color puro). Pero no necesitas
dominar los colores en RGB, puedes usar páginas como
https://www.w3schools.com/colors/colors_picker.asp en donde puedes
generar códigos RGB de forma gráfica.
Colores RGB
Uso de Offset
Al utilizar el método offset podemos definir un rango basado en el
desplazamiento de otro rango. Aunque offset puede funcionar con rangos,
es más usada cuando trabajamos con una sola celda, por ejemplo, si ya tienes
la referencia de una celda y deseas ingresar algún dato en la celda que esta a
la derecha, entonces solo te desplazas una columna a la derecha. Esto puede
parecer un poco confuso al inicio así que vamos a ver algunos ejemplos y con
eso lo comprenderás sin problemas.
Parámetro Descripción
Número de filas que debe desplazarse, un número
positivo indica que debe desplazarse hacia abajo, y un
RowOffset
número negativo indica que debe desplazarse hacia
arriba.
Número de columnas que debe desplazarse, un número
positivo indica que debe desplazarse hacia la derecha, y
ColumnOffset
un número negativo indica que debe desplazarse hacia
la izquierda.
Ahora veamos un ejemplo, imagina que vas a escribir un valor monetario en
la celda activa (ActiveCell) y en la celda que está a su derecha, debes
escribir la moneda. El problema de hacer esto, es que no sabes cúal es la
celda activa, podrías usar algo como Range("B2"), pero no puedes decir que
vas a usar la celda B2 porque no sabes cúal es la celda activa. Existen formas
de conseguir cual es la dirección de la celda activa, pero en casos como este,
lo mejor es hacer referencia a una celda basada en otra celda. Veamos la
solución más sencilla para este problema:
1 Sub EjemploOffset()
2 'Colocar un valor en la celda activa
3 ActiveCell.Formula2R1C1 = 25.2
4
5 'Usamos offset para movernos cero filas
6 'y 1 columna a la derecha, luego escribimos un valor
7 ActiveCell.Offset(0, 1).Formula2R1C1 = "$"
8 End Sub
Para tener una mejor idea de cómo usar offset, aquí hay grafico de cómo
usarlo para seleccionar algunas celdas que están alrededor de una celda
Ejemplos de Offset
Ahora veamos cómo se comporta Offset al usarse con rangos, imagina que
tienes seleccionadas las celdas A1:A3, que piensas que pasaría si ejecutas un
código como este:
1 Sub EjemploOffsetRangos()
2 Dim rango As Range
3
4 Set rango = Range("A1:A3")
5
6 rango.Offset(0, 1).Select
7 End Sub
Borrar rangos
Los rangos poseen un método llamado Delete, puedes usarlo para borrar un
rango completo de celdas. De la misma forma en que sucede en Excel,
cuando borras una o más celdas, Excel reorganiza las demás celdas para
cubrir el espacio, por ejemplo, si borras la columna B, entonces mueve todas
las columnas a la izquierda, y los datos de la columna C, pasan a la columna
B.
Ocultar rangos
Ahora veremos cómo ocultar rangos. Una tarea habitual en Excel es ocultar
filas o columnas que no usas o que tienen datos que no deseas que este
visibles porque no son importantes. Para ocultar o mostrar una fila, podemos
cambiar la propiedad Hidden a true para ocultar y a false para mostrar.
Ahora voy a introducir el objeto Rows, este objeto puede hacer referencia a
cualquier fila de la hoja de cálculo, por medio de su índice. Por ejemplo, el
siguiente código oculta la fila 2, si necesitas volver a hacerla visible, recuerda
que solo debes cambiar la propiedad Hidden de true a false.
1 Sub OcultarRango()
2 Rows(2).Hidden = True
3 End Sub
Por ejemplo, veamos este rango que inicia en la celda B1 y luego se extiende
4 filas hacia abajo y dos columnas a la derecha, hasta llegar a la celda C4.
Como puedes ver, simplemente hemos definido nuevamente los límites del
rango, pero también puedes lograr un código más genérico, como por
ejemplo incrementar el rango en una fila más o una columna más. Para esto
podemos usar las propiedades Rows.Count y Rows.Count del rango para
conocer cuantas filas y columnas utiliza el rango y luego definir un
incremento basado en esos números, por ejemplo, para incrementar el rango
en 1 fila, podes usar este código:
1 Sub IncremetarFilaRango()
2 Dim rango As Range
3
4 Set rango = Range("B1:C4")
5
6 Set rango = rango.Resize(rango.Rows.Count + 1, rango.Columns.Count)
7
8 rango.Select
9
10 End Sub
Ejercicio
Ahora que conoces los rangos y como realizar operaciones con ellos, crea una
macro llamada Aplica20Descuento y que cambie el contenido de todas las
celdas seccionadas al multiplicar su valor por 0.8, los valores de las celdas
que seleccione la persona que llama la macro, deben ser numéricos. Puedes
validar si una celda tiene un valor numérico , usando con un código como
este:
1 If IsNumeric(celda.Formula2R1C1) Then
2 'Es un numero
3 End If