Você está na página 1de 81

INTRODUCCIÓN AL

VISUAL BASIC Y
MODELOS DE CARTERA

Tema 1. Introducción

Máster en Ciencias Actuariales y


Financieras

Antonio Díaz Pérez


Universidad de Castilla-La Mancha
antonio.diaz@uclm.es
 

Tema 1. INTRODUCCIÓN

1.1 Introducción a Excel


1.2 Funciones financieras básicas
1.3 Introducción al Visual Basic para Aplicaciones (VBA)
1.4 Aplicaciones financieras

1.1 Introducción a Excel

En este primer apartado revisamos ciertas funciones y procedimientos de


Excel que se utilizan en el resto de la asignatura. Se trata de funciones
estadísticas, matemáticas y de búsqueda, así como funciones condicionales que
volveremos a analizar en Visual Basic. El usuario avanzado de Excel puede
utilizar este apartado para refrescar conceptos que ya conoce.
Excel proporciona muchas fórmulas predefinidas o integradas,
denominadas funciones. Estas funciones presentan la siguiente sintaxis:
NOMBRE(argumento1;argumento2;…)
Cada función tiene asignado un número determinado de argumentos
según su finalidad. Cada argumento puede ser un valor, una referencia a un
rango de celdas que contengan los datos, o incluso otra/s función/es.
La función más común es SUMA: calcula la suma de los valores que
pueden aparecen como argumentos o que se encuentran situados en un rango
de celdas. Al tratarse de una función utilizada con mucha
frecuencia tiene su propio botón Autosuma en el grupo Modificar
de la ficha Inicio.
Ejemplo: “=SUMA(2;5;9;6)” equivale a “=2+5+9+6” y devuelve el valor “25”.
Ejemplo: “=SUMA(B2:C3)” equivale a sumar cada uno de los valores que
aparecen en las celdas del rango B2:C3, es decir en las celdas B2, B3, C2 y C3.

2
 
 

Para introducir una función se puede teclear su nombre, o Insertar función

o utilizar el grupo Biblioteca de funciones


de la ficha Fórmulas. En los dos últimos
casos se abre una ventana en la que
aparece la descripción de la función y de
cada uno de sus argumentos, el resultado
actual de la función y el resultado actual de
toda la fórmula. Para introducir un rango
como argumento pulse el botón .
Siguiendo con el ejemplo anterior, podríamos pulsar Insertar función para
realizar la suma del rango
B2:C3.

 Diferencia entre referencias relativas y absolutas


Cuando se crea una fórmula, normalmente las referencias de celda o de
rango se basan en su posición relativa respecto a la celda que contiene la
fórmula.
Ejemplo: supongamos que la celda B4 contiene la fórmula =A2*B2 (ver tabla más
abajo). Excel multiplica el valor de dos celdas por encima y una celda a la
izquierda (A2) por el de dos celdas por encima (B2) de la actual B4. Este método
se denomina referencias relativas.
Si se copia una fórmula que utiliza referencias relativas, se actualizan las
referencias en la fórmula pegada de forma que se mantiene la posición relativa
de dichas referencias según aparecen en la celda copiada.

3
 
 

A B C
1
2
3
4 =A2*B2 =B2*C2
5 =A3*B3 =B3*C3

Ejemplo: copiamos la fórmula de la celda B4 en el rango B4:C5. La fórmula


en la celda B5 ha cambiado a =A3*B3, que hace referencia a las celdas que
están dos celdas por encima y a la izquierda de la celda B5 (es decir la celda A3)
y dos celdas por encima en su misma columna (celda B3).

Para “fijar” el contenido de una referencia, es decir, para que no cambie


al copiar una fórmula en una celda diferente, se utilizan referencias absolutas.
Para crear una referencia absoluta se coloca un signo de dólar ($) delante
de la columna (letra) y/o de la fila (número) de la referencia a fijar (también
pulsando F4).
Ejemplo:
A B C
1
2
3
4 =A2*$B$2 =B2*$B$2
5 =A3*$B$2 =B3*$B$2

Se puede crear una referencia absoluta para la fila y relativa para la


columna, o viceversa. Para ello coloque un signo de dólar ($) delante del
elemento a fijar, ya sea la columna (letra) o la fila (número) (también pulsando
F4). En la siguiente tabla se fija tan sólo la columna:
A B C
1
2
3
4 =A2*$B2 =B2*$B2
5 =A3*$B3 =B3*$B3

4
 
 

Ejemplo “Número de años”


Construya una tabla en la que se muestre la equivalencia en días, meses
y semestres de un determinado número de años. Introduzca una fórmula en la
celda B7 que pueda copiar en el rango B7:F9 y que complete la tabla.
A B C D E F
1 DATOS:
2 Un año => 365 Días
3 12 Meses
4 2 Semestres
5
6 Años 1 2 3 4 5
7 Días 365 730 1095 1460 1825
8 Meses 12 24 36 48 60
9 Semestres 2 4 6 8 10

Solución:
B7: =B2*B6, multiplica el número de días que tiene un año por el número de
años correspondiente a su columna.
Si copia la celda B7 en el rango B7:F9 no se obtiene la solución deseada.
Sitúe tantos signos dólar (tecla F4) como sea necesario para resolver el ejercicio.

 La función SI
Al construir una hoja de cálculo se debe de tratar, en la medida de lo
posible, de desarrollar fórmulas lo más generales posibles que se puedan
adaptar a diferentes casos. Por ejemplo, el flujo de caja de un bono puede ser
simplemente la cuantía de un cupón o, en el caso de que coincida con el último
flujo o vencimiento del bono, la cuantía del cupón más el nominal del bono.
La función SI (“if” en VBA) proporciona diferentes resultados en función
de si se cumple una o varias condiciones. En concreto, devuelve un valor si la
condición especificada (prueba_lógica) es VERDADERO y otro valor si dicho
argumento es FALSO.
Sintaxis: =SI(prueba_lógica;valor_si_verdadero;valor_si_falso)
- Prueba_lógica: es cualquier valor o expresión que pueda evaluarse como
VERDADERO o FALSO.
- Valor_si_verdadero: es el valor que se devolverá si prueba_lógica es
VERDADERO.

5
 
 

- Valor_si_falso: es el valor que se devolverá si prueba_lógica es FALSO.

NO
Prueba lógica Valor_si_falso

SI

Valor_si_verdadero

Valor_si_verdadero y Valor_si_falso pueden contener otra fórmula.

EJEMPLO “Factura”

Realizamos una hoja de cálculo para expedir facturas. Contemplamos la


posibilidad de aplicar un descuento por pronto pago del 10% en caso de pago al
contado. Aplicamos el IVA al 21%.
Solución:
A B C D
6 Forma de pago: Contado Subtotal: 15.000
7 Tipo descuento: 10% Descuento: 1.500
8 Base: 13.500
9 Tipo IVA: 21% IVA: 2.835
10 TOTAL: 16.335

Se trata de hacer que en la factura se aplique un descuento del 10% sólo


en el caso de cobrar al contado. La fórmula se coloca en la celda D7 y es la
siguiente:
D7: =SI(B6=“Contado”;D6*B7;0)
Esta fórmula comprueba si en la celda B6 existe la palabra Contado. En
tal caso, ejecuta una fórmula (10% de descuento), en caso contrario, coloca
simplemente un cero en la celda D7, es decir, no realizará ningún cálculo.
D8: =D6-D7 , calcula la base imponible tras restar el posible descuento.
D9: =D8*B9 , calcula el IVA
D10: =D8-D9 , obtiene el Total a cobrar

6
 
 

 La función SI con varias condiciones


Puede ocurrir que sea necesario que la función =SI considere varias
condiciones. En función de si se tienen que cumplir todas las condiciones o al
menos una de ellas utilizaremos el operador Y(ꞏ) o el operador O(ꞏ):
- Y(Condición1;Condición2;…): la prueba lógica devuelve VERDADERO sólo si
se cumplen todas las condiciones. Si algunas de las condiciones no se cumple
devuelve FALSO.
- O(Condición1;Condición2;…): la prueba lógica devuelve VERDADERO si se
cumple al menos una de las condiciones. Si no se cumple ninguna de las
condiciones, el operador devuelve FALSO.
Sintaxis:
=SI(Y(Condición1;Condición2;…); _ ; _ ) : se deben cumplir todas las condiciones
=SI(O(Condición1;Condición2;…); _ ; _ ) : se debe cumplir al menos una

EJEMPLO “Control de caja”

Se trata de construir una hoja de control de flujos de caja en un hipotético


caso en el que se deba controlar entradas y salidas además del saldo. La
columna A recoge la fecha de cada movimiento y la columna B el concepto de la
operación. En la columna C aparecen las cantidades depositadas (cobros) y en
la columna D las cantidades desembolsadas (pagos). Finalmente la columna E
refleja el saldo.
Datos:
El saldo inicial es de 4000 €. El día 14 de octubre se contabiliza una
compra con factura nº 12 que implica una salida de caja por valor de 500 € y ese
mismo día una entrada de 1000 € por la venta con factura nº 34.
Solución:
A B C D E
1 Fecha Concepto Depósito Extracción Saldo
2 4.000,00
3 14/10/2017 Compra Fra/12 500,00 3.500,00
4 14/10/2017 Venta Fra/34 1.000,00 4.500,00
5 4.500,00
6 4.500,00

7
 
 

 Solución a)
- E3: =E2+C3-D3, calcula el saldo anterior, más la cantidad de la celda del
depósito, menos la cantidad de la celda de la extracción.
El problema de esta solución aparece cuando se copia la fórmula varias
celdas hacia abajo, ya que a partir del último apunte siempre muestra el saldo
anterior, existan o no cantidades en las celdas de depósito o extracción.
 Solución b)
La función =SI(ꞏ) puede solventar el problema anterior. Podemos controlar
que se cumpla una de estas dos condiciones: que introduzcamos una cantidad
en la celda del depósito o en la de la extracción. Sólo en ese caso aparecerá el
saldo final. Si no existe movimiento en esa fila, la celda permanecerá en blanco
aunque contenga una fórmula.
E3: =SI(O(C3>0;D3>0);E2+C3-D3;"") , (copiar la fórmula hacia abajo)
Si una de las dos condiciones se cumple se ejecuta la fórmula E2+C3-D3.
En caso contrario no aparece nada. Las dos comillas devuelven un carácter nulo.

 La función SI.CONJUNTO

Las últimas versiones de Excel incorporan esta función. Permite incluir


una sucesión de condiciones y las respectivas decisiones a tomar si son
verdaderas. La función comprueba si se cumplen una o varias condiciones y
devuelve un valor que corresponde a la primera condición verdadera.1
Sintaxis:
=SI.CONJUNTO(prueba_lógica1;valor_si_verdadero1;
prueba_lógica2;valor_si_verdadero2;…)
- Prueba_lógica1: es cualquier valor o expresión que pueda evaluarse como
VERDADERO o FALSO.
- Valor_si_verdadero1: es el valor que se devolverá si prueba_lógica1 es
VERDADERO.
No se incluye el típico Valor_si_falso. Si no se cumple ninguna de las
condiciones, la función devuelve “#N/A”.

                                                            
1
 Equivale a la función SELECT CASE en VBA. 

8
 
 

Se puede utilizar como última Prueba_lógica la expresión VERDADERO


o el equivalente valor de 1 para establecer qué hacer en caso de que las demás
condiciones sean falsas.
Ejemplo:
=SI.CONJUNTO(E10=1;1;E10=2;2;1;3)
Esta función devuelve un 1 si la celda E10 contiene un 1, devuelve un 2
si contiene un 2, y devuelve 3 si no se cumple ninguna de las otras condiciones
previas.

 La función SI con anidamiento

Es común la utilización de varias funciones SI anidadas sucesivamente. 

EJEMPLO “Tabla de notas”

Con este ejemplo repasamos varias funciones matemáticas y estadísticas


junto con la función SI con anidamiento.
Se trata de elaborar una tabla con los alumnos de una asignatura. Se
dispone de las notas de los dos cuatrimestres. Con ellas se realizan una serie de
cálculos estadísticos.
Datos:
Con las siguientes calificaciones:
Alumno 1er Cuatrimestre 2º Cuatrimestre
Pedro 2,5 5
Ana 9,7 7,1
Silvia 6 6,2
Luis 1,5 7
Isabel 8,5 9
Juan 7,2 5

Calificar a los alumnos con la nota global del curso en las siguientes
categorías. Suspenso (nota < 5), Aprobado (5 ≤ nota < 7), Notable (7 ≤ nota <
8,5), Sobresaliente (nota ≥ 8,5). Además obtener la nota media, máxima, mínima
y más repetida y calcular el número de alumnos.

Sintaxis de las funciones a utilizar:

9
 
 

 =PROMEDIO(rango), =MAX(rango), =MIN(rango), =MODA(rango): Valor


promedio (media aritmética), máximo, mínimo y más repetido respectivamente
de una lista de números.

Nota: algunas versiones de Excel 2010 utiliza MODA.UNO(rango) aunque


permite el uso de MODA(ꞏ)

 =CONTAR(rango): Cuenta el número de celdas que contienen números.


 =CONTARA(rango): Cuenta el número de celdas que no están vacías.
 =CONTAR.SI(rango;criterio): Cuenta las celdas, dentro del rango, que no
están en blanco y que cumplen con el criterio especificado. Ejemplos:
=CONTAR.SI(A1:A4;123) cuenta las veces que aparece 123 en el rango
A1:A4. =CONTAR.SI(A1:A4;“>123”) cuenta las veces que una celda del rango
A1:A4 contiene un valor superior a 123.

 &: Une dos cadenas de texto. Ejemplo: la celda A1 contiene “Federico” y la


celda B1 contiene “García”, entonces la fórmula =A1&“ ”&B1 , devuelve la
cadena “Federico García”.

Solución:

Planteamos la hoja de cálculo como sigue:


- Columna D la nota final que será la nota media de los dos cuatrimestres.
- Columna E la evaluación en forma de texto.
- En las celdas inferiores izquierda la nota media, máxima y mínima y moda, y el
número de alumnos.
- En las celdas inferiores derecha el número y porcentaje de cada una de las
calificaciones posibles.
   

10
 
 

A B C D E F
1 Alumno 1 Cuatr 2 Cuatr Nota Evaluación
2 Pedro 2,5 5 3,75 Suspenso
3 Ana 9,7 7,1 8,40 Notable
4 Silvia 6 6,2 6,10 Aprobado
5 Luis 1,5 7 4,25 Suspenso
6 Isabel 8,5 9 8,75 Sobresaliente
7 Juan 7,2 5 6,10 Aprobado
8
9
10 Nota media 6,23 Número %
11 Nota máxima 8,75 Suspenso 2 33,33%
12 Nota mínima 3,75 Aprobado 2 33,33%
13 Nota + repetida 6,10 Notable 1 16,67%
14 Nº alumnos 6 Sobresaliente 1 16,67%

D2: =(B2+C2)/2, o también D2: =PROMEDIO(B2:C2), (y copiar hacia abajo)

E2: =SI(D2<5;“Suspenso”;SI(D2<7;“Aprobado”;SI(D2<8,5;“Notable”;“Sobresaliente”)))

NO NO NO
D2<5 D2<7 D2<8,5 Sobresaliente

SI SI SI

Suspenso Aprobado Notable

B10: =PROMEDIO(D2:D7)

B11: =MAX(D2:D7)

B12: =MIN(D2:D7)

B13: =MODA(D2:D7)

B14: =CONTARA(A2:A7)
E11: varias posibilidades:
a) =CONTAR.SI($E$2:$E$7;“Suspenso”) , (copiar en E11:E14 editando cada
fórmula para cambiar el texto de la nota, es decir, sustituir “Suspenso” por
“Aprobado”, ...)
b) =CONTAR.SI($E$2:$E$7;D11) , (copiar hacia abajo)
Copiamos estas fórmulas hasta la celda E14. Así por ejemplo en función
de la opción elegida, en la celda siguiente quedaría:

11
 
 

E12:
a) =CONTAR.SI($E$2:$E$7;“Aprobado”)
b) =CONTAR.SI($E$2:$E$7;D12)
F11: =E11/$B$14 , obtiene el porcentaje de alumnos con la calificación que
aparece en esa fila
Copiar hacia abajo hasta la celda F14.

 Funciones básicas de búsqueda y referencia:


La función básica en el manejo básico de bases de datos es BUSCARV,2
aunque la combinación de las funciones COINCIDIR e INDICE proporciona
resultados similares y alguna posibilidad adicional.
La función BUSCARV busca un valor específico en la columna situada a
la izquierda de los datos que desea encontrar y devuelve el valor en la misma
fila de una columna especificada en la tabla.
Sintaxis:
=BUSCARV(valor_buscado;rango_comparación;indicador_columna;ordenado)
- Valor_buscado: es el valor que se busca en la primera columna del rango.
- Rango_de_comparación: es el conjunto de información donde se buscan los
datos.
- Indicador_columnas: es el número de columna de rango_de_comparación
desde la cual debe devolverse el valor coincidente.
- Ordenado: es un valor lógico que indica si desea que la función BUSCARV
busque un valor igual o aproximado al valor especificado. Si el argumento
ordenado es VERDADERO (1) o se omite, la función devuelve un valor
aproximado, es decir, si no encuentra un valor exacto, devolverá el valor
inmediatamente menor que valor_buscado. Si ordenado es FALSO (0),
BUSCARV devuelve el valor buscado. Si no encuentra dicho valor, devuelve el
valor de error #N/A.
Por su parte, la función COINCIDIR muestra la posición relativa del valor
coincidente en la columna especificada.
=COINCIDIR(valor_buscado;columna_de_comparación;ordenado)

                                                            
2
 En algunas versiones de X2010 se sustituye BUSCARV por CONSULTARV. 

12
 
 

Por último, la función INDICE devuelve el valor dentro de un rango en la


posición relativa indicada por la fila y la columna especificadas.
=INDICE(rango;fila;columna)

EJEMPLO “Consulta de inventario”


Se trata de una base de datos que contiene información sobre el inventario
de artículos que tenemos en almacén y que permite su consulta rápida. En la
celda B1 se introduce el código de un artículo y Excel nos muestra debajo
información sobre a qué producto corresponde y cuántas unidades hay
almacenadas.

A B C D
1 Código a buscar: A04
2 Artículo: Sonajeros 3
3 Cantidad en almacén: 160 Sonajeros
4 Coste unitario: 0,50
5
6 Código Descripción Cantidad Coste unitario
7 A01 Pañales 150 1,00
8 A02 Chupetes 200 2,20
9 A04 Sonajeros 160 0,50
10 A05 Peucos 230 0,60
11 A07 Biberones 250 3,50

B2: =BUSCARV($B$1;$A$7:$D$50;2), busca el contenido de la celda B1 en la


primera columna del rango A7:D50. Una vez encontrado, devuelve el contenido
de la segunda columna del rango, es decir, el correspondiente a la descripción
del producto.
Nótese que hemos omitido el cuarto argumento de la función BUSCARV, es
decir, 0 si desordenado o 1 si verdadero. En estos casos, Excel utiliza el valor 1
por defecto, quedando =BUSCARV($B$1;$A$7:$D$50;2;1).
C3: =BUSCARV($B$1;$A$7:$D$50;3), ídem para tercera columna (cantidad).
D3: =BUSCARV($B$1;$A$7:$D$50;4), ídem para cuarta columna (coste
unitario).

Compruébese lo que ocurre si introducimos el código A03 en la celda B1


y piense cómo actuar en ese caso.

13
 
 

Alternativamente:
D2: =COINCIDIR(B2;A7:A50), fila con el valor buscado en rango A3:A50. En
este caso devuelve el valor 3 porque el código A04 está en la tercera fila del
rango.
D3: =INDICE(A7:D50;D2;2), devuelve el valor de la celda con la posición de fila
(D2) y columna 2 especificadas dentro del rango A7:D50.
También se podría haber obtenido directamente el mismo resultando anidando
ambas funciones: D3: =INDICE(A7:D50;COINCIDIR(B2;A7:A50);2)

EJEMPLO “Comisiones en función saldo medio trimestre”


Debemos establecer la comisión de mantenimiento de las cuentas de
nuestros clientes que se establecen en base a un baremo en función del saldo
medio de la cuenta corriente durante el trimestre.

A B C D
1 Baremo aplicable a comisiones mantenimiento
2 Tramo Saldo mínimo Comisión
3 1 0 6,00
4 2 3.000 3,00
5 3 10.000 0,00
6
7 Cliente Saldo actual Saldo trimestre Com. mantenimiento
8 Aurora Ramírez 4.210,00 3.005,00 3,00
9 Sonia García 26,30 56,00 6,00
10 Pedro Fernández 9.980,00 10.070,10 0,00

D8: =BUSCARV( ¿? ), establezca los cuatro argumentos de la función


BUSCARV para la celda D8 y copie en la celdas inferiores.

14
 
 

 Funciones estadísticas con condicionales:


La hoja de cálculo proporciona decenas de funciones para obtener
estadísticos de una base de datos (véase ficha Fórmulas, Biblioteca de
funciones, Estadísticas). Dentro de estas funciones, resultan de especial utilidad
aquellas que permiten calcular directamente los estadísticos para una
determinada submuestra. La selección de la submuestra que utilizar en el cálculo
se puede realizar de forma sencilla a partir de Tablas dinámicas o, en las últimas
versiones de Excel, con las funciones estadísticas que acaban en *.SI() o en
*.SI.CONJUNTO().

 Tablas dinámicas
Se trata de un asistente que permite crear informes de tablas y gráficos
dinámicos. Para crear una tabla dinámica seleccionamos la base de datos, o
incluso cualquier celda en su interior, en la ficha Insertar pulsamos en Tabla
Dinámica. Aparece ventana en la que se nos propone el rango de celdas de la
base de datos y podemos seleccionar si se crea en una hoja nueva o en una
existente.

EJEMPLO “Tabla de notas” (tablas dinámicas)


Utilizando la base de datos del ejemplo de Tabla de notas (rango A1:E7)
creamos la tabla en una hoja nueva. En la ventana lateral Campos de tabla,
seleccionamos todos los campos, excepto el campo “Alumno”. Por defecto, a
partir de estos datos Excel muestra como filtro en la primera columna el texto
Aprobado, Notable, Sobresaliente y Suspenso, y aparecen las columnas Suma
de 1 Cuatr, 2 Cuatr y Nota.
De nuevo en la ventana lateral Campos de tabla (o pulsando sobre
encabezado de cada columna), podemos seleccionar el estadístico a mostrar
(suma, recuento, promedio, máximo, mínimo, producto, contar números,
desviación típica y varianza muestrales y poblacionales). También podemos
añadir campos adicionales arrastrando su nombre a la ventana Filas. Véase
cómo quedaría la tabla añadiendo el campo Nota a dicha ventana:

15
 
 

 Funciones .SI y .SI.CONJUNTO


Las últimas versiones de Excel incluyen estas funciones que incorporan
condiciones a ciertas funciones habituales. Además, las funciones
.SI.CONJUNTO permiten prescindir del uso de algunos SI anidados, dado que
admiten hasta 127 condiciones diferentes.
Entre estas funciones podemos encontrar: CONTAR.SI, SUMAR.SI,
SUMAR.SI.CONJUNTO, MAX.SI.CONJUNTO, MIN.SI.CONJUNTO,
PROMEDIO.SI, PROMEDIO.SI.CONJUNTO.
Sintaxis:
 =PROMEDIO.SI(rango;criterio;rango_promedio): calcula la media aritmética
de las celdas del “rango_promedio” que corresponden a las filas de las celdas
del “rango” que cumplen el “criterio”.
Ejemplo: en la hoja de cálculo Tabla de notas, queremos obtener la nota final
promedio de aquellos alumnos que aprobaron el primer cuatrimestre.
=PROMEDIO.SI(B2:B7;">=5";D2:D7), que obtiene como resultado 7,3375, que
se corresponde a la nota final media del alumno 2, 3, 4 y 5.

 =PROMEDIO.SI.CONJUNTO(rango_promedio; rango1;criterio1;…): calcula la


media aritmética de las celdas del “rango_promedio” que corresponden a las

16
 
 

filas de las celdas del “rango1”, “rango2”,… que cumplen simultáneamente el


“criterio1”, “criterio2”, ...

Ejemplo: en la hoja de cálculo Tabla de notas, queremos obtener la nota final


promedio de aquellos alumnos que aprobaron el primer cuatrimestre y obtuvieron
al menos un 7 en el segundo cuatrimestre.
=PROMEDIO.SI.CONJUNTO(D2:D7;B2:B7;">=5";C2:C7;">=7"), que devuelve
8,575, que es la media de las notas finales del alumno 2 y 5.

17
 
 

1.2 Funciones financieras básicas


Excel tiene varios centenares de funciones. En este apartado repasamos
algunas de las funciones financieras más usuales y aprovechamos para analizar
los métodos de búsqueda de objetivos mediante el complemento Solver. Con
este fin proponemos un ejemplo de selección de inversiones y otro de valoración
de bonos.

EJEMPLO “Selección de inversiones”


Los criterios clásicos de selección de inversiones son el valor actual neto
(VAN) y el tanto interno de rentabilidad (TIR). Las empresas utilizan estos
criterios para analizar la conveniencia de acometer una nueva inversión a partir
de los flujos de cajas que prevé que genere dicha inversión. El VAN es la suma
del desembolso inicial (-A) y los flujos de caja (Qi) descontados al coste de capital
(k).

-A Q1 Q2 Qn

0 1 2 n
-A
Q1
1 k
Q2
1  k 2
------
Qn
1  k n
Q1 Q2 Qn n Qj
VAN   A  
1  k  1  k 2
 ... 
1  k n
  A  
j 1 1  k 
j

El VAN de una inversión representa el aumento o disminución que sufre


el valor de la empresa a consecuencia de la realización de una inversión. Mide
la rentabilidad absoluta neta.
El TIR es el tipo de interés (r) que anula el valor del VAN (VAN(r)=0). Mide
la rentabilidad relativa bruta. El TIR es la r que satisface esta ecuación:
Q1 Q2 Qn n Qj
VAN   A  
1  r  1  r 2
 ... 
1  r n
  A  
j 1 1  r 
j
0

18
 
 

Un proyecto es rentable si VAN>0 o si el TIR>coste de capital (coste de


financiar la nueva inversión) r > k.
La representación del VAN en función del k:

VAN
VAN > 0
r>k VAN < 0
r<k
Se acepta
Se rechaza

r
k

VAN = f(k)

Sintaxis de algunas funciones financieras aplicables:


=TIR(rango;estimar): devuelve el TIR que proporciona un proyecto de
inversión con pagos (valores negativos) y cobros (valores positivos) para
períodos anuales regulares. “Estimar” es un número que pensamos que se
aproximará al resultado del TIR y es el valor que utiliza Excel para iniciar las
iteraciones.
=TIR.NO.PER(valores;fechas;estimar): devuelve el TIR para flujos de caja
no periódicos, siendo “fechas” el rango donde se especifica el momento del
tiempo expresado en fechas o en número de días en el que se sitúa cada flujo
de caja especificado en “valores”.

=VNA(t_interés;rango): calcula el VAN de una inversión a partir de un tipo


de interés y una serie de pagos (valores negativos) y cobros (valores positivos)
periódicos anuales futuros. Si el primer flujo de caja se sitúa al inicio del primer
período (es el caso del desembolso inicial), su celda no se incluye en el rango
de valores especificado en la función VNA y su valor se debe agregar al resultado
de VNA.
=VNA.NO.PER(t_interés;valores;fechas): devuelve el VAN para flujos de
caja no periódicos, siendo “fechas” el rango donde se especifica el momento del
tiempo expresado en fechas o en número de días en el que se sitúa cada flujo
de caja especificado en “valores”.

19
 
 

Nota: en X2003 las funciones TIR.NO.PER y VNA.NO.PER no están instalada


inicialmente, por lo que su uso requiere activarla: menú Herramientas –
Complementos – Herramientas para análisis.

El complemento Solver permite resolver problemas de optimización con


restricciones a partir de varios algoritmos de búsqueda de soluciones.
Por defecto, es un complemento que está instalado pero que hay que
activar la primera vez que se utiliza:
Pulsar botón Office (en X07) o menú Archivo (en X10 y X13), Opciones de
Excel – Complementos. Una vez en esa ventana, pulsar botón “Ir…” (abajo). En
la nueva ventana de
Complementos, seleccionar
“Solver”.
Para utilizarlo, seleccionar Datos – Análisis – Solver. La celda que fijemos
como “Celda objetivo” debe contener fórmulas que devuelvan el valor buscado
(mínimo, máximo o igual a cierto número) a partir de que Solver cambie el
contenido numérico de la celda o celdas que marquemos como “Cambiando las
celdas de variables”. Se pueden introducir restricciones y cambiar el método de
optimización.

20
 
 

Datos del ejemplo “Selección de inversiones”


Una empresa se plantea evaluar un proyecto de inversión con un
desembolso inicial de 60.000 € y una duración de tres años. Esperamos que el
proyecto genere flujos de caja constantes de 26.625 €. Teniendo en cuenta que
el coste del capital para la empresa es del 8%, se trata de evaluar el proyecto
utilizando el criterio del VAN y del TIR.

Solución:
A B C D E
1 DATOS: Cálculo TIR
2 Coste C.(k): con Solver:
3 8,00% 0%
4 Período FNC Valor Actual Valor Actual
5 0 -60.000 -60.000 -60.000
6 1 26.625 24.653 26.625
7 2 26.625 22.827 26.625
8 3 26.625 21.136 26.625
9
10 VAN= 8.615 Suma: 19.875
11
12 Cálculo s/ f. financieras
13 Decisión:
14 VAN 8.615 Se acepta
15 TIR 15,79% Se acepta

A) Cálculos a partir del valor actual de los flujos de caja:


A) 1. Cálculo del VAN:
C5: =$B5*(1+C$3)^(-$A5), calcula el valor actual del flujo B5 (copiar hacia
abajo y también en la columna E. Copiar en el rango C5:C8 y en E5:E8.
Téngase en cuenta que para actualizar los flujos utiliza respectivamente el tipo
de interés de la celda C3 y E3.
C10: =SUMA(C5:C8), suma del valor actual de los flujos de caja con la que
obtenemos el VAN del proyecto (copiar en E10 para el cálculo del TIR con el
Solver),
A) 2. Cálculo del TIR con el Solver:
Podemos dar valores manualmente a la celda E3 hasta que consigamos
que se anule la celda E10. En ese caso, el valor de la celda E3 será el TIR
dado que consigue anular el valor actual neto de los flujos de caja (E10).
Para obtener el mismo resultado de forma inmediata, podemos lanzar el
Solver para que dé valores a la celda E3 hasta que alcance el óptimo

21
 
 

buscado, es decir, que el valor de la celda E10 sea cero. Pulsamos el botón
“Resolver”.

Aunque en este ejemplo hemos utilizado el Solver para obtener la


solución, su uso no es necesario en este ejemplo sencillo.
El complemento Solver tiene un desventaja importante con respecto a las
funciones Excel. Mientras que todas las funciones actualizan su valor cuando
cambia cualquier celda que interviene en su cálculo (por ejemplo, rectificamos el
valor del flujo de caja del periodo 1), Solver se ejecuta una única vez y devuelve
un valor que ya no varía hasta que volvamos a ejecutarlo.

B) Cálculos a partir de las funciones financieras del Excel:


B14: =B5+VNA(C3;B6:B8), obtiene directamente el VAN, su valor debe
coincidir con la celda C10,
B15: =TIR(B5:B8;0,1), devuelve el TIR a partir de un valor inicial del 10%.

En todos los casos, la decisión de aceptación o rechazo del proyecto en


base al criterio VAN depende de si valor es positivo, y en base al criterio TIR de
si éste es mayor al coste de capital. Por tanto:
C14: =SI(B14>0;”Se acepta”;“Se rechaza”),
C15: =SI(B15>C3;”Se acepta”;“Se rechaza”),

22
 
 

1.3 Introducción al Visual Basic para Aplicaciones (VBA)

El uso de código de Visual Basic para Aplicaciones (VBA) y macros amplía


y mejora las posibilidades de Excel a través de dos vías:
1. Son una forma excelente de realizar tareas repetitivas.
2. Facilitan el uso de la hoja de cálculo a otros usuarios que no estén
familiarizados con Excel.
En este apartado nos centramos en mostrar cómo automatizar cálculos
repetitivos con funciones y macros, trabajando con ejemplos que muestran las
mejoras en la funcionalidad de Excel que proporciona VBA. Podemos preparar
hojas de cálculo robustas si sustituimos secuencias complicadas de cálculos por
simples funciones que hemos definido. Además, los macros de VBA permiten
automatizar tareas repetitivas (por ejemplo la simulación). En ambos casos, los
procedimientos se programan en VBA; los primeros son funciones definidas por
el usuario (Function) y los segundos son macros o subrutinas (Sub).
Es importante distinguir entre subrutina y función. La función devuelve un
valor numérico resultante de cálculos que se hacen a partir de los argumentos o
inputs que se especifican al llamar a la función desde una celda de la hoja de
cálculo o desde un procedimiento de VBA. Por su parte, las subrutinas no
requieren necesariamente de argumentos o inputs, y ejecutan una secuencia de
comandos nutriéndose de los inputs y del contenido de una o varias celdas de la
hoja de cálculo. Se ejecutan desde el menú Programador de Excel, desde el
menú del editor de VBA o desde una llamada (comando Call) en un
procedimiento. La llamada a un macro no devuelve ningún valor, pero ejecuta el
código y puede cambiar el valor de las variables pasadas como argumentos.
La primera vez que se trabaja con VBA en un ordenador hay que habilitar
la ficha Programador. Con este fin, pulse el botón Office (X07) o el menú Archivo
(X10 y X13) – Opciones – Personalizar cinta de opciones. Una vez desplegada
la ventana, active la casilla “Mostrar ficha Programador en la cinta de opciones”
(X07), la casilla “Programador” (X10) o “Desarrollador” (X13).3

                                                            
3
 En versiones anteriores de Excel, se debe seguir el mismo procedimiento que el indicado para activar 
Solver. 

23
 
 

Las funciones y los macros se programan desde el Editor VBA.


Para abrirlo, pulse sobre la ficha Programador – Visual Basic o a partir de
la combinación de teclas Alt + F11.4
Para escribir una función debemos entrar en un módulo existente o
crearlo. Para abrir un
nuevo módulo seleccione
Insertar – Módulo en el
Editor VBA.

Ejecución y depuración de funciones y macros


Las funciones y los macros de VBA se escriben en un módulo. Para crear
uno nuevo se selecciona Insertar – Módulo en el menú de la ventana del editor
de VBA. Para entrar en el editor, se puede pulsar Alt + Tab o Alt + F11 o hacer
clic en el botón equivalente en la ficha Programador de Excel.
Una función o un macro son una serie de instrucciones VBA encerradas
entre un par de instrucciones Function o Sub y End Function o End Sub
respectivamente. Si una función o un macro no tienen argumentos o inputs, el
nombre del mismo debe incluir un par de paréntesis vacíos.
Un ejemplo sencillo:
Sub demoMsgBox()
MsgBox "Pulsa OK para terminar esta demo de MsgBox"
End Sub
Hay varias formas de ejecutar una macro o una función:
- Desde Excel, en la ficha Programador (o Desarrollador) – Códigos – Macros,
se selecciona el nombre de la macro en el listado y se pulsa ejecutar.

                                                            
4
 En versiones anteriores se accede a partir del menú Herramientas – Macro – Editor Visual Basic. 

24
 
 

- Desde el editor de VBA, se sitúa el cursor sobre cualquier parte del código del
macro que se quiere ejecutar y se pulsa el botón o la tecla F5.
- Se puede ejecutar también directamente:
o si se le asigna al macro un botón (CommandButton) que se ubica en la
hoja de Excel o en un formulario FRM,
o si se le asigna una combinación de teclas específica (Opciones - Tecla
de método abreviado).
Nota: Los módulos formulario (nombre.FRM) además de código contienen la
descripción del formulario (ventana o cuadro de diálogo) y sus controles.

     
 
Resulta de gran utilidad ejecutar un macro instrucción a instrucción para
observar qué acciones origina cada instrucción y así mejorar el código o depurar
errores. Para ejecutar paso a paso, desde el menú Ejecutar del editor de VB o
también haciendo clic en o pulsando F8 para pasar de una instrucción a la
siguiente.
Cuando el macro está en ejecución, se puede inspeccionar el valor que
en ese momento toma una variable si situamos el cursor sobre ella. Aparece una
etiqueta amarilla con su valor. Para inspeccionar el valor de un objeto (por
ejemplo, la celda B23), hay que situar el cursor sobre el texto del código en el
que aparece su nombre y pulsar o May+F9. Si se pulsa Agregar, la variable
u objeto aparece en la ventana Inspecciones y se puede ver su valor en todo
momento de la ejecución.
En macros muy largas o cuya ejecución requiere mucho tiempo puede
resultar tedioso la ejecución paso a paso (F8). En ese caso, se pueden insertar
uno o varios puntos de inspección (F9) donde queremos que la ejecución normal
del macro (F5) se interrumpa. En ese punto podemos inspeccionar el valor de
las variables o el estado de la hoja de cálculo y reanudar la ejecución automática
(F5) o paso a paso (F8). Para insertar o eliminar un punto de inspección, se

25
 
 

puede utilizar el menú Depuración, hacer clic en o F9. La línea seleccionada


como punto de inspección cambia a un fondo de color rojo.
Al interrumpir un macro en ejecución se pueden modificar ciertas partes
del código sin que esto impida la posterior reanudación de la ejecución, pero la
mayor parte de las modificaciones implican la finalización del proceso.
Un macro se puede interrumpir definitivamente en cualquier momento
pulsando “Restablecer” si el macro está detenido, o, si está en ejecución,
pulsando Esc + Esc o Ctrl + Bloq Despl.
Cuando se corre el código, la ejecución puede parar si se produce un
error. Una ventana muestra el tipo de error y al pulsar OK el cursor salta a la
instrucción que origina el error. Si se corrige el error, podemos continuar la
ejecución pulsando Depurar. También podemos parar definitivamente la
ejecución con Finalizar .

1.3.1. Funciones definidas por el usuario (Function)

Una función definida por el usuario es una lista de instrucciones que


persiguen obtener como resultado un único valor que devuelve la propia función.
Son especialmente útiles para automatizar cálculos a los que hay que recurrir en
repetidas ocasiones. Permite trabajar con hojas de cálculo con diseño muy
sencillo y limpio, además se pueden exportar a otras hojas de cálculo.
Una función requiere tres elementos obligatorios:
1. Una línea cabecera con el nombre de la función y una lista de argumentos.
2. Una línea de cierre (habitualmente la inserta el propio VBA).
3. Líneas con el código del programa (instrucciones) entre cabecera y cierre.
En cuanto se escribe una línea y se pulsar la tecla Intro, VBA depura el
contenido de la línea. Las palabras que VBA reconoce como comandos de
programación cambian a color azul y aparecen en la primera letra en
mayúsculas. Las líneas que comienzan por un apóstrofe se interpretan como
texto de ayuda y se muestran en color verde.
El empleo de funciones Function con código complicado puede ser difícil
de gestionar, por lo que NO SE RECOMIENDA. Excel refresca toda la hoja cada
vez que se cambia la posición del cursor, se escribe cualquier carácter o se hace

26
 
 

click en cualquier celda o botón. Esto implica que continuamente está llamando
a las funciones VBA que hemos creado, por lo que entorpece y en muchas
ocasiones llega a paralizar la programación de otras funciones o procedimientos.

Nota importante sobre el uso de funciones VBA y Solver: es habitual un error en


el Editor de VBA cuando editamos código de funciones (Function) cuando se
hace alguna llamada a Solver. El Editor da error en cada una de las variables
utilizadas en el código. Para evitarlo, asegúrese de activar Solver en Excel
(Archivo – Complementos – Ir – marcar Solver) y también en el Editor de VBA
(Herramientas – Referencias – marcar Solver.

Ejemplo: Conversor de grados Fahrenheit a grados Celsius (Iniciación)


La escala de temperatura Fahrenheit fija las temperaturas de congelación
y ebullición del agua en 32 °F y 212 °F respectivamente. La fórmula matemática
a utilizar para su conversión a grados Celsius es la siguiente:
32
1,8
Creamos una función que, a partir del dato de grados F (lo introducimos
como argumento de la función), devuelva el equivalente en grados C.
Function Celsius(GradosF)
Celsius = (GradosF - 32) / 1.8
End Function

Ahora en la hoja de cálculo podemos escribir:


A B C D
1 Temperaturas:
2 Fahrenheit: 50
3 Celsius: 10

B3: =celsius(B2)

27
 
 

Ejemplo: Valoración opciones por Black-Scholes (Uso de dos funciones con


múltiples inputs y llamada a funciones de Excel y a funciones VBA)

Excel no ofrece una función para el cálculo del valor de una opción según
la fórmula de Black-Scholes. No obstante, podemos utilizar funciones existentes
para poder resolver el problema con la hoja de cálculo. Sin embargo, de cara a
obtener una hoja de cálculo más sencilla para el usuario resulta de interés
desarrollar una función definida por el usuario para valorar una opción de compra
call (BScall).
La teoría subyacente en la fórmula de Black-Scholes se analiza en la
asignatura “Activos Financieros Derivados y Gestión de Riesgos” de 2º
cuatrimestre. Ahora no es necesario entender la fórmula de valoración ya que
nuestra propuesta es trabajar con código VBA.
La fórmula de valoración de Black-Scholes para una opción de compra
europea sobre acciones que no pagan dividendos es la siguiente:
c  S  N (d1 )  X  e  rt N (d 2 )
siendo:
S = precio actual de mercado del activo,
X = precio de ejercicio de la opción,
r = tipo de interés libre de riesgo capitalizable continuamente,
t = número de años hasta el vencimiento,
N(d): es el valor de la función de distribución acumulada de la normal estándar,
N(0,1). Se trata de la probabilidad acumulada de una normal estándar para un
valor menor que d. Por ejemplo, para d = -1:
Probabilidad

N(d)

d = -1 0 +1 +2

d1 y d2 vienen dados por las siguientes expresiones:


  1
ln S  (r   2 )t
X 2
d1  d 2  d1   t
 t

28
 
 

 = desviación típica del rendimiento instantáneo de la acción en términos


anuales.
Excel proporciona la función DISTR.NORM.ESTAND(z) para obtener
directamente el valor de la expresión N(z). Esta función es compatible con X10 y
X13 aunque se sustituye por la función DISTR.NORM.ESTAND.N(z;tipo) que
devuelve el valor de la función de densidad en z si tipo = 0, o el valor de la función
de distribución acumulada hasta z si tipo = 1.
Adicionalmente, la paridad put-call permite obtener el valor de una opción
de venta (put) europea a partir del valor de una opción de compra (call) sobre el
mismo activo subyacente y con el resto de características idénticas.
c + X e –rT = p + S

Ejemplo:
Se supone una opción de compra (call) europea sobre una acción con seis
meses hasta el vencimiento. El precio actual del activo subyacente es de S = 100
€ y el precio de ejercicio es de X = 95€. La desviación anualizada del tanto de
rendimiento instantáneo de la acción es del  = 20% y el tipo de interés en tiempo
continuo libre de riesgo el r = 8%.
A B C D
1 Black-Scholes
2 Datos:
3 Precio acción (S) 100
4 Precio ejercicio (X) 95
5 Tipo interés (r) 8%
6 Plazo h vto. (t) 0,5
7 Volatilidad () 0,2
8
9 Cálculos con Excel: Funciones VBA:
10 d1 0,7163 Call 10,8369
11 N(d1) 0,7631 Put 2,119
12 d2 0,5748
13 N(d2) 0,7173
14 Call 10,8369
15 Put 2,1119

B10: =(LN(B3/B4)+(B5+0.5*B7^2)*B6)/(B7*RAIZ(B6))
B11: =DISTR.NORM.ESTAND.N(B10;1)
B12: =B10-B7*RAIZ(B6)
B13: =DISTR.NORM.ESTAND.N(B12;1)
B14: =B3*B11-B4*EXP(-B5*B6)*B13 ; B15: =B14+B4*EXP(-B5*B6)-B3

29
 
 

En el Editor de VBA (abrir desde ventana del Desarrollador de Excel)


planteamos una nueva función para el cálculo del valor de la call. Posteriormente
la aprovechamos para el cálculo de una put.
Utilizamos las siguientes funciones propias de VBA:
- Log: proporciona el logaritmo natural (LN en Excel), mientras que Log10
es el logaritmo en base 10 (LOG en Excel).
- Sqr: raíz cuadrada (RAIZ en Excel).
- Exp: exponencial.
Además llamamos a una función de Excel. Para usar en el código
funciones de Excel debemos ponerles el sufijo Application o
WorksheetFunction. El nombre de la función debe ser el de la versión inglesa
de Excel. Por ejemplo, si dentro de código VBA quisiéramos utilizar la función
SUMA de Excel, deberíamos escribir Application.Sum, ya que en la versión
inglesa de Excel se utiliza la función =SUM. En el caso que nos ocupa,
Application.NormSDist proporciona la probabilidad acumulada en la
distribución normal estándar, es decir, NormSDist en la versión inglesa es
equivalente a nuestro Distr.Norm.Estand.

Function BScall(S, X, r, t, sigma)


'obtiene el valor de una opción call europea sobre acciones
que no pagan dividendo
d1 = (Log(S / X) + (r + 0.5 * sigma ^ 2) * t) / (sigma *
Sqr(t))
d2 = d1 - sigma * Sqr(t)
Nd1 = Application.NormSDist(d1)
Nd2 = Application.NormSDist(d2)
BScall = S * Nd1 - X * Exp(-r * t) * Nd2
End Function

Utilizando una llamada a nuestra nueva function BSCall y valiéndonos de


la paridad put-call podemos crear fácilmente una función similar para obtener el
valor de una opción de venta (put).
Function BSput(S, X, r, t, sigma)
callprice = BScall(S, X, r, t, sigma)
BSput = callprice + X * Exp(-r * t) - S
End Function

D10: =BScall(B3;B4;B5;B6;B7) D11: =BSput(B3;B4;B5;B6;B7)

30
 
 

Ejemplo: Valoración opciones por Black-Scholes (II) (Uso de estructuras de


control)

Antes de realizar ciertos cálculos podemos comprobar el cumplimiento de


ciertas condiciones. Si no se cumplen, se genera un error. Cuando se trata de
una función de Excel escrita en una celda de la hoja, Excel devuelve un mensaje
de error en dicha celda. Cuando el error se produce ejecutando un código, Excel
interrumpe la ejecución y muestra un mensaje de error en inglés que puede
desconcertar al usuario. Conviene tratar de eludir dichos errores.
En la función que hemos elaborado para valorar la prima de una call o de
una put vamos a tratar de evitar que se produzca un error por la introducción de
un valor negativo en el valor del plazo. Esto implicaría el cálculo de la raíz
cuadrada de un número negativo. Llamamos a las nuevas funciones BScall2 y
BSput2.
CVErr devuelve el mensaje de error correspondiente al número de error
especificado como argumento. En este caso, la constante xlErrValue toma el
valor 2015 que se corresponde con el texto “#VALOR!”.

Function BScall2(S, X, r, t, sigma)


If t > 0 Then
BScall2 = BScall(S, X, r, t, sigma)
Else
MsgBox (”¡Plazo negativo!”)
BScall2 = CVErr(xlErrValue)
End If
End Function

Function BSput2(S, X, r, t, sigma)


callprice = BScall2(S, X, r, t, sigma)
BSput2 = callprice + X * Exp(-r * t) - S
End Function

D10: =BScall2(B3;B4;B5;B6;B7)
D11: =BSput2(B3;B4;B5;B6;B7)

   

31
 
 

1.3.2. Programación orientada a objetos de VBA

Cada objeto de Excel representa una característica de Excel, por ejemplo,


libros de trabajo (workbook), hojas de cálculo (worksheets), rangos (ranges),
gráficos (chats), etc. son objetos de Excel como lo es el propio Excel (el objeto
Application). Al programar en VBA se modifican las propiedades de esos objetos
y se aplican diferentes métodos a dichos objetos.

 Los objetos se agrupan en colecciones:


Por ejemplo, la colección Workbooks se compone de todos los libros de
trabajo (workbook) abiertos. Del mismo modo, la colección Worksheets
comprende todas las hojas de un libro de trabajo (workbook), o la colección
Charts contiene todos los gráficos de una hoja de cálculo. Sin embargo, algunos
objetos son objetos únicos (colecciones con un solo miembro), por ejemplo,
Excel solo tiene un objeto Application y para cualquier celda de la hoja hay solo
un objeto Font (aunque ese objeto tiene varias propiedades, como Name, Size,
etc). Para hacer referencia a estos objetos simples, basta con escribir Application
o Font. Los objetos individuales que componen una colección se referencian
mediante números (1, 2, 3…) o por nombre –por ejemplo, Workbooks(1) o
Sheets(“hoja1”)–. El objeto Range es un objeto simple al que se le hace
referencia como si se tratara de una colección –por ejemplo, Range( “datos”) o
Range(“A1:B20”)–.

 Los objetos se agrupan según una jerarquía:


Esta secuencia muestra la jerarquía de objetos en Excel. El rango de
celdas “datos” en la hoja “hoja1” del libro Modelo.xlsx se referencia como:
Application.Workbooks(“Modelo.xlsm”).Sheets(“hoja1”).Range(“dato
s”)
No es necesario usar toda la jerarquía, dado que el rango “datos” es único.
Si el libro “Modelo.xlsm” es el libro activo cuando se ejecuta VBA, basta con
hacer referencia a:
ActiveWorkbooks.Sheets(“hoja1”).Range(“datos”)

32
 
 

Del mismo modo, si solo el libro “Modelo.xlsm” está abierto y la hoja


“hoja1” está activa, basta con:
ActiveSheet(“hoja1”).Range(“datos”)

 Los objetos tienen propiedades:


Las propiedades son los atributos de un objeto, los valores o parámetros
que lo describen. Los valores de las propiedades son habitualmente números,
texto, True o False, etc. Se tiene control de los objetos de Excel utilizando VBA
para cambiar sus propiedades.
Application.ScreenUpdating = False
Esta línea de código paraliza el refresco de la ventana de Excel durante
la ejecución de una macro. ScreenUpdating es una propiedad del objeto
Application que toma valor True/False.
Otro ejemplo:
Range(“B23”).Name = “mes1”
Range(“B23”).Value = 4000 o también Range(“B23”) = 4000
Range(“B24”).Formula = “=b23/30”
La celda B23 se convierte en un rango llamado “mes1” y toma valor 4000.
Escribimos una fórmula en la celda B24 que divide el valor de la celda B23 por
30. En el siguiente ejemplo, la variable “a” toma el valor de la celda B24.
a = Range(“B24”).Value

Nota: alternativamente se puede sustituir Range(“B24”)por únicamente [b24].


Por ejemplo: [B23] = 4000 y también [B24].Formula = “=b23/30”

 Los objetos tienen métodos:


Los métodos son un conjunto de acciones predefinidas que se pueden
aplicar a un objeto. Algunos ejemplos sobre el objeto Range:
Range(“A1:B3”).Select selecciona el rango de celdas A1:B3,
Range(“A1:B10”).Copy copia el rango A1:B10 al portapapeles,
Range(“hola”).PasteSpecial pega el portapapeles en el rango “hola”,
Workbooks(“Modelo.xlsm”).Activate hace a Modelo el libro activo,
Sheets(“hoja1”).Delete borra la hoja llamada “hoja1”.
En este ejemplo, Range, Workbooks y Sheets son objetos y Select, Copy,
PasteSpecial, Activate y Delete son métodos que actúan sobre el objeto.

33
 
 

1.3.3. Macros de VBA (subrutinas Sub)

Macros de pulsaciones
Cuando desde Excel seleccionamos la opción “Grabar macro”

(Programador/Desarrollador – Código – Grabar macro) o desde la opción


equivalente en el editor de VB, el grabador traduce cada pulsación en el teclado
o con el ratón a comandos de código VBA. El resultado es un código rudimentario
VBA que podemos utilizar como punto de partida para editarlo y reescribirlo, y
así convertirlo en código VBA más apropiado. Una vez que deseemos finalizar
la secuencia de instrucciones pulsamos “Detener grabación” .
La ventaja de esta opción frente a escribir el código del macro consiste en
que cada paso dado se almacena en un nuevo módulo de macro adjunto al libro
de Excel. Así la secuencia de acciones realizadas queda registrada como una
secuencia de comandos de VBA, la cual servirá como punto de partida del macro
definitivo. A partir de ella, se modifican esos comandos y se añaden otros, como,
por ejemplo, la introducción de bucles para repetir ciertas instrucciones.
El grabador tiene dos modos. Por
defecto interpreta las direcciones de las
celdas en referencias relativas, aunque
también se puede programar para que
utilice referencias absolutas.
Lo ilustramos con un ejemplo. Seleccionamos la celda B4, escribimos
Enero, nos vamos a B5 e introducimos Febrero, cambiamos a C4 y entramos
350, en C5 ponemos 500 y en C6 introducimos la fórmula =SUMA(C4:C5).
Pulsamos Detener grabación. Como resultado se ha creado el Módulo2:
Sub Macro1()
'
' Macro1 Macro
'
'
Range("B4").Select
ActiveCell.FormulaR1C1 = "Enero"
Range("B5").Select
ActiveCell.FormulaR1C1 = "Febrero"
Range("C4").Select
ActiveCell.FormulaR1C1 = "350"
Range("C5").Select
ActiveCell.FormulaR1C1 = "500"

34
 
 

Range("C6").Select
ActiveCell.FormulaR1C1 = "=SUM(R[-2]C:R[-1]C)"
Range("C7").Select
End Sub
Siempre que ejecutamos este macro obtenemos exactamente el mismo
resultado, que consiste en rellenar el rango B4:C7.
El grabador de macros produce excelentes resultados cuando realizamos
tareas complejas que requieran el uso de comandos del menú, como por
ejemplo, realizar gráficos a partir de datos, ordenar datos, etc. El resultado es un
código conciso. Por el contrario, si las acciones consisten en secuencias de
movimiento de cursor, el resultado es un código farragoso. Es el caso del
ejemplo, que lo podríamos editar y obtener el mismo resultado con este código:
Sub Macro1()
Range("B4") = "Enero"
Range("B5") = "Febrero"
Range("C4") = 350
Range("C5") = 500
Range("C6") = "=SUM(C4:C5)"
End Sub

1.3.4. Variables, condicionales y bucles

Declaración y Tipos de variables


Las declaraciones se usan para dar nombre y definir procedimientos,
variables, matrices y constantes. Para declarar variables se utiliza normalmente
una instrucción Dim. La declaración sólo se realiza una vez.
Dim Hola As String
- Si esta instrucción aparece dentro de un procedimiento, la variable Hola se
puede usar sólo en ese procedimiento.
- Si la instrucción aparece en la sección Declarations del módulo, la variable
Hola estará disponible en todos los procedimientos dentro del módulo, pero
no para los restantes módulos del proyecto.
- Para hacer que esta variable esté disponible para todos los procedimientos
de un proyecto:
Public Hola As String

35
 
 

No es necesario declarar una variable para poder utilizarla en un


procedimiento. En ese caso la variable es del tipo Variant. Ejemplo, el uso por
primera vez de la variable:
a = 20
Range("A1").Value = a  
Es equivalente a:
Dim a As Variant
a = 20
Range("A1").Value = a 
Aunque en desuso, se puede sustituir la declaración de una variable por
su uso directo escribiendo su nombre seguido del carácter de declaración
(símbolo) correspondiente. Ejemplo: si queremos que la variable “a” sea entera
(Integer), podemos utilizar alternativamente:
a% = 20
Range("A1").Value = a%  
Otra posibilidad sería:
Dim a As Integer
a = 20
Range("A1").Value = a 

 Tipos de variables con su carácter de declaración:


- Integer (%): número entero con valores que van de -32.768 a 32.767.
- Long (&): número entero largo con un valor comprendido entre -/+
2.147.483.648.
- Currency (@): número de punto fijo con 15 dígitos a la izquierda del signo
decimal y 4 dígitos a la derecha.
- Single (!): número de punto flotante de precisión simple, con valores que van
de -3,4E38 a -1,4E-45 para valores negativos y de 1,4E-45 a 3,4E38 para
valores positivos.
- Double (#): número de punto flotante de doble precisión, con valores de -
1.8E308 a -4,9E-324 para valores negativos y de 4,9E-324 a 1,8E308 para
valores positivos.
- String ($): cadena de caracteres (letras y números), con longitud hasta 2^31
caracteres.
- Variant: es un tipo de datos especial que puede contener cualquier clase de
datos y es el tipo de datos para todas las variables si no se declaran

36
 
 

explícitamente como variables de algún otro tipo (utilizando instrucciones


como Dim, Private, Public o Static).
- Otros: Boolean (True o False), Byte (entre 0 y 225), Date (fechas), Decimal
(entre 0 y 28 posiciones decimales), Object (un objeto como una ventana,
archivo, ...)
Ejemplos:
Dim hola As Integer, n As Double
Dim Matriz(3, 4) As Integer
Dim MiMatriz(1 To 5, 4 To 9, 3 To 5) As Double
Dim FechaNacimiento(1 To 10) As Date 

También directamente:
lahora = Time 'lahora es Variant por defecto, Time es
'una función de VBA que devuelve la hora
rdo# = 12/3 'rdo# es Double por el carácter #
 
Nota: Al ejecutar el código, VBA prescinde de todo lo situado a la derecha del
símbolo “ ' ”, por lo que dicho carácter se utiliza para añadir comentarios.

Ejemplo: Factorial de un número (I) (Uso declaraciones variables, de la


herramienta InputBox y de funciones Excel)
En este ejemplo declaramos dos variables, pero sin especificar el tipo
(deberían ser enteras). Por defecto se les asigna el tipo Variant.
Sub Factorial()
'Calcula el factorial de un número
Dim fac, num
num = InputBox(“Introduzca un número”, “Calcular
Factorial”)
fac = Application.Fact(num)
MsgBox ”El factorial de ” & num & “ es ” & fac
End Sub

 Funciones de conversión de tipos:


- Val(string): convierte una cadena de caracteres a valor numérico. Si la
cadena a convertir contiene algún carácter no numérico devuelve 0. Así, si al
pedir un valor se teclea "Hola", la función Val devuelve un cero.
- Str(número): convierte el número a una expresión de cadena.
- Las funciones CStr, CVar, CSng, CLng, CInt, … convierten el valor
especificado como argumento en una variable String, Variant, Single, Long,
Integer, …

37
 
 

Vectores y matrices (arrays)

Un array es una variable que contiene un grupo de valores con el mismo


tipo de dato, por ejemplo, un vector o una matriz. Para declarar un array con
variables de tipo Double:
Dim x() as Double
donde () le dice a VBA que x es un array.
En la declaración se pueden especificar las dimensiones de x (número de
elementos):
Dim x(1 to 10) as Double
En este caso se declara un vector fila con 10 elementos, cuyo primer
elemento tiene el índice 1.

En ocasiones no se conoce el número de elementos inicialmente, y éste


se fija como resultado de operaciones realizadas en el macro. La instrucción
ReDim permite fijar las dimensiones:
Dim x() as Double
ReDim x(1 to 10)

Por defecto el índice de un array va desde 0 hasta el número especificado


en la instrucción Dim o ReDim.
ReDim x(10, 3) crea una matriz de 11 filas y 4 columnas.

Hacer referencia a celdas y rangos


Un objeto Range está definido por una clase donde se definen sus
propiedades. Entre las propiedades de un objeto Range están Value, que
contiene el valor de la celda, Column y Row que contienen respectivamente la
fila y la columna de la celda, Font que contiene la fuente de los caracteres que
muestra la celda, etc.
Range, como objeto, también tiene métodos que sirven para llevar a cabo
una acción sobre un objeto. Por ejemplo, el método Activate, hace activa una
celda determinada, Clear, borra el contenido de una celda o rango de celdas,
Copy, copia el contenido de la celda o rango de celdas en el portapapeles.

38
 
 

Sub demo
ActiveSheet.Range("A1").Value = "Hola"
ActiveSheet.Range("A1").Font.Bold = True
ActiveSheet.Range("A1").Font.Color = RGB(255,0,0)
End Sub
Escribe “Hola” en la celda A1 en negrita (Bold) y en color rojo, dado que
los 3 argumentos de la función RGB(rojo, verde, azul) toman valores entre 0 y
255 que muestran la intensidad de los tres colores respectivamente.
El objeto Cells(fila, columna) sirve, como el objeto Range, para referenciar
una celda o rango de celdas, pero en lugar de utilizar la referencia de la forma
A1, B1, X320,... utiliza la fila y la columna que ocupa la celda dentro de la hoja
(objeto WorkSheet). Por ejemplo, para poner “hola” en la celda C4 de la hoja
activa utilizaríamos:
ActiveSheet.Cells(4,3).Value= "Hola"

También se puede utilizar Cells para referenciar un rango. Cells es un


poco más larga, pero a veces resulta mucho más funcional que utilizando
únicamente Range.
Para referirnos al rango A1:B8, pondremos:
Range(Cells(1, 1), Cells(8, 2)).Value = "Hola"
Esto es equivalente a
Range(“A1:B8”).Value = "Hola"
Otra forma interesante de utilizar Cells es la siguiente:
Range("A5:B10").Cells(2, 1).Value = "Hola"
que pondrá en la celda A6 el valor "Hola". Observe que en este ejemplo Cells
comienza a contar filas y columnas a partir del rango especificado en el objeto
Range.
Otros ejemplos:
Método A1 Método índice Se refiere a
Range("A3") Cells(3,1) A3
Range("A1:B3") Range(Cells(1,1),cells(3,2)) A1:B3

Resulta muy conveniente al programar que la referencia a una celda o


rango dependa de alguna variable. Si utilizamos las variables col y fila podemos
analizar unos ejemplos:
Rango fila col Método A1 Método índice
A3 3 Range("A" & fila) Cells(fila,1)
A1:B3 3 Range("A1:B" & fila) Range(Cells(1,1),Cells(fila,2))
A1:B3 1 Range("A" & col & ":B3") Range(Cells(1,col),Cells(3,2))

39
 
 

Las propiedades Rows y Columns hacen referencia a filas o columnas


enteras. Estas propiedades devuelven un objeto Range que representa un rango
de celdas. Algunos ejemplos:
Rows(1), fila uno, Rows, todas las filas de la hoja de cálculo,
Columns(1), columna uno, Columns("A"), columna uno, Columns, todas las
columnas de la hoja de cálculo.
La propiedad Offset hace referencia a una celda relacionada con la actual.
ActiveCell.Offset(1, 3).Font.Underline = xlDouble
Asigna un formato de doble subrayado al contenido de la celda situada
una fila más abajo y a tres columnas de la celda activa en la hoja de cálculo.
El objeto que contiene el rango en el que se encuentra la celda activa se
denomina ActiveCell.CurrentRegion. El uso de este objeto es muy útil a
la hora de contar celdas, cambiarlas de formato, etc. Este código las borra:
ActiveCell.CurrentRegion.EntireRow.ClearContents

Variables objeto
Una variable objeto sirve para hacer referencia a un objeto, esto significa
que podremos acceder a las propiedades de un objeto e invocar a sus métodos
a través de la variable en lugar de hacerlo directamente a través del objeto. Se
suele utilizar en bucles del tipo For Each ... Next o cuando sea necesario
construir funciones que devuelvan rangos, referencias a hojas, etc.
Para declarar una variable objeto se utiliza la instrucción Dim Var_Objeto
As Objeto. Por ejemplo:
Dim R As Range
Dim Hoja As WorkSheet
Para asignar un objeto a una variable debe utilizar la instrucción Set
Variable_Objeto = Objeto. Por Ejemplo:
Set R= ActiveSheet.Range("A1:B10")
Set Hoja = ActiveSheet
Set Hoja = WorkSheets(1)
Ejemplo: Llenar el rango de A1 a B10 con la palabra "Hola" en negrita.
Sub obj()
Dim R As Range
Set R = ActiveSheet.Range("A10:B15")
R.Value = "Hola"
R.Font.Bold = True
End Sub

40
 
 

Pasar una variable como argumento en Function o Sub


Las llamadas a funciones y subrutinas van acompañadas en muchas
ocasiones de una lista de argumentos que proporcionan información sobre
variables y objetos necesarias para la ejecución de dicho procedimiento.
Cuando los argumentos son variables, basta con asignarles un nombre.
En ocasiones además se establece el tipo de variable (Single, Double, etc).
Cuando se llama a ese procedimiento desde Excel, se puede poner directamente
el valor de una celda.
Por ejemplo, las funciones vistas para el cálculo de la prima de una opción
de compra (call):
Function BScall(S, X, r, t, sigma)
'obtiene el valor de una opción call europea sobre acciones
que no pagan dividendo
d1 = (Log(S / X) + (r + 0.5 * sigma ^ 2) * t) / (sigma *
Sqr(t))
d2 = d1 - sigma * Sqr(t)
Nd1 = Application.NormSDist(d1)
Nd2 = Application.NormSDist(d2)
BScall = S * Nd1 - X * Exp(-r * t) * Nd2
End Function

En este caso, no se especifica el tipo de variable para S, X, r, t y sigma,


por lo que por defecto son variables Variant. Se podrían haber fijado como
variables Double y el resultado de la Function también como variable Double:
Function BScall(S As Double, X As Double, r As Double, t As
Double, sigma As Double) As Double
Para llamar a estar función desde Excel, basta con incluir 5 celdas
separadas por puntos y comas:
=BScall(A1;A2;A3;A4;A5)

41
 
 

Pasar un rango como argumento en Function o Sub


La mayor parte de funciones de Excel requieren pasar uno o varios rangos
de datos con los que se ejecutarán los cálculos. Por ejemplo, la función =SUMA()
requiere pasar el rango que contiene los números a sumar. Cuando se requiere
pasar un rango de celdas como argumento a una Function o Sub de VBA, se
utiliza el objeto Range que se asigna a una variable. Esa variable se convierte
en el objeto contenedor del rango dentro del código. Dicho objeto puede ser un
vector fila o columna, o una matriz. En el ejemplo que se muestra abajo, le
asignamos a la variable R el objeto rango de celdas (Range).
Dentro del procedimiento se pueden utilizar propiedades de los objetos,
como es el caso de EntireRow si los datos están en forma de columna y
EntireColumn si los datos están en forma de fila. Se puede trasvasar los valores
del rango a una matriz de dos dimensiones de VBA. En el ejemplo, copiamos el
contenido del rango R a la matriz ajo.
Por ejemplo, deseamos pasar a la función “hola” una fila de datos (rango
A2:H2) para que VBA realice un cálculo con sus elementos. Además convertimos
la fila de datos que compone el rango en la matriz “ajo(1 fila, n columnas)”:

Function hola(R As Range)


'asignamos a nn el nº columnas del rango fila R:
nn = R.EntireColumn.Count
'asignamos al vector ab todos los elem del rango:
ab = R.Value
'asignamos a pq el 3er elemento del rango original:
pq = R(3)
For j = 1 To nn
cd = cd + Sqr(ab(1, j)) 'suma raíz de elementos en cd
(…)
Next j
hola = cd 'asignamos valor de cd a Function
(…)
End Function

Para llamar a estar función desde Excel, por ejemplo, haríamos:


=hola(A2:H2)
En este ejemplo devolvería el valor de la suma de raíces cuadradas de los
elementos del rango.

42
 
 

Interactuando: MsgBox e InputBox

 La función Msgbox(texto, botones_e_icono, título)


Muestra un mensaje en un cuadro de diálogo, espera a que el usuario
haga clic en un botón y devuelve un valor entero (tipo Integer) correspondiente
al botón elegido por el usuario. Los tres argumentos de la función son, en primer
lugar el texto que aparece en el cuadro y en tercer lugar el título. El segundo
argumento es un valor (botones_e_icono) que especifica a VBA cuáles son los
botones a mostrar (pueden aparecer los botones Si, No, Aceptar, Anular,
Reintentar, Cancelar) y el icono visible (Exclamación, Interrogación, Información,
Error). VBA sugiere unas constantes que toman los distintos valores posibles.
En el ejemplo siguiente la constante vbYesNo especifica que aparecerá el
botón “Si” y el botón “No”, la constante vbCritical implica que hasta que no se
seleccione uno de esos dos botones, no se podrá trabajar en otra ventana. La
constante vbDefaultButton2 establece como botón por defecto (al que irá en
primer lugar el cursor) el botón 2.

Sub Macro1()
Mensaje = "¿Desea continuar?" ' Define el mensaje.
Estilo = vbYesNo + vbCritical + vbDefaultButton2 'Define
botones
Título = "Demostración de MsgBox" ' Define el título
Respuesta = MsgBox(Mensaje, Estilo, Título)
If Respuesta = vbYes Then ' El usuario eligió el botón Sí.
MiCadena = "Sí" ' Ejecuta una acción.
Else ' El usuario eligió el botón No.
MiCadena = "No" ' Ejecuta otra acción.
End If
End Sub

 La función InputBox(texto, título, por defecto)


Muestra un mensaje en un cuadro de diálogo, espera que el usuario
escriba un texto o haga clic en un botón y devuelve un tipo String con el contenido
del cuadro de texto.
Sub Entrar_Valor()
ActiveSheet.Range("A1").Value = InputBox("Introduzca un texto
para la celda A1", "Entrada de datos")
End Sub

43
 
 

Estructuras de decisión (condicionales)

Las instrucciones condicionales evalúan si se cumple una condición y


especifican las instrucciones a ejecutar en función del resultado.

 Instrucciones If ... Then: entre las instrucciones “If condición Then” y “End If”
se sitúan una secuencia de instrucciones que sólo se ejecutarán en el caso de
que se cumpla la condición o prueba lógica especificada en el “If condición Then”.
La estructura es:
If condición Then
Serie de instrucciones (sólo se ejecutan si se cumple la condición)
End If
Alternativamente se puede utilizar:
If condición Then Serie de instrucciones separadas por “:” (no requiere End If)

Instrucción
precedente

NO
Prueba lógica If condición Then

SI
Instrucciones que se ejecutan si se cumple
Secuencia de
la condición
instrucciones

End If
End If

Instrucción
siguiente

Esta estructura básica se puede hacer más compleja con el uso de la


instrucción “Else”. En el caso de que la condición especificada en el “If condición
Then” se cumpla, se ejecutan las instrucciones que se encuentran entre dicha
instrucción y la instrucción “Else” y a continuación el programa salta a la
instrucción que aparece debajo del “End If”. En el caso de que la condición no
se cumpla, la ejecución del programa salta a la línea siguiente al “Else”.

44
 
 

La estructura es:
If condición Then
Serie 1 de instrucciones (se ejecutan en caso de que se cumpla la condición)
Else
Serie 2 de instrucciones (se ejecutan si no se cumple la condición)
End If
Esquema del If…Then…Else:

Instrucción
precedente

NO 
Prueba lógica If condición Then

SI
Instrucciones que se ejecutan si se cumple
Secuencia de
la condición
instrucciones

Else
Else

Instrucciones que se ejecutan si NO se


Secuencia de cumple la condición
instrucciones

End If
End If

Instrucción
siguiente

Además con el uso de “ElseIf condición Then” se pueden añadir más


condiciones a la inicial.
La estructura es:
If condición1 Then
Serie 1 de instrucciones (se ejecutan si se cumple la condición 1)
ElseIf condición2 Then
Serie 2 de instrucciones (se ejecutan si se cumple la condición 2)
Else
Serie 3 de instrucciones (se ejecutan si no se cumplen las condiciones
anteriores)
End If

45
 
 

Ejemplo: Bonificación por ventas (Uso de condicionales)


Si el rendimiento es del tipo 1 la variable bonificación toma un valor del
10% del salario, si es del tipo 2 la bonificación es del 9% del salario, si es del tipo
3 o superior la bonificación es del 7%, y en caso contrario (el tipo de rendimiento
no toma ninguno de los valores anteriores) la bonificación es cero.
Function Bonificación(tipo, salario)
If tipo = 1 Then
Bonificación = salario * 0.1
ElseIf tipo = 2 Then
Bonificación= salario * 0.09
ElseIf tipo >= 3 Then
Bonificación = salario * 0.07
Else
Bonificación = 0
End If
End Function

Ejemplo: Comisión por objetivos en ventas (Uso de condicionales)


Los empleados de una empresa obtienen una comisión variable sobre las
ventas alcanzadas en el mes. La comisión sigue una escala con varios tramos:
ventas inferiores a 10.000€ (8%), entre 10.000 y 20.000€ (10,5%), superiores a
20.000€ (12%).
En ejemplo sencillo permite resolverlo de varias formas a partir de
funciones de Excel. Quedaría como sigue:
A B C D
1 Escala com. por ventas
2 Ventas (>=) Porc.Com.
3 0 8%
4 10000 10,5%
5 20000 12%
6
7 Empleado Ventas Comisión
8 1 25000 3000
9 2 9999 799,92
10 3 10000 1050

C8: =B8*SI(B8<$A$4;$B$3;SI(B8<$A$5;$B$4;$B$5))
Alternativamente, podríamos haber utilizado una función de búsqueda:
C8: =B8*BUSCARV(B8;$A$3:$B$5;2;1)
En este apartado, nos resulta de interés implementarlo mediante la
creación de una nueva función en VBA. Así, creamos la función Com. Podemos

46
 
 

empezar a escribir debajo del End Function de la anterior función escrita en


el módulo.

Function Com(vtas)
'devuelve la comisión por ventas
If vtas < 0 Then
Com = 0
ElseIf vtas < 10000 Then
Com = 0.08 * vtas
ElseIf vtas < 20000 Then
Com = 0.105 * vtas
Else
Com = 0.12 * vtas
End If
End Function

C8: =com(B8)

Ejemplo: Compra de casa (Condicionales y llamada a otros Sub)


Para cambiar la ejecución de un procedimiento a otro se escribe el nombre
del procedimiento de destino incluyendo todos los argumentos requeridos. Se
puede utilizar, aunque no es necesario, la instrucción Call. Si no se emplea
Static, el valor de las variables locales no se conserva entre distintas llamadas.
Sub Principal()
'Dos posibilidades de cambiar al procedimiento "CalcuCasa"
CalcuCasa 99800, 43100
Call CalcuCasa(380950, 49500)
End Sub

Sub CalcuCasa(precio As Single, salario As Single)


If 2.5 * salario <= 0.8 * precio Then
MsgBox "No puede permitirse esta casa."
Else
MsgBox "Esta casa está a su alcance."
End If
End Sub

 Estructuras IF anidadas
La instrucción If puede utilizarse como parte de las instrucciones incluidas
dentro de otro If. Es decir, dentro de una estructura if puede ir otra, y dentro de
esta otra, y otra... A esta estructura de programación se le denomina If anidado.

47
 
 

Ejemplo: Comparación valores de dos celdas (If anidados)


Se comparan los valores de la celda A1 y A2 de la hoja activa. Si son
iguales, se escribe en A3 este texto: "Los valores de A1 y A2 son iguales". Si el
valor de A1 es mayor que A2, se escribe "A1 mayor que A2", y en caso contrario,
se escribe "A2 mayor que A1".
Sub Anidados()
If Range("A1").Value = Range("A2").Value Then
Range("A3") = "Los Valores de A1 y A2 son iguales"
Else
If Range("A1").Value > Range("A2").Value Then
Range("A3").Value = "A1 mayor que A2"
Else
Range("A3").Value = "A2 mayor que A1"
End If
End If
End Sub

Observe que la segunda estructura If..Else..End If queda dentro del Else


de la primera estructura. Esta es una regla general, un End If siempre cierra el
último If ( o Else) abierto.

 Instrucciones Select Case


Se trata de una estructura condicional en la que la condición sólo puede
consistir en que una variable o una celda tome determinados valores. Se trata
de una alternativa a la instrucción If…Then. Mientras que las instrucciones
If...Then pueden utilizar condiciones más complejas e incluso especificar una
condición distinta para cada instrucción ElseIf, la instrucción Select Case
compara únicamente el valor de la variable que evalúa al comienzo de la
estructura de control.
La estructura es:
Select Case variable_a_evaluar
Case valor 1
Serie 1 de instrucciones (se ejecutan si la variable toma este valor)
Case valor 2
Serie 2 de instrucciones (se ejecutan si la variable toma este otro valor)
Case Else
Serie 3 de instrucciones (se ejecutan si no toma ningún valor anterior)
End Case

48
 
 

Ejemplo: Bonificación por ventas (Uso de condicional Select Case)


El ejemplo de la bonificación en el salario se podría formular utilizando la
instrucción Select Case:
Function Bonificación(rendimiento, salario)
Select Case rendimiento
Case 1
Bonificación = salario * 0.1
Case 2, 3
Bonificación = salario * 0.09
Case 4 To 6
Bonificación = salario * 0.07
Case Is > 8
Bonificación = 100
Case Else
Bonificación = 0
End Select
End Function

Estructuras de bucles

Las estructuras de bucles sirven para ejecutar un grupo de instrucciones


de forma repetitiva. Existen múltiples opciones de bucles para lograr el mismo
objetivo. Existen tres tipos de construcciones:
1. Un bucle con la condición al principio (top-checking loop): la condición se
comprueba antes de que ocurra nada más. Las instrucciones a realizar no
se ejecutan si la condición no se cumple a la entrada del bucle.
2. Un bucle con la condición al final (bottom-checking loop): la condición del
bucle se comprueba después de realizar las instrucciones de dentro del
bucle. Las instrucciones se ejecutarán al menos una vez.
3. Sin condición inicial o final. Dentro del bucle debe existir un condicional
que permita salir del bucle. En caso contrario tendríamos un bucle infinito.

 Instrucciones For...Next
Para repetir un bloque de instrucciones enmarcadas dentro del
“For…To…” y el “Next” un número determinado de veces. Estos bucles usan una
variable contador cuyo valor se incrementa (o se reduce) desde el valor
especificado como inicial hasta el valor final cada vez que se ejecuta la secuencia
de instrucciones comprendidas dentro del bucle. Por defecto, la variable

49
 
 

contador aumenta en una unidad cada vez que se llega a la instrucción Next
salvo que se especifique una variación distinta añadiendo “Step variación”.
La estructura básica es:
For contador = número_inicial To número_final (Step variación)
Serie de instrucciones
Next

Ejemplo: Números pares (bucle For-Next)


Este código llena el rango de celdas A1:A5 con valores pares
consecutivos empezando por el 2.
Sub Pares()
Dim Fila, i As Integer
For i=2 To 10 Step 2
ActiveSheet.Cells(Fila,1).Value = i
Fila = Fila+1
Next i
End Sub

Ejemplo: Cuartiles (bucle y rango como variable)


Este ejemplo calcula los cuartiles de una base de datos extraída de un
rango de celdas que en la hoja de cálculo “Hoja1” se le ha asignado el nombre
“datos”. Muestra los resultados uno a uno en una secuencia de cuadros de
diálogo.
A4: =ENTERO(ALEATORIO()*100) , números aleatorios con distribución
uniforme entre 0 y 1 que multiplicamos por 100 (para que fluctúen entre 0 y 100
y redondeamos a números enteros.
Copiamos en rango A4:A203
Copiamos y pegamos como valores Alt + O + V)
Para asignar el
nombre “datos” al rango
seleccionado, pulsamos
“Asignar nombre” en la
ficha “Nombres
definidos” de la ficha
Fórmulas.

50
 
 

La hoja podría quedar como sigue:


A B C D
1 Cuartiles
2
3 200 extracciones nº aleatorios uniformes
4 26
5 58
… … … … …
203 70

Sub Cuartiles()
Dim datos As Variant
‘asignamos el contenido del rango “datos” en el array datos
datos = Worksheets(“Hoja1”).Range(“datos”)
For i = 0 To 4
cuart = Application.Quartile(datos, i)
MsgBox "El cuartil número " & i & " es " & cuart
Next
End Sub

 Intrucciones Do...Loop
Ejecutan un bloque de instrucciones un número indefinido de veces.
Después de la instrucción inicial “Do” o de la final “Loop” se suele añadir “While
condición” o “Until condición”. En el caso del While, la secuencia de
instrucciones se repiten “mientras” se cumpla la condición y se sale del bucle
cuando ya no se cumple. En el caso del Until, la secuencia de instrucciones se
repiten “hasta que” se cumpla la condición, momento en que se sale del bucle.
La condición While o Until pueden ir al principio, al final o dentro del bucle.
En este tipo de bucle existen un buen número de estructuras posibles:
Do While condición
Secuencia de instrucciones (se ejecutan si se cumple la condición)
Loop
También es posible:
Do Until condición
Secuencia de instrucciones (se ejecutan mientras no se cumpla la condición)
Loop
Otra posibilidad:
Do
Secuencia de instrucciones (se ejecutan indefinidamente hasta que se
cumpla la condición especificada en el If…Then)
If condición Then Exit Do
Loop

51
 
 

Ejemplos: Contar de 20 a 10 (distintas opciones Do-Loop)


Sub ComprobarWhile()
contador = 0
miNum = 20
Do
miNum = miNum - 1
contador = contador + 1
Loop While miNum > 10
MsgBox "El bucle se ha repetido " & contador & " veces."
End Sub

Sub CompPrimeroUntil()
contador = 0
miNum = 20
Do Until miNum = 10
miNum = miNum - 1
contador = contador + 1
Loop
MsgBox "El bucle se ha repetido " & contador & " veces."
End Sub

Sub EjemploSalida()
contador = 0
miNum = 20
Do
miNum = miNum - 1
contador = contador + 1
If miNum < 10 Then Exit Do
Loop
MsgBox "El bucle se ha repetido " & contador & " veces."
End Sub

 Intrucciones While...Wend
Se trata de una versión limitada de las anteriores Do…Loop. Ejecutan un
bloque de instrucciones mientras una condición sea cierta. Como limitación
importante es que no existe un “Exit While”.
Única estructura posible:
While condición
Secuencia de instrucciones (se ejecutan si se cumple la condición)
Wend

52
 
 

Ejemplo: Celda vacía (Do-Loop y condiciones)


Este código se puede incorporar a otros procedimientos o funciones.
Cuando un procedimiento sitúa la celda activa en una determinada posición, por
ejemplo, en la celda A3, siempre que se ejecute el código, éste empezara a hacer
operaciones desde esa celda. Esto puede tener consecuencias no deseadas ya
que la segunda o ulterior vez que ejecute la macro escribirá sobre los resultados
de las ejecuciones anteriores. Una solución es observar cual es la primera celda
vacía disponible y cambiar en la instrucción ActiveSheet.Range("A3").Activate ,
la referencia A3 por la que corresponde a la primera celda vacía de la columna
A. El siguiente código recorre todas las filas desde A3 hasta encontrar una vacía
y la convertirá en celda activa para que la ejecución del macro comience a partir
de ella.

Sub CeldaVacia()
WorkSheets("Hoja7").Activate
ActiveSheet.Range("A3").Activate
Do While Not IsEmpty(ActiveCell)
ActiveCell.Offset(1,0).Activate
Loop
. . .
End Sub

Otra alternativa sin uso de bucles podría ser:


Sub CeldaVacia()
Worksheets("Hoja7").Range("A3").Activate
n = ActiveCell.CurrentRegion.EntireRow.Count
Range("A3").Offset(n, 0).Activate
. . .
End Sub

53
 
 

Ejemplo: Utilizando bucles (distintas alternativas)


Crear un listado con los nombres de 100 clientes utilizando VBA. En la
primera columna del listado mostraremos el número de orden y en la segunda
su nombre que responderá al formato “Cliente_ORDEN” (es decir, cliente_1,
cliente_2, ... ). El listado comienza en la celda B3. En la resolución utilizamos un
contador que nombramos “n”.

Idea básica:

INICIO

n=0

n=n+1

Celda (fila n, columna B) = n


Celda (fila n, col. C9 = “Cliente_” & n

NO
¿n = 100?

SI

FIN

Soluciones alternativas:
1. Sin utilizar ninguna instrucción de bucle.
Utilizamos una “etiqueta”, esto es, una línea que contiene una palabra
seguida de dos puntos (:). VBA omite en su ejecución esta línea pero desde otra
instrucción podemos desplazar la ejecución a dicha línea mediante la instrucción
“GoTo nombre_etiqueta”.

Sub BUCLEETIQUETA()
n = 0
etiqueta:
n = n + 1
Cells(n + 2, 2).Value = n
Range("C" & n + 2).Value = "Cliente_" & Format(n, "000")
If n < 100 Then GoTo etiqueta
End Sub

54
 
 

2. FOR - NEXT
Sub BUCLEFOR_NEXT()
For n = 1 To 100
Range("B" & n + 2).Value = n
Cells(n + 2, 3).Value = "Cliente_" & Format(n, "000")
Next
End Sub

3. DO - LOOP
Sub BUCLEDO_LOOP()
Do
n = n + 1
Cells(n + 2, 2).Value = n
Range("C" & n + 2).Value = "Cliente_" & Format(n, "000")
If n = 100 Then Exit Do
Loop
End Sub

4. DO - LOOP UNTIL
Sub BUCLEDO_LOOPUNTIL()
Do
n = n + 1
Range("B" & n + 2).Value = n
Cells(n + 2, 3).Value = "Cliente_" & Format(n, "000")
Loop Until n = 100
End Sub

5. DO - LOOP WHILE
Sub BUCLEDO_LOOPWHILE()
Do
n = n + 1
Cells(n + 2, 2).Value = n
Range("C" & n + 2).Value = "Cliente_" & Format(n, "000")
Loop While n < 100
End Sub

Ejemplo: Factorial de un número (II) (Uso de bucles)


Modificamos el código de Factorial de un número (I) para evitar llamar a
funciones de Excel. Resolvemos el problema mediante un bucle:
Sub Factorial2()
num = InputBox("Introduzca un número", "Calcular Factorial")
If num < 1 Then
fac = "Número negativo"
ElseIf num > 160 Then
fac = "Número demasiado alto"
Else
fac = num
For n = num - 1 To 1 Step -1
fac = fac * n
Next
End If
MsgBox "El factorial de " & num & " es " & fac
End Sub

55
 
 

- Bucles con manejo de rangos (For Each)


Esta estructura permite repetir un bloque de instrucciones para cada uno
de los objetos, por ejemplo formularios (ventanas creadas desde VB), de una
colección o para cada elemento de una matriz. VB asigna valor automáticamente
a una variable cada vez que se ejecuta el bucle.

Ejemplo: For Each (con matrices)


A cada elemento de la matriz “Hola”, matriz que definimos compuesta por
10 elementos que tomarán valores enteros (instrucción Dim), le asignamos el
valor de un contador (n) que se incrementa en una unidad tras cada iteración.
Así Hola(1) toma valor 1, Hola(2) toma valor 2, … Nota que el bucle se ejecuta
en tantas ocasiones como dimensiones tenga la matriz.
Dim Hola(10) As Integer, n As Variant
For Each n In Hola
Hola(n) = n
Next n

Ejemplo: For Each (con objetos)


En este ejemplo se da la posibilidad de cambiar el nombre de cada una
de las hojas de cálculo del libro de trabajo actual.

Sub CambiarNombre ()
Dim Nuevo As String
Dim Hoja As WorkSheet
For Each Hoja In WorkSheets
Nuevo = InputBox("Introduzca el nuevo nombre para la _
hoja " & Hoja.Name,"Nombrar Hojas")
If Nuevo <> "" Then Hoja.Name = Nuevo
Next
End Sub

56
 
 

1.3.5. Controles y eventos

Controles en la hoja Excel


Los controles que proporciona el Editor de VBA
para incluir en los formularios (FRM) pueden también
utilizarse directamente en la hoja de cálculo.
Para insertar controles en la hoja hay que pulsar
Insertar en la ficha Controles de la ficha Programador.
Por ejemplo, se puede dibujar un Cuadro de
Texto y una Etiqueta que lo acompaña, posicionar una
Barra de Desplazamiento, etc. Sin embargo, los
Botones y las Listas son los controles más útiles dentro de una hoja de cálculo.
Un Botón permite invocar un procedimiento cuando el usuario pulse sobre él.
Dependiendo de la versión de Excel, podemos encontrar:

- Casilla de verificación: opción que puede activarse o desactivarse.

- Cuadro de texto: cuadro en el que puede escribirse texto.

- Botón de comando: botón que inicia una acción cuando se hace clic en él.

- Botón de opción: selecciona una opción entre un grupo de opciones.

- Cuadro de lista: cuadro que contiene una lista de elementos.

- Cuadro combinado: cuadro de texto que contiene un cuadro de lista


desplegable. Puede escribirse un texto o seleccionarse una opción en la lista.

- Botón de alternar: permanece presionado al hacer clic y se libera cuando


se vuelve a hacer clic.

- Botón de número: puede adjuntarse a una celda o a un cuadro de texto para


aumentar o disminuir su valor.

- Barra de desplazamiento: para desplazarse a través de un rango de valores.

- Rótulo: texto agregado a una hoja de cálculo o formulario para proporcionar


información.

- Imagen: incrusta una imagen en un formulario.

- Cuadro de grupo: un borde y un rótulo que agrupa controles relacionados.

- Barra de tabulaciones: contiene una colección de una o más fichas.

57
 
 

- Página múltiple: contiene una colección de una o más páginas. Cada objeto
Page de un control MultiPage es un formulario que contiene sus propios
controles.

- RefEdit: muestra la dirección de un rango de celdas que haya introducido


o seleccionado el usuario en una o varias hojas de cálculo.

- Controles adicionales: lista de los controles ActiveX adicionales.

La forma de configurar un control dentro de la hoja de cálculo o desde el


Editor de VBA es diferente. En la hoja de cálculo, se pulsa con el botón
secundario del ratón sobre el control en Modo Diseño, y se selecciona la opción
Propiedades o Formato de control.

EJEMPLO “Consulta resultados de una opción call según Black-Scholes


(II)” (Uso de controles Lista en la hoja Excel)

Previamente hemos creado funciones para obtener el valor de la prima de


una opción call europea según la fórmula de Black-Scholes. En este ejemplo
llamamos a esa función para elaborar la base de datos de las columnas D y E, y
buscamos unos resultados concretos. Tratamos de encontrar con dos métodos
alternativos el valor de la call si la volatilidad anual de la acción es del 20%.

Solución: 

A B C D E
1 Valor call s/ BS
2 Datos: Volatilidad Call
3 S (precio acción) 20 15% 1,82
4 X (precio ejercicio) 19 16% 1,86
5 T (plazo h. ejercicio) 0,5 17% 1,90
6 r (tipo interés) 6% 18% 1,95
7 19% 1,99
8  (Volatilidad): 20% 2,04
9 Call: 2,04 21% 2,08
10 22% 2,13
11 Posición en lista: 6
 

58
 
 

Una vez dibujado el control


Lista y ajustado su tamaño, pulsamos
el botón secundario del ratón y
elegimos Formato de control.
En la ventana emergente
seleccionamos la ficha Control e
introducimos el rango de celdas de la
hoja donde se encuentra la lista en el Rango de entrada (D3:D10). La celda
establecida en Vincular con la celda (B11 en este caso) es la celda en la que se
almacena la posición del elemento de la lista seleccionado por el usuario.

E3: =BScall($B$3;$B$4;$B$6;$B$5;D3), llama a nuestra función BScall.

Copiar celda B3 hacia abajo.

B9: =INDICE(E3:E10;B11), devuelve el elemento de la base de datos que está


en la posición marcada por la celda B11.
Nota: la celda B11 no contiene ninguna función.

EJEMPLO “Elevar al cuadrado un rango de valores” (Uso de controles


Botón de comando en la hoja Excel)

Creamos un botón, que al ser pulsado por el usuario, ejecuta un


procedimiento que eleva al cuadrado el rango de celdas activas.

Solución: 

Dibujamos el botón. Según la versión, aparece un cuadro de diálogo que


nos permite asociarlo a un macro existente o a uno nuevo con nombre
“Botón1_Haga_clic_en”. En el menú contextual que aparece al pulsar el botón
derecho del ratón podemos cambiar su nombre en la opción “Modificar texto”.
Si asignamos un nuevo macro al botón, en X2010 se abre una ventana en
VBA con el siguiente código:

59
 
 

Sub Botón1_Haga_clic_en()

End Sub
En versiones anteriores de Excel, había que hacer un doble click sobre el
botón en Modo Diseño para que automáticamente apareciera:
Private Sub CommandButton1_Click()

End Sub
En cualquier caso, podemos escribir una llamada a otra función o
procedimiento o directamente escribir el código:
For Each cell In Selection.Cells
cell.Value = cell.Value ^ 2
Next cell

Controles en formularios de VBA


Una vez que se crea un formulario (menú
Insertar – UserForm) o se abre uno de los existentes,
aparece la ventana “Cuadro de herramientas” donde
se pueden dibujar en el formulario los controles con la
forma y aspecto deseados.
Según la versión de Excel tienen asignados
nombres en inglés (CheckBox, TextBox, CommandButton, OptionButton,
ListBox, ComboBox, ToggleButton, SpinButton, ScrollBar, Label, Image, Frame,
TabStrip, MultiPage y RefEdit) o en español.

Eventos
Puede ser de mucha utilidad que un evento desencadene una macro para
ejecutar una tarea. Los eventos están siempre asociados con objetos, como
puede ser el caso de un control, una hoja de cálculo o un libro. Ejemplos de
eventos son: pulsar sobre un botón o celda, situar el cursor sobre el elemento,
quitar el cursor, presionar una tecla, que se produzca un error, etc. Algunos de
estos eventos los comentamos a continuación:
 Click (aplicado a un control): Lo vemos con un ejemplo. Creamos un botón de

comando en la hoja de cálculo del ejemplo anterior para que al pulsar sobre
él se ejecute la macro grabada.
 BeforeDoubleClick (aplicado a una hoja de cálculo):

60
 
 

Private Sub Worksheet_BeforeDoubleClick(ByVal Target As


Excel.Range, Cancel As Boolean)
MsgBox "Hizo doble clic en la celda " & Target.Address
Cancel = True
End Sub
Este evento se desencadena cada vez que el usuario hace doble clic en
una celda de la hoja de cálculo. El parámetro Target se incorpora a la macro para
que el programador sepa en qué celda se hizo doble clic. El argumento Cancel
tiene un valor predeterminado de False pero se puede cambiar a True en el
código. Al fijar Cancel como True se cancela la acción predeterminada para el
evento. En este caso, la acción predeterminada al hacer doble clic en una celda
es cambiar al modo de edición para esa celda (como si se pulsa F2). Debido a
que Cancel está establecido como True, esto no ocurrirá. Si desea obtener la
acción predeterminada, quite la línea Cancel=True.
 Change (aplicado a una hoja de cálculo). Se desencadena cada vez que el
usuario escribe un valor nuevo en una celda.
Private Sub Worksheet_Change(ByVal Target As Excel.Range)
MsgBox "Esta hoja cambió en la celda " & Target.Address
End Sub

 BeforeClose (aplicado a un libro): se puede utilizar este tipo de eventos para


realizar tareas de limpieza antes de guardar o cerrar un archivo.
Sub Workbook_BeforeClose(Cancel As Boolean)
a = MsgBox("¿Desea cerrar el libro?", vbYesNo)
If a = vbNo Then Cancel = True
End Sub
En este ejemplo, se pide al usuario que cierre el archivo
independientemente de si lo guardó previamente o no.

 Activate (aplicado a una hoja de cálculo): para situar el cursor cuando se


activa la hoja.
Private Sub Worksheet_Activate()
ActiveSheet.Range("a1").Select
End Sub
 Los eventos asociados a cada
control, a la hoja de cálculo o al
libro se pueden visualizar en el
Editor de VB:

61
 
 

1.3.6. Miscelánea

Control de errores
La instrucción On Error activa una rutina de control de errores y especifica
la ubicación de la misma en un procedimiento.
Sintaxis: On Error GoTo línea, On Error Resume Next.
Sub InicializarMatriz(Var1, Var2, Var3, Var4)
On Error GoTo ControlErrores
. . .
Exit Sub
ControlErrores:
. . .
Resume Next
End Sub

Algunas funciones básicas

- Abs (ꞏ): valor absoluto de un número.

- Conversión a un tipo de datos específico: CCur(ꞏ), CDate(ꞏ), CDbl(ꞏ), CDec(ꞏ),


CInt(ꞏ), CLng(ꞏ), CSng(ꞏ), CStr(ꞏ), CVar(ꞏ).
- Date: fecha actual del sistema.

- DateSerial(año, mes, día): devuelve una Variant para un año, mes y día
especificados.
DateSerial(1990 - 10, 8 - 2, 1 - 1)
- Day(fecha), Month(fecha), Year(fecha)

- Int(ꞏ): parte entera de un número.

- Format(expresión, formato): da un formato a la expresión.

- InStr(inicio, string1, string2): devuelve una Long que especifica la posición de


la primera aparición de una cadena en otra.
Celda ="$F$10" ' Cadena en la que se busca.
MyPos = Instr(2, Celda, "$") ' Devuelve un valor 3
- Left(string, longitud): devuelve una String que contiene un número especificado
de caracteres del lado izquierdo de una cadena.
UnaCadena = "Hola Mundo" ' Define la cadena.
MiCadena = Left(UnaCadena, 3) ' Devuelve "Hol".
- Len(string): devuelve una Long que contiene el número de caracteres en una
cadena.

62
 
 

MiCadena = "Hola a todos" ' Inicializa la cadenas.


MiLong = Len(MiCadena) ' Devuelve 11.
- Quitar espacios: devuelve una String que contiene una copia de una cadena
determinada sin espacios a la izquierda (LTrim), sin espacios a la derecha
(RTrim) o sin espacios ni a la derecha ni a la izquierda (Trim).

- Mid(string, inicio, longitud): devuelve una String que contiene un número


especificado de caracteres de una cadena.
MiCadena = "Demostración función Mid"
Palabra = Mid(MiCadena, 21, 3) ' Devuelve "Mid".
- Right(string, longitud): devuelve una String que contiene un número
especificado de caracteres del lado derecho de una cadena.

- Rnd(ꞏ): devuelve una Single que contiene un número aleatorio.

- Str(ꞏ): devuelve en una String la representación de cadena de un número.


MiCadena = Str(-459.65) ' Devuelve "-459,65"

Algunos operadores

- &: concatena dos cadenas de texto. Ejemplo: resultado = expresión1 &


expresión2
- *, +, -, /, \ (división convirtiendo el resultado a entero), ^, =, Mod (división
devolviendo solo el resto)
- And, Or, Eqv (devuelve verdadero si ambas condiciones son verdaderas o
ambas son falsas), Not, Xor (devuelve verdadero si una condición es verdadera
y la otra falsa o viceversa)

63
 
 

1.4 Aplicaciones financieras

EJEMPLO “Sucesión de Fibonacci” (Trabajo básico con vectores)

La sucesión comienza con los números 0 y 1, y a partir de estos, cada


término es la suma de los dos anteriores. Para obtenerla vamos a trabajar con
un vector que almacena la sucesión.

A B C D E
1 Sucesión de Fibonacci
2 Calcular
3 Elementos 25
4
5 N Fibonacci
6 0 0
7 1 1
8 2 1
9 3 2
10 4 3
… … … … … …
31 25 75025

Nota sobre el código:


1. Borramos datos de extracciones anteriores.
2. Comprobamos que la celda B3 contenga un número, además lo redondeamos a
entero en el caso de que no lo sea.

El código aparece en el Anexo de Soluciones.

64
 
 

EJEMPLO “Valoración de Swaps de tipos de interés (IRS)” (Trabajo básico


con bucles y Solver)

La pata o rama variable de un IRS se obtiene a partir de la predicción de


los tipos al contado a un año que esperamos que se den en el futuro. Dicha
predicción se obtiene a partir de los tipos a plazo implícitos (forward) para plazos
de un año vigentes en el futuro. A su vez los forwards se extraen de los tipos al
contado a distintos plazos obtenidos del interbancario (LIBOR).

Los swaps en su momento inicial tienen valor nulo. Posteriormente en


función de la evolución de los tipos de interés, su valor vendrá dado por la
diferencia neta y actualizada entre los dos flujos de pagos intercambiados
durante el período contractual, en función de la curva cupón cero vigente en cada
momento.

Dado que los flujos a tipo variable no se conocen de antemano, se estiman


previamente a partir de los tipos “forward” implícitos en la curva cupón cero. En
el momento de la emisión el valor de la operación debe ser cero, al objeto de que
ninguna parte se sienta perjudicada. El tipo de interés de la pata fija que
establece un valor inicial del IRS igual a cero se denomina tipo swap.

El tipo forward para el plazo [t1, t2]:

 
1
 1 0 Rt t2
 t 2 t1

1 R   1 R   1  F 
t2 t1 t 2 t1
Ft1 ,t 2    1 
 
2
0 t2 0 t1 t1 ,t 2     ;  t1
 1 0 Rt1 

En el caso del tipo de interés forward para un préstamo a un año que se


otorgará dentro de dos años se calcula a partir de los tipos al contado a tres años
y a dos años:

1 0 R3 3  1 0 R2 2  1  F2,3   


Trabajo a realizar:

A partir de los tipos Libor que aparecen en las columnas A y B de la


siguiente hoja:

1. Obtener en Excel los distintos tipos forward al plazo de un año (col. E).

65
 
 

2. Preparar fórmulas en Excel de la columna I para obtener el valor actual


de la diferencia entre la pata fija (columna G que hace referencia a la celda
H3) y la flotante para cada año (H10:H20 a partir de la columna E). Para
obtener el valor descontado en la columna I se utiliza el tipo al contado
swap correspondiente. (En columna I se obtiene en Excel el valor actual
de la diferencia entre la G y la H para el plazo correspondiente a cada fila)

3. Se puede obtener el tipo swap para 10 IRS con pagos anuales distintos,
simplemente cambiando desde VBA el contenido de la celda H2 a la que
están referidas todas las fórmulas de las columnas G a I. Para cada plazo
(H2), se llama a Solver desde VBA para que cambie el valor de la celda
H3 con objeto que el valor actual total de la operación (celda I20) sea cero.
El resultado se coloca en la fila correspondiente de la columna L.

Nota: todos los cálculos se hacen en la hoja Excel, salvo la optimización que se
ejecuta desde VBA.

4. Se puede realizar una nueva versión de la hoja que utilice un optimizador


en VBA que evite llamar a Solver.

Ejemplo resuelto para un IRS a 2 años:

El código aparece en el Anexo de Soluciones.

66
 
 

EJEMPLO: Números primos


Elaboramos una hoja similar a la anterior para obtener una lista con un
número determinado de números primos. Ese número se fija en la celda B2. El
código borra los posibles datos de extracciones previas y realiza la extracción. A
partir del último número primo calculado, se trata de probar si el número siguiente
es primo o, por el contrario, es divisible por un número primo inferior.

A B C D E F
1 Números primos:
2 Cantidad: 10
3 Extraer
4 Orden Nº primos
5 1 1
6 2 2
7 3 3
8 4 5
9 5 7
… … … … … … …
14 10 23

El código aparece en el Anexo de Soluciones.

EJEMPLO: Triángulo de Tartaglia o Pascal


En la valoración binomial de opciones se utilizan árboles binomiales para
simular los posibles precios que puede tomar el activo subyacente de la opción
a lo largo de un determinado número de periodos. Si el precio del activo
subyacente al principio de un periodo es S, al final del periodo puede tomar
únicamente dos posibles valores, uS o dS, siendo u un factor de crecimiento y d
de decrecimiento. Para que no se den oportunidades de arbitraje, u debe ser
mayor a erꞏt, donde r es el tipo de interés libre de riesgo para la amplitud del
periodo (t), y d < erꞏt.
El modelo parece muy ingenuo pero haciendo la amplitud de los periodos
lo suficientemente pequeña el modelo binomial converge a la fórmula cerrada de
Black-Scholes.
Los precios finales del activo subyacente después de n periodos (son n+1
precios) se pueden calcular a partir de la siguiente expresión:
Sj = u n - j d j S

67
 
 

donde n es el número de periodos y j es el número de veces que el precio


decrece.
Por su parte, la probabilidad que el precio crezca (se convierta en uS) al
final de un periodo se denota por q, siendo 1-q la probabilidad de que se dé el
nudo inferior (dS).
Para n periodos, la probabilidad de que se produzca un determinado nudo
j se calcula como el número de rutas que llevan a ese nudo por la probabilidad
de subida elevado al número de subidas que llevan a ese nudo por la
probabilidad de bajada elevado al número de bajadas que llevan a ese nudo.

donde el número de rutas se obtiene


!
como combinaciones
! !

El triángulo de Tartaglia
proporciona ese número de
combinaciones. Cada elemento se
obtiene como suma de los dos
valores que tiene arriba. 

Ejemplo:
Se trata de elaborar un programa que obtenga, a partir de un número n de
periodos el triángulo de Tartaglia para n niveles. Se incluye un botón para
ejecutar la macro y otro para borrar los resultados previos.

A B C D E F G H I
1 Triángulo Tartaglia
2 Construir
3 Niveles 9
4 1 Limpiar
5 1 1
6 1 2 1
… … … … … … … …
12 1 8 28 56 70 56 28 8 1
13

El código aparece en el Anexo de Soluciones.

68
 
 

EJEMPLO: Cálculo de los tipos Euribor


El Euribor es el tipo de interés en el mercado interbancario para
operaciones realizadas para un conjunto de plazos establecidos. Los bancos de
máxima solvencia de la UEM se prestan dinero mediante depósitos a plazo en
euros. Los tipos
Euribor a cada plazo
se publican a las
11:00 horas (CET)
con fecha de
liquidación en D+2 y
la convención
Actual/360. El cálculo
diario se hace a partir
de un panel de 20
bancos contribuidores entre los que, a 18/10/2016, se encuentran Belfius, BNP-
Paribas, Deutsche Bank, …, BBVA, Santander, CECABANK, CaixaBank, …,
Unicredit. (ver http://www.emmi-benchmarks.eu/)
Para cada plazo, Thomson Reuters calcula el tipo promedio, redondeado
a tres decimales, después de eliminar el 15% de las mayores cotizaciones y el
15% de las menores.

Ejemplo:
Partiendo de una parrilla de 14 bancos contribuidores y los tipos que
reportan para 7 vencimientos (overnight, 1d, 1w, 1m, 3m, 6m, 1y), calcular los
correspondientes tipos Euribor (EONIA, Euribor a 1 día, 1 semana, 1 mes, 3
meses, 6 meses y 1 año). Calculamos el promedio eliminando el 15% de las
mayores/menores cotizaciones (es decir, los 2 más altas y los 2 más bajas).
Nota: generamos las cotizaciones como números aleatorios uniformes:
- desde Excel: función ALEATORIO()
. desde VBA: función RND()

69
 
 

A B C D E
1 Cálculo de dist. Euribor
2 Calcular
3
4 EONIA Eur1d Eur1w Eur1m Eur3m Eur6m Eur1y
5 EURIBOR(%): 0.467 0.393 0.482 0.559 0.423 0.404 0.416
6
7 Datos Over 1d 1w 1m 3m 6m 1y
8 Banco1 0.243 0.816 0.045 -0.033 0.078 0.362 0.564
9 Banco2 0.057 0.373 -0.018 0.739 0.157 0.514 0.018
… … … … … …
10 Banco14 0.795 0.263 0.637 0.351 0.638 -0.094 -0.055

El código aparece en el Anexo de Soluciones.

EJEMPLO: Valoración de opciones por Black-Scholes utilizando


integración numérica

En los ejemplos analizados al principio del apartado 1.3 sobre valoración


de opciones a partir de la fórmula de Black-Scholes, se recurría a la fórmula de
Excel DISTR.NORM.ESTAND(z) para obtener el valor de la función de
distribución acumulada (CDF) de la normal estándar. En concreto, se utiliza la
instrucción Application.NormSDist para invocar a la función de Excel.
Dicha CDF proporciona la probabilidad acumulada en la distribución
normal estándar hasta el valor de z (d1 en la nomenclatura de Black-Scholes). Se
trata del área debajo de la función de densidad hasta ese valor. Por ejemplo,
para d = -1:
Probabilidad

N(d)

d = -1 0 +1 +2

La función de densidad de la N(0,1) se obtiene como:


x2
1 2
f ( x)  e
2
Mientras que la función de distribución acumulada:
u2
1 x 2
 x  
2 
e du

70
 
 

Ejemplo:
Se trata de modificar el código de las funciones BScall para calcular la
función de distribución acumulada sin necesidad de recurrir a la función de Excel.
Para ello resolvemos la integral por métodos numéricos que calculan
aproximadamente el valor de la integral. Entre los métodos numéricos
alternativos disponibles utilizamos la regla del trapecio.
La regla se basa en aproximar el valor de la integral de f(x) por el de la
función lineal que pasa a través de los puntos (a, f(a)) y (b, f(b)). La integral de
esta función es igual al área del trapecio bajo la gráfica
de la función lineal. Se sigue que

En concreto, analizamos el intervalo [-6, z] y lo dividimos en intervalos de


amplitud 0,1. Creamos la función CDF(z) para calcular la probabilidad acumulada
que, a su vez, llamará a la función PDF(z) para obtener la función de densidad
en cada punto.

Function BScall3(S, X, r, t, sigma)


'obtiene el valor de una opción call europea sobre acciones
que no pagan dividendo
d1 = (Log(S / X) + (r + 0.5 * sigma ^ 2) * t) / (sigma *
Sqr(t))
d2 = d1 - sigma * Sqr(t)
Nd1 = CDF(d1)
Nd2 = CDF(d2)
BScall = S * Nd1 - X * Exp(-r * t) * Nd2
End Function

El código aparece en el Anexo de Soluciones.

Nota: podemos definir la constante pi de dos formas alternativas:


 Const pi = 3.14159265358979
 pi = 4 * Atn(1) ‘Atn calcula el arcotangente de un número

71
 
 

EJEMPLO Optimizador para cálculo del TIR. Aplicable a “Selección de


inversiones”
Este código se puede aplicar a cualquier problema en el que haya que
actualizar flujos de caja. Por ejemplo, a ejercicios de selección de inversiones y
de valoración de bonos y obligaciones.
La subrutina tiene un funcionamiento similar a la función TIR.NO.PER de
Excel aunque subsana su principal inconveniente. Dicha función de Excel
requiere introducir el plazo de cada flujo de caja en días. Para hacer los cálculos,
Excel convierte los días en años dividiendo por 365 días. Esto genera errores
cuando se calcula el TIR de un bono siguiendo la convención de mercado
Actual/Actual. Según este criterio, el plazo en años hasta el primer flujo se
computa como el cociente entre el plazo en días y 365 o 366 días, según el
número real de días del periodo de generación del cupón (si es año bisiesto o
no). Para los restantes flujos, el plazo se obtiene sumando un año cada vez. La
función TIR.NO.PER no permite realizar estos ajustes. Nuestra función miTIR
usa como input el plazo en años, permitiendo de esta forma utilizar el convenio
que el usuario necesite.
Un segundo problema a resolver es la conveniencia de elaborar código
autosuficiente en VBA, es decir, código cuya ejecución no requiera recurrir a
funciones de Excel o al Solver. Por ejemplo, la llamada reiterativa a la aplicación
Solver consume la memoria RAM del ordenador y ralentiza progresivamente la
ejecución del programa.
Con objeto de hacer frente a ambos problemas planteamos ahora el
código necesario para obtener el TIR mediante aproximaciones sucesivas
(prueba y error). Como argumentos a la función pasaremos el rango de plazos
en años (calculados con el convenio o criterio que estimemos oportuno) y el
rango de cuantías.
En este ejemplo planteamos un método muy sencillo que consiste en ir
“barriendo” los posibles valores hasta alcanzar la solución. Es decir, partimos de
un valor inicial reducido para el posible TIR, por ejemplo r = 0. Si el valor actual
de los flujos descontados a ese r es positivo, entonces incrementamos r en pasos
de cuantía incr = 0.01. Con los sucesivos incrementos en r conseguimos reducir
cada vez más el valor actual, hasta que alcance un valor negativo. Ese valor
negativo indica que el TIR es inferior al último r utilizado. Entonces volvemos al

72
 
 

penúltimo r, que nos dará un valor actual positivo, y reducimos el tamaño del
paso, por ejemplo a incr = 0.1. Volvemos a incrementar r hasta que se alcance
un valor actual negativo y retornamos al último r que daba un valor actual
positivo. Repetimos este proceso hasta llegar a un valor actual lo suficientemente
cercano a cero. Por ejemplo, podemos fijar un umbral de error de +/- 0.000001
para parar la ejecución del código.

Function miTIR(Rplazos as Range, Rcuantias as Range) as Double


Dim tir as double
tir = 0
Call calcularTIR(Rplazos, Rcuantias, tir)
miTIR = tir
End Function

El código aparece en el Anexo de Soluciones.

73
 
 

EJEMPLO Optimizador para la volatilidad implícita de una opción


En la valoración de opciones europeas sobre acciones que no pagan
dividendo es habitual plantearse el cálculo de la volatilidad implícita de las
acciones a las que la opción se está valorando en el mercado. Es decir, en el
mercado podemos observar la cotización del precio de las acciones S, de la
prima de la opción call c, y el tipo de interés r, y calcular el plazo hasta el ejercicio
de la opción T. La volatilidad implícita  es la desviación típica utilizada en la
fórmula de Black-Scholes para obtener el valor de la prima de la opción c.
El problema se puede solventar fácilmente por prueba y error sabiendo
que la función del precio de la call respecto a  es monótona creciente. A
diferencia del ejemplo para el cálculo del TIR, vamos a emplear otro método de
aproximación a la solución.
Se parte de dos posibles valores que puede tomar . Un valor alto de
100 y un valor bajo de 0. Calculamos cuál es el valor de la prima para un valor
de  promedio entre alto y bajo. Si la prima obtenida es mayor a la real,
entonces reemplazamos el valor de alto por el del promedio entre alto y bajo.
En caso contrario, reemplazamos el valor de bajo por el del promedio entre alto
y bajo. El procedimiento se interrumpe cuando la diferencia entre alto y bajo
es inferior a un umbral de 0.000001.

Function BSvolatilidad(S, X, r, t, c) as Double


...
End Function

El código aparece en el Anexo de Soluciones.

74
 
 

EJEMPLO: Valor en riesgo (VaR, Value-at-risk) a partir de una distribución


no paramétrica

El Value at Risk (VaR) es una medida de riesgo ampliamente utilizada en


los mercados financieros y que centra la regulación de las entidades financieras
en el contexto de Basilea. Existen varias formas de definirlo. Por ejemplo, el Hull
utiliza “el nivel de pérdidas que con una confianza del c% no se excederán en N
días hábiles” o también el “nivel de pérdidas correspondiente al (100-c) percentil
de la distribución del cambio del valor de una cartera en los próximos N días”.
Por su parte, Jorion establece que es “la máxima pérdida sobre un horizonte
temporal objetivo tal que exista una probabilidad prefijada reducida de que las
pérdidas reales sean mayores”.
Así, por ejemplo, si un gestor de carteras tiene un VaR diario de 1 millón
de u.m. con nivel de confianza c = 99%, implica que hay sólo una posibilidad
entre 100 de que se produzca una pérdida diaria superior a 1 millón en
condiciones normales de mercado.
VaR = x euros, Nivel de Confianza = c %, Horizonte Temporal = t días:
- En el c% de los casos la pérdida no
será superior a x € en los próximos t
días.
- Nivel de significatividad (1-c)%:
frecuencia con la que se espera que
ocurra un nivel de pérdidas dado.
Definición más formal:
Sea f(w) la distribución de probabilidad del valor futuro de la cartera, el
VaR (o Wc) se define implícitamente a partir de

Prw  Wc   p  1  c

c   f wdw
Wc

Para distribuciones discretas, el VaR es la menor pérdida que deja un


probabilidad en la cola derecha de, al menos, c.
Ejemplo:
A partir de 254 observaciones diarias de los ingresos diarios de una
entidad financiera se obtiene el VaR para un nivel de confianza del c = 95%. En
primer lugar, se ordenan los ingresos de menor a mayor. En segundo lugar, se
busca la observación cuya probabilidad de sufrir una pérdida mayor sea p = 1 –

75
 
 

c = 5%, es decir, que el número de observaciones que quedan a su izquierda


sea pꞏT = 0,05 ꞏ 254 = 12,7 observaciones. El valor absoluto de las pérdidas
sufridas en esa observación será la máxima pérdida en un día para un nivel de
confianza del 95% (VaR95%).
Si se utilizara una hoja de cálculo de Excel:
1. Se fija un valor del ingreso diario medio y su volatilidad.
2. Si se supone que la variable ingreso diario se distribuye como una normal,
extraemos números aleatorios normales con esa media y desviación
típica.
3. Se ordenar la lista de ingresos simulados (Ficha Inicio – Ordenar y filtrar
– Ordenar de menor a mayor).
4. Se aplica la función =PERCENTIL(datos;0,05).
A partir de código en VBA, y sin recurrir a funciones de Excel o de VBA,
se pide la realización de los siguientes pasos:
1. Simular extracciones de números aleatorios normales.
2. Ordenar los datos a partir de un programa “burbuja”.
3. Obtener el percentil del 5%.

A B C D E
1 Value at Risk
2 Calcular
3 Ingresos diarios: Cálculo del VaR
4 Media: 50 N.Confianza 0.95
5 Desv.típica: 6000 VaR: -10103.94
6 Observ: 254 Excel percentil: -10090.35
7
8 Día Ingreso Ingr.ordenados
9 1 11135.03 -17875.36
10 2 1852.53 -16464.96
… … … … … …

Nota sobre la tabla: los números que aparecen en los rangos B9:B… y D9:D…
son números aleatorios cuyo valor depende de cada extracción. Como
consecuencia el valor del VaR (E5) y el percentil de Excel (E6) varían cada vez
que se ejecuta el macro.

76
 
 

A tener en cuenta:
- La instrucción de VBA Rnd genera números aleatorios uniformes entre 0 y 1.
- Para obtener números aleatorios normales a partir de números uniformes
existen varios métodos. Entre ellos podemos utilizar este:5
1. Se generan dos números v1, v2 en [-1, 1] a partir de una distribución
uniforme en [0, 1].
2∙ 1
2∙ 1
2. Se descartan aquellos pares v1, v2 que no cumplan:
1
3. Se obtienen los números aleatorios z1, z2 mediante la fórmula:

- Otra posibilidad es el método de Box-Muller:


1. Se generan dos números v1, v2 a partir de distribución uniforme en (0, 1].
2. Se obtienen los números aleatorios z1, z2 mediante la fórmula:
2 2

2 2

- Aunque se pide elaborar un programa burbuja para ordenar un vector, VBA


permite ordenar un rango de datos en Excel mediante un código:
Range ("B9:B256").Select
Selection.Sort Key1:=Range("B9"), Order1:=xlAscending, _
Header:=xlYes, OrderCustom:=1, MatchCase:=False, _
Orientation:=xlTopToBottom
 

El código aparece en el Anexo de Soluciones.

                                                            
5
 Otra alternativa sencilla consiste en, dado el Teorema Central del Límite, obtener extracciones de una 
variable aleatoria normal mediante la suma de 12 números aleatorios con distribución uniforme entre 
a=0 y b=1. Esta variable se tipifica para obtener una N(0,1) restando la media que toma valor 6, ya que 
12 µ(X) = 12 ∙ (a+b)/2 = 6, y dividiendo todo por la desviación típica que toma valor 1, ya que 12 2(X) = 
12 ∙ (b‐a)2/12 = 1. 

77
 
 

EJEMPLO “Calculadora de préstamos” (Trabajo con matrices y Formularios)

La calculadora de préstamos en un formulario autosuficiente que permite


al usuario introducir principal, tanto nominal y plazo en años de una operación
de amortización, eligiendo entre pagos mensuales o trimestrales, y entre las
modalidades de amortización: francés, cuotas de amortización constantes y
términos crecientes en progresión geométrica.

Se utiliza un formulario, etiquetas, controles de texto y de opción, y barras


de desplazamiento.

Este es el resultado:

Pasos:

1. Crear las etiquetas con el texto (Labels).

2. Establecer el texto por defecto de las TextBoxes (1000, 5, 2 y 1.01).

3. Dibujar las ScrollBars. La 1 tiene valor mínimo de 1, máximo de 30000


(equivalente a 30%), cambio mayor 1000 y valor 500.6 Por su parte, la 2
tiene valor mínimo de 1, máximo de 40 años, cambio mayor 1 y valor 2.
Haciendo doble click sobre ellas se puede escribir el código:

                                                            
6
 En el caso del ScrollBar1 se recomienda cambiar el valor por defecto del parámetro “delay” (50) y 
dejarlo 0 para hacer más rápido el desplazamiento del tipo de interés. 

78
 
 

Private Sub ScrollBar1_Change()


TextBox2.Text = ScrollBar1.Value / 100
End Sub

Private Sub ScrollBar2_Change()


TextBox3.Text = ScrollBar2.Value
End Sub

4. Se crean las Frame modalidad y periodicidad para que contengan las


cada uno de los dos grupos de OptionButton. Para que actúen como un
grupo, es decir, que sólo una pueda tomar valor verdadero, deben
incluirse dentro de una Frame.

5. Una etiqueta con fondo de otro color muestra el valor del primer término
amortizativo.

6. ListBox1 contiene el cuadro amortizativo. Marcamos 7 columnas


(ColumnCount) aunque sólo utilizamos 6 dado que da problemas a la hora
de fijar la anchura de la última columna.

7. CommandButton1 contiene el código para realizar los cálculos, el


CommandButton2 permite salir del formulario y el CommandButton3 copia
el contenido del ListBox1 en la hoja de cálculo.

Private Sub CommandButton2_Click()


Unload Me
End Sub

Los cálculos a realizar son:

Gráfico de la evolución de la reserva de una operación de amortización:

C0  I1 
a1 
A1 
I2 
C1  a2 
A2 
I3 
C2  a3 
A3 
C3=0 
0  1  2  3 

79
 
 

 Notación:
Cs = capital vivo al final del periodo s (reserva matemática por la derecha)
as = término amortizativo del periodo s (en el argot bancario es conocido por
“cuota”)
Is = cuota de interés del periodo s
As = cuota de amortización del periodo s (es positiva solo si as > Is)
Ms = capital amortizado al final del periodo s
is = rédito de valoración del periodo s (tipo efectivo subperiodal)
n = número de periodos
 Algunas relaciones básicas:
as = Is + As Is = Cs-1ꞏ is
Cs = Cs-1(1+is) - as Cs = Cs-1 - As
C0 = A1 + A2 + ... + An Ms = C0 - Cs
Ms = Ms-1 + As

 Equivalencias entre tipos de interés:


- i = tipo de interés efectivo anual,
- m = frecuencia con la que se producen los pagos dentro de un año o número
de periodos en los que se divide el año,
- i(m) = tipo de interés efectivo subperiodal o rédito subperiodal (si m=12 se
denominaría rédito mensual), es el tipo de interés correspondiente a
subperiodos de amplitud 1/m años,
- j(m) = tipo de interés nominal anual pagadero con frecuencia m.
m
 j (m) 
(1  i )  (1  i ( m ) ) m  1  ; j(m) = i(m) ꞏ m
 m 
Cuando se analizan las operaciones de amortización es habitual denotar
por is al tipo de interés efectivo subperiodal o rédito de valoración del periodo s,
simplificando así la notación i(m)s.

80
 
 

 Método francés (términos amortizativos constantes):

C0 a a a ꞏ ꞏ ꞏ a a

0 1 2 3 ꞏ ꞏ ꞏ n-1 n

i = i1 = i2 = ... = in a = a1 = a2 = ... = an
1  (1  i) n
C0  a  a n i  a As = As-1 (1 + i) = A1 (1 + i) s -1
i
donde n es el número de periodos.

 Método de cuotas de amortización constantes:


i = i1 = i2 = ... = in A = A1 = A2 = ... = An
n
C0   Aj  n  A
j 1

donde n es el número de periodos.

 Método de términos amortizativos variables en progresión geométrica:


La letra q denota uno más la razón de la progresión en tanto por uno.
Ejemplo: si la razón de la progresión es del 1,5%, entonces q = 1,015.

C0 a aꞏq aꞏq2 ꞏ ꞏ ꞏ aꞏqn-2 aꞏqn-1

0 1 2 3 ꞏ ꞏ ꞏ n-1 n

i = i1 = i2 = ... = in
donde n es el número de periodos.
El primer término de la progresión (a) se obtiene despejando de la
expresión que iguala los valores actuales de prestación y contraprestación:
1  q n 1  i 
n
C0  Aa, q n i a
1 i  q

El código aparece en el Anexo de Soluciones.

81