Visual Basic For Applications
Visual Basic For Applications
Visual Basic
Septiembre 2023
3
¿Qué es VBA?
4
¿Cómo acceder a VBA desde Excel?
1. Mostrar la pestaña de ‘Programador’.
No se exhibe por defecto, se puede añadir
a la cinta de opciones.
5
¿Cómo acceder a VBA desde Excel?
2. Programador => Visual Basic o Alt + F11
6
Ventanas de VBA
Normalmente, cuando abrimos el entorno de programación de VBA, nos
encontramos una interfaz como esta de abajo (a veces, necesitaremos incluir o
excluir algunas ventanas).
Project
Coding window
Explorer
7
Configuración de ventanas
Para añadir ventanas: Ver => (Nombre de la ventana)
8
Descripción de las ventanas
Explorador de proyectos
• Nos muestra los libros abiertos,
incluyendo el libro actual, todas sus Código
hojas y objetos creados (como
formularios). • En esta ventana escribiremos
funciones y subrutinas.
• Esta ventana nos permite crear y
abrir módulos de código donde
éstos serán escritos.
Ventana Inmediato
• Esta ventana nos permite probar y Ventana Inspección
ejecutar pequeños trozos de
código. • Esta ventana nos permite ver el
valor de ciertas variables o
• Nos deja ejecutar cualquier expresiones según se ejecuta el
declaración de VBA manualmente código.
mientras el programa se está
ejecutando y depurar el código.
9
Descripción de las ventanas
Ventana propiedades
• Nos enseña las propiedades del
objeto que hayamos seleccionado
(libro, pestaña, módulo,…)
• Además, nos da la posibilidad de
modificar alguna propiedad sin
necesidad de código
Locales
• Esta ventana muestra los valores
auxiliares del código mientras está
ejecutando
• Útil para ejecutar el código línea a
línea
10
2 Acceso a los objetos de Excel
11
Usar el comando “Print” en la ventana de Inmediato para probar
.Add: Añade una pestaña (o varias con el input Count) antes (Before) o
después (After) de una de las pestañas del libro.
20
• Fundamentos de programación
Variables
Especificaremos el tipo de la variable con la palabra clave ‘As’, normalmente al
principio del proceso. Los principales tipos de datos son los siguientes:
21
• Fundamentos de programación
Variable Locales y Globales
Variables locales se declaran en la rutina y solo pueden ser llamadas desde la
rutina y durante su ejecución. Por ejemplo:
Sub Example1()
Dim LocalVariable as Integer
....
End Sub
22
• Fundamentos de programación
Funciones definidas por el usuario y Subrutinas
En Excel Visual Basic, el conjunto de comandos para realizar una particular tarea o
acción se establece dentro de un procedimiento, el cual puede ser una Función o
una Subrutina.
FUNCIONES SUBRUTINAS
Llevan a cabo cálculos y Realizan una acción con
devuelven un valor único o Excel. Normalmente, no
una matriz. tienen parámetros de
entrada o de salida.
En general, si deseas realizar una tarea que devuelva un resultado (e.g. sumar un
grupo de números), usarás una Función, pero si solamente necesitas que se
lleven a cabo un conjunto de acciones (e.g. dar formato a un conjunto de
celdas), deberías decantarte por una Subrutina.
23
• Fundamentos de programación
Diferencias entre Funciones y Subrutinas
Función Subrutina
24
• Fundamentos de programación
Notas importantes
Es importante destacar que:
26
• Fundamentos de programación
Programación estructurada
El código se escribe una vez y se lee muchas veces en el futuro. Por este motivo, se
debería organizar de un modo claro y entendible. Algunas recomendaciones:
- Usar comentarios para explicar las líneas de código que no son fácilmente
comprensibles.
Comentarios - VBA considera cualquier texto seguido de un apóstrofe (') como un
comentario y no será ejecutado.
27
• Fundamentos de programación
Errores VBA
Si durante la ejecución del código el procesador detecta un error, por ejemplo, de
sintaxis, el código dejará de funcionar y se mostrará un mensaje. En este caso, dará
la opción de depurar el error. Se resaltará en amarillo la línea de código que genera
el error.
Cuando esto ocurra, aunque el error sea corregido, la línea seguirá resaltada (esto
indica que el código está en modo de parada) y no podremos seguir ejecutando el
código. Necesitamos pulsar RESTABLECER para detener este modo e intentar
ejecutar el código otra vez.
28
4 ¿Cómo programar?
29
• ¿Cómo programar?
Distintas posibilidades…
Excel Visual Basic ofrece dos opciones principales para programar:
30
• ¿Cómo programar?
Generación Automática de Macros
Este método es especialmente recomendable cuando necesitemos trabajar con
objetos de Excel tales como libros, hojas, rangos de celdas, celdas, gráficos, etc…
o si vamos a usar algún complemento o herramienta de Excel, como filtros,
importación de datos, solver, etc. Para generar una macro automática, la
grabaremos:
Asignar nombre
Ir al menú Click en ‘Grabar
a la macro y
‘Desarrollador’ Macro’
otras opciones
31
• ¿Cómo programar?
Generación Automática de Macros
32
• ¿Cómo programar?
Ejecutar una macro automática desde Excel
Una macro puede ser ejecutada desde Excel en Alt+F8 o usando el botón Macro
en el menu ‘Desarrollador’.
33
• ¿Cómo programar?
Generación Automática de Macros
Las macros también pueden ser asignadas a botones u objetos de Excel (formas,
imágenes, etc.) y ejecutadas con un click de ratón o un cambio en su forma. En el
caso de los botones:
Desarrollador => Insertar => Controles de formulario
Asignando la macro… Click derecho en el objeto => ‘Asignar macro’ => Seleccionar la macro
34
• ¿Cómo programar?
Ejercicio: Calcular la TIR de un bono a 10 años
En el libro ‘E1_TIR_Bono_Macro’ se encuentra una valoración de un bono a 10
años. La idea del ejercicio es construir una subrutina (grabando una macro) que use
la opción ‘Buscar Objetivo’ (Datos => Análisis de hipótesis => Buscar objetivo) de
Excel para calcular la Tasa Interna de Retorno (TIR). Esta macro debe ser asignada
a una figura y probada cambiando el cupón del bono.
Recuerde…
La Tasa Interna de Retorno (TIR) es una tasa de descuento que hace el Valor Actual Neto de
los flujos de caja igual a cero. Tal que la TIR es:
𝑛𝑛
𝐹𝐹𝐹𝐹𝑖𝑖
0=�
(1 + 𝑇𝑇𝑇𝑇𝑇𝑇)𝑖𝑖
𝑖𝑖=0
• 𝐹𝐹𝐹𝐹𝑖𝑖 es el flujo de caja del periodo 𝑖𝑖.
• 𝐹𝐹𝐹𝐹0 es la inversión inicial (precio del bono en nuestro caso).
Debido a la naturaleza de esta fórmula, la TIR no puede ser calculada analíticamente y debe
ser calculada mediante prueba y error o usando un software programado para ello.
35
• ¿Cómo programar?
Programación pura en Visual Basic
Lo primero de todo para crear un código en VBA es crear un modulo si todavía no
existe.
36
• ¿Cómo programar?
Programación pura en Visual Basic: Funciones
VBA nos ofrece numerosas funciones ya implementadas, que el usuario
puede ejecutar, siempre respetando el formato de llamada. Estas
funciones permiten desarrollar cualquier procedimiento en consonancia
con las necesidades del usuario. (Ver funciones VBA más comunes en el
Apéndice I)
Sin embargo, el usuario puede construir sus propias funciones VBA,
llamándolas desde Excel u otro procedimientos de Función o Subrutina.
Se debería de respetar la siguiente estructura:
Código Descripción ¿Obligatorio?
Function Es el comienzo de la función. El NombreFuncion es elegido por el Sí
NombreFuncion(Argumentos) usuario. Los Argumentos en paréntesis son las variables que
necesitamos introducir. Si los paréntesis están vacíos entonces no hay
necesidad de introducir ningún parámetro.
Dim Variables Declaración interna de variables. Se recomienda declarar todas las No
variables al comienzo.
(CODIGO)
NombreFuncion = Indica el resultado que queremos devolver. Sí
End Function Indica el fin de la función. Sí
37
• ¿Cómo programar?
Ejercicio: Creando nuestra primera función
En la hoja ‘Deposito’ del libro ‘E2_IntroduccionVBA’ encontrareis las características
de un depósito a plazo (nominal, tipo de interés y plazo). Crear una función en VBA
para calcular el valor del depósito a plazo a su vencimiento (Valor Futuro):
38
• ¿Cómo programar?
Programación pura en Visual Basic: Subrutina
Subrutina es un procedimientos que ejecuta operaciones internas pero no devuelve
ningún resultado. Se puede trabajar directamente con las celdas de Excel (leyendo
o escribiendo datos), haremos uso de la siguiente estructura:
39
• ¿Cómo programar?
Ejercicio: Creando nuestra primera subrutina
En la hoja ‘Deposito’ del libro ‘E2_IntroduccionVBA’ encontrareis las características
de un depósito a plazo (nominal, tipo de interés y plazo). Esta vez crearemos dos
subrutinas para calcular el valor del depósito a plazo a su vencimiento (Valor
Futuro):
40
• ¿Cómo programar?
Funciones a la hoja de trabajar
Recordar que …
VBA también nos permite usar Funciones de Excel. Para hacer esto, debemos
escribir, ‘Application.WorksheetFunction.’ y el nombre de la función (siempre en
inglés). Acto seguido, debemos introducir los argumentos de la función separados
por comas.
Application.WorksheetFunction.
41
5 Condicionales en VBA
42
• Declaraciones condicionales en VBA
Condicional en VBA: If … Then
If: Ejecuta condicionalmente un grupo de instrucciones, dependiendo del valor de
una expresión. Sintaxis:
If <expresion> Then
[instrucciones]
[Else]
[Instrucciones_else]
End If
Function MyMax(inp1,inp2) If
1 3
1 If inp1 >= inp2 Then
2 MyMax = inp1
2 4
3 Else
4 MyMax = inp2
5 End If
End Function 5
43
• Declaraciones condicionales en VBA
Condicional en VBA: If … Then
Alternativas a la declaración “If”:
Solo se quiere ejecutar un bloque, si se satisface una condición:
If <expresion> Then
[instrucciones]
End If
Lógicos
45
• Declaraciones condicionales en VBA
Declaraciones condicionales en VBA: Select Case
Select Case: Ejecuta una de varias instrucciones grupales, dependiendo del valor
de una expresión. Sintaxis:
Select Case test_expression
[Case list_expression-n
[instructions-n]]
[Case Else
[instructions-else]]
End Select
46
6 Bucles VBA
47
• Bucles VBA
Bucles: For … Next
For: Repite un grupo de instrucciones un número específico de veces.
Sintaxis:
For <iterator = First To Last>
[instructions]
Next iterator
Sub Returns_Sub()
1 For i = 1 To 10
2 Aux = (Range("A1").Offset(i,0).Value / Range("A1").Offset(0,0).Value) - 1
3 Range("A1").Offset(i,1) = Aux
4 Next i
End Function
Los bluces pueden ser decrecientes:
For <iterator = Last To First Step -1>
[instructions]
Next iterator
48
• Bucles VBA
Bucles : Do While … Loop
Do While: Repite un bloque de instrucciones mientras se cumple una
condición. Sintaxis:
Do While <expression>
[instructions] El iterador debe ser
Loop inicializado. Cuidado con
los bluces infinitos.
Sub LastCell()
1 i=1
2 Do While Range("A1").offset(i,0) <> ""
3 i=i+1
4 Loop
5 Range("A1").Offset(i,0) = "LastCell"
End Function
49
• Bucles VBA
Bucles : Do Until … Loop
Do Until: Repite un bloque de instrucciones hasta que se cumple una
condición. Sintaxis:
Do Until <expression>
[instructions] El iterador debe ser
Loop inicializado. Cuidado con
los bluces infinitos.
Sub LastCell()
1 i=1
2 Do Until Range("A1").offset(i,0) = ""
3 i=i+1
4 Loop
5 Range("A1").Offset(i,0) = "LastCell" Si queremos el mismo
resultado que con “While”,
End Function
es necesario cambiar el
operador
50
• Bucles VBA
Ejercicio: Uso de Condicionales y Bucles
En la hoja ‘SumarSi’ del libro ‘E2_IntroduccionVBA’ encontrareis una base de datos
con activos y nominales. El objetivo es crear una Función para sumar el nominal
total de un activo:
Function MiSumaSi(activo)
51
• Bucles VBA
Ejercicio: Interpolando
En la hoja ‘Interpolacion’ del libro ‘E3_Interpolacion’ encontrareis un conjunto de
datos con fechas y tipos. El objetivo es crear una Función para interpolar un tipo
dada una fecha:
2. Usar un bucle para hallar las fechas anterior y posterior de una fecha dada y
evaluar la fórmula de interpolación
𝑇𝑇𝑇𝑇𝑇𝑇𝑜𝑜𝐷𝐷𝐷𝐷𝐷𝐷𝐷𝐷𝐷𝐷𝐷𝐷𝐷 − 𝑇𝑇𝑇𝑇𝑇𝑇𝑜𝑜𝐴𝐴𝐴𝐴𝐴𝐴𝐴𝐴𝐴𝐴
𝑇𝑇𝑇𝑇𝑇𝑇𝑇𝑇 = 𝑇𝑇𝑇𝑇𝑇𝑇𝑜𝑜𝐴𝐴𝐴𝐴𝐴𝐴𝐴𝐴𝐴𝐴 + 𝐹𝐹𝐹𝐹𝐹𝐹𝐹𝐹𝐹 − 𝐹𝐹𝐹𝐹𝐹𝐹𝐹𝑎𝑎𝐴𝐴𝐴𝐴𝐴𝐴𝐴𝐴𝐴𝐴
𝐹𝐹𝐹𝐹𝐹𝐹𝐹𝑎𝑎𝐴𝐴𝐴𝐴𝐴𝐴𝐴𝐴𝐴𝐴 − 𝐹𝐹𝐹𝐹𝐹𝐹𝐹𝑎𝑎𝐷𝐷𝐷𝐷𝐷𝐷𝐷𝐷𝐷𝐷𝐷𝐷𝐷
Consejo
Para saber cuantas filas tiene un rango:
MiRango.Rows.Count
52
7 Generación de complementos .XLAM
53
• Generación de complementos .XLAM
54
• Generación de complementos
Protección de un complemento XLA
.XLAM
55
• Generación de complementos .XLAM
56
8 Interacción con el usuario
57
• Interacción con el usuario
Interacción con el usuario
58
• Interacción con el usuario
Msgbox
Nos mostrará en la pantalla un mensaje que se introduce como un
argumento.
El usuario puede poner un título al msgbox rellenando el argumento
Title.
Ejemplo
Sub Ex_Msgbox1()
Msgbox “This is an example”, [Title]:=“EXAMPLE”
End Sub
Resultado
59
• Interacción con el usuario
Msgbox
Para interactuar con Excel, son necesarios más argumentos.
• vbOKCancel
• vbOKOnly
• vbYesNo
• vbYesNoCancel
60
• Interacción con el usuario
Msgbox (Código) Opción escogida
Sub Ex_Msgbox2()
End Sub
61
• Interacción con el usuario
Msgbox (Diálogo)
vbOKCancel vbOKOnly
vbYesNo vbYesNoCancel
Mismo output
62
• Interacción con el usuario
Inputbox
Nos mostrará en la pantalla un mensaje que se introduce como un
argumento.
Esto pregunta al usuario por el input, que será asignado a una nueva
variable en código VBA.
Ejemplo
Sub Ex_Inputbox()
variable = InputBox("This is an example", "EXAMPLE")
Range("A1") = variable
End Sub
Resultado
63
9 Eventos asociados a hojas y libro de
Excel
64
Eventos asociados a Hojas
• Cualquier hoja de un libro Excel puede tener asociada la ejecución de código Visual
Basic ante ciertas acciones que ocurran en esa hoja. En el editor de Visual Basic, en
cada Hoja podrán crearse subrutinas que se ajusten a ciertos nombres. Estos
procedimientos pueden ser insertados directamente de los dos desplegables
disponibles.
65
Eventos asociados a Libros
• Cada libro puede tener asociada la ejecución de subrutinas ante ciertas acciones. En
el editor de Visual Basic, en el elemento ThisWorkbook del libro en cuestión se crearán
dichas subrutinas (deberán ajustarse a ciertos nombres). Estos procedimientos
pueden ser insertados directamente de los dos desplegables desponibles.
66
10 Programación de tareas
67
Tareas programadas (I)
• Podemos programar la ejecución de una macro (procedimiento tipo Sub) a una hora
determinada. Dicha macro puede realizar cualquier tipo de actividad como llamadas
a otras macros (útil para archivar últimas cotizaciones diarias).
• Esta tarea será configurada mediante el método Ontime del objeto Application.
• Sub CierreDia()
• ‘Esta macro debe contener todo el código a ejecutar a la hora prevista de cierre.
• ‘Será ejecutada automáticamente a la hora indicada en el método Application.Ontime que
se
• ‘ activa en la macro ActivarReloj puesta más abajo.
• MsgBox “Tarea Activada a las 18:00:00”
• ‘Introducir aquí todas las sentencias y rutinas a ejecutar.
• End Sub
• Sub ActivarReloj()
• ‘Esta macro debe ejecutarse una vez (por ejemplo al abrir el libro) para que se programe
• Application.OnTime TimeValue(“18:00:00”), “CierreDia”
• ‘ El parámetro segundo es la macro que se ejecuta a las 18.00. OnTime admite más
opciones.
• ‘ Si pones el cursor sobre la palabra y pulsas F1 veras su ayuda y sus posibilidades.
• End Sub 68
Tareas programadas (II)
• Si deseamos ejecutar alguna tarea automáticamente al abrir un libro, podemos utilizar la macro Auto_Open.
Si queremos ejecutar una tarea con un cierto retardo tras la apertura de un libro, podemos hacer uso del
método Ontime del objeto application. Podremos programar la tarea a partir de la hora actual, que
obtendremos llamando a la función Time. La hora devuelta es una cifra que varía entre 0 y 1 (1 para las
23:59:59).
• Sub Apertura()
• ‘Esta macro debe contener todo el código a ejecutar a la hora prevista.
• ‘Será ejecutada automáticamente a la hora indicada en el método Application.Ontime que se
• ‘ activa en la macro Auto_Open puesta más abajo.
• MsgBox “Tarea Activada a la hora actual + 5 minutos”
• ‘Introducir aquí todas las sentencias y rutinas a ejecutar.
• End Sub
• Sub Auto_Open()
• ‘Esta macro debe ejecutarse una vez (por ejemplo al abrir el libro) para que se programe
• Dim t, minuto
• Minuto = 1/ (24 * 60)
• T = Time
• Application.OnTime (t + 5 * minuto), “Apertura”
• End Sub
69
Tareas programadas (III)
• También se puede usar:
70
11 Tratamiento de errores
71
Tratamiento de errores
• En ocasiones, pueden aparecer errores en tiempo de ejecución, (sobre objetos de
Excel), que no permiten continuar con la ejecución del código. Como ejemplo
podremos provocar un error de división por cero:
• Sub Errores()
• ‘Sin control de errores. Provoca un error de división por cero, aparece un
mensaje
• ‘del sistema que no nos permite continuar la ejecución del código
• Dim x, a
• a=5
• x=a/0 ‘ <= error de división por cero
• x= x + 33
• Cells(1,1) = x
• End Sub
Cuadro de diálogo del error
Tanto si pulsamos Finalizar como Depurar,
no se podrá continuar la ejecución
mientras exista el error
72
Tratamiento de errores
• Dentro de una macro, puede activarse el ignorar los errores del sistema, hasta el
final de dicha macro. En esta modalidad, si en una línea se produce un error del
sistema, se ignora dicha línea y se continúa la ejecución en la línea siguiente.
• Sub IgnorarErrores()
• ‘Macro que ignora los errores del sistema.
• ‘Si en una línea se produce un error, se ignora esa línea se salta a ejecutar la
• ‘siguiente línea. Este ignorado es efectivo hasta el final de la macro
• Dim x, a
• On Error Resume Next ‘ a partir de aquí se ignoran los errores que se
produzcan
• a=5
• x=a/0 ‘ <= error de división por cero. Está línea no será ejecutada
• x= x + 33
• Cells(1,1) = x
• End Sub
73
Tratamiento de errores
• Podremos provocar que si se produce un error del sistema en una línea, se ignora
dicha línea y se salta a otra línea para hacer un tratamiento específico del
error. Podremos saber las características del error mediante el objeto Err (por
ejemplo, el número de error está en Err.Number)
• Sub ControlarErrores()
• Dim x, a, c
• On Error GoTo ControlErr ‘activa control de errores (válido hasta el final del sub)
• a=5
• x=a/0 ‘ <= error de división por cero. Está línea no será ejecutada y salta etiqueta
ControlErr
• x= x + 33
• Cells(1,1) = x
• Exit Sub ‘debemos evitar que entre en el tratamiento de los errores
• End Sub
74
Tratamiento de errores
• Podremos provocar que si se produce un error del sistema en una línea, se ignora
dicha línea y se salta a otra línea para hacer un tratamiento específico del
error. Podremos saber las características del error mediante el objeto Err (por
ejemplo, el número de error está en Err.Number)
• Sub ControlarErrores()
• Dim x, a, c
• On Error GoTo ControlErr ‘activa control de errores (valido hasta el final del sub)
• a=5
• x=a/0 ‘ <= error de división por cero. Está línea no será ejecutada y salta etiqueta
ControlErr
• x= x + 33
• Cells(1,1) = x
• Exit Sub ‘debemos evitar que entre en el tratamiento de los errores
• ControlErr :
• c = MsgBox(“Error num:”& Err.Number & “. Continuar?”, vbYesNo)
• If c = vbYes Then
• ‘podría hacer cualquier tipo de manipulación
• Resume Next ‘ continua en la siguiente a la línea de error
• End if
• End Sub
• Nota: si se desea desactivar control de errores: On Error GoTo 0
75
Apéndice I:
Librería VBA de Funciones
• Librería VBA de Funciones
Funciones VBA más usadas
VBA tiene una librería de funciones a nuestra disposición. Aquí, mostramos algunas de las
más importantes, especialmente para finanzas.
Función Descripción
Abs (number) Nos devuelve el valor absoluto de un número
Int (number) Nos devuelve la parte entera de un número
Date Nos devuelve la fecha actual del sistema
Now Nos devuelve la fecha y hora actuales del sistema
Time Nos devuelve la hora actual del sistema
DateSerial Nos devuelve una fecha (número) dados los valores de un año, mes y día
(year,month,day)
DateValue (“22/09/2007”) Nos devuelve el valor en serie de una fecha
Day (date) Nos devuelve el día del valor de una fecha
Month (date) Nos devuelve el mes del valor de una fecha
Year (date) Nos devuelve el año del valor de una fecha
Weekday (date) Nos devuelve el día de la semana del valor de una fecha, considerando el domingo
como día 1
• Librería VBA de Funciones
Funciones VBA más usadas
Función Descripción
Dateadd (interval, number, date) Añade un número de intervalos de tiempo a una fecha proporcionada y
devuelve la fecha resultante. El intervalo podría ser: “yyyy” para años, “q”
para trimestres, “m” para meses, “ww” para semanas y “d” para días.
Ejemplo:
Datediff (interval, date1, date2) Nos devuelve la diferencia entre dos fechas, basado en un intervalo
específico. El intervalo podría ser: “yyyy” para años, “q” para trimestres,
“m” para meses, “ww” para semanas y “d” para días.
Ejemplo:
Time = #20:12:15#
TimeFormat = Format(Time, "hh:mm:ss AMPM") => “08:12:15 PM"