0082 Introduccion A Las Macros para Microsoft Excel
0082 Introduccion A Las Macros para Microsoft Excel
0082 Introduccion A Las Macros para Microsoft Excel
Postgrado oficial
oficial
Ciencias
Cienciasde
dela
laTierra
Tierra
J. V. Pérez Peña
Granada, 2012.
ISBN: 978-84-615-7245-8
Materias BIC: UFBC UMN UMP
Introducción a las Macros para Microsoft Excel® is licensed under a Creative Commons
Reconocimiento-NoComercial-CompartirIgual 3.0 Unported License.
http://creativecommons.org/licenses/by-nc-sa/3.0/
El presente libro es un intento de sintetizar una temática compleja como son las macros y el lenguaje
de programación Visual Basic for Applications (VBA) integrado en gran parte de las aplicaciones de
escritorio de Microsoft Windows ®. Este libro-manual es fruto del curso de postgrado Macros para
Ms Excel impartido dentro del programa de doctorado de Ciencias de la Tierra de la Universidad
de Granada, y nace como la necesidad de plasmar los contenidos de dicho curso en un único
volumen que pueda servir de referencia bibliográfica a los alumnos del mismo. Debido a la temática
de este curso, es posible encontrar manuales teóricos en ambos extremos; sumamente detallados
(dirigidos prácticamente a desarrolladores), o excesivamente escuetos (en los que no es posible
entender lo que se está realizando). Este es un puente entre ambos extremos; ofreciendo una base
teórica precisa y actualizada, así como ejemplos de uso práctico.
El curso de postgrado impartido en la Universidad de Granada, pese a contar hasta la fecha con
solamente dos ediciones, cuenta con un grado de aceptación muy elevado entre sus estudiantes, que
entienden este tipo de formación práctica como parte esencial para su formación.
A pesar de que el presente manual esta específicamente enfocado a las macros para Ms Excel ®,
haciendo uso de los objetos COM de Microsoft, el lector encontrará una introducción a la
programación en leguaje VBA, así como una presentación a la programación orientada a objetos que
le podrá servir a modo de base para realizar script y aplicaciones para cualquier otro tipo de
software que admita el lenguaje VBA.
Este libro se completa con los archivos de los ejercicios resueltos que se encuentran en el CD
adjunto.
Agradecimientos
0. INTRODUCCIÓN 10
1. VARIABLES 18
1.1. Concepto de variable 18
2. INSTRUCCIONES 22
. . Instrucción lógica If …Then 22
2.2. Bucle For …Next 25
. . ”ucle Do … Loop 27
. . Sentencia SelectCase … 30
3. MATRICES (ARRAYS) 32
3.1. Concepto de matriz 32
3.2. Declaración de matrices en VBA (Dinámicas Estáticas) 32
Para entender mejor el editor vamos a crear una macro en blanco. Para hacer esto vamos a la
pestaña Vista Macros, aunque también podemos entrar desde la ficha de Programador Macros, y
aún tenemos otro modo de entrar con Alt+F11. En la ventana nos aparecerán las macros que hemos
creado en el documento. Vemos que no aparece ninguna macro en el cuadro inferior, porque aún no
hemos creado ninguna. Para crear una nueva macro escribimos en el cuadro debajo de Nombre de la
macro . Le ponemos de nombre MiMacro y le damos a crear.
El editor contiene 3 ventanas principales: la Ventana Proyecto (parte izquierda superior), la Ventana
de Código (parte derecha) y la Ventana Propiedades (parte izquierda inferior). Además, como
muchos otros programas de Windows, también tiene un Menú y debajo una barra de herramientas.
La Ventana Proyecto; esta ventana muestra los libros (*.xls) y los complementos abiertos.
Usualmente verás nombres del tipo "VBAProject" y entre paréntesis el nombre del archivo o
complemento Excel. Veamos el caso de VBAProject (Libro1); simplemente significa que tienes
abierto un libro Excel llamado Libro 1. Además tenemos 2 sub-carpetas; Microsoft Excel
Objetos (con Hoja1, Hoja2, Hoja3, y ThisWorbook) y Módulos (En esta última vemos
Módulo1, que es donde hemos creado nuestra primera macro).
Ventana de Código: esta es el lugar donde escribiremos el código propiamente dicho de las
macros. Como vemos, en la barra de título de esta ventana pone Libro Módulo1
Código . Esto quiere decir que la ventana de código corresponde a un módulo estándar
llamado Módulo1 que se ha creado en dentro del Libro1 (libro que tenemos actualmente
abierto). Dentro de esta ventana de cogido vemos que el programa ha escrito Sub MiMacro()
… End Sub. Lo que hay entre estas dos instrucciones es la macro que acabamos de crear.
Como recordaremos una macro es en esencia un conjunto de instrucciones, ¿qué instrucciones
contiene ahora mismo nuestra macro? …Exacto, ¡Ninguna!
Ventana Propiedades: Esta ventana nos informa de las propiedades del elemento
seleccionado (en nuestro caso, el Módulo1). No nos preocuparemos por entender todo esto
ahora, ya lo iremos desentrañando a medida que avance el curso.
Ahora vamos a ver lo que hace nuestra macro. Cerramos el editor, volvemos a nuestro libro de
Excel, y en Menú Vista Macros; seleccionamos MiMacro y le damos a ejecutar.
2. Creamos el botón en la celda C3. Al crearlo vemos que se abre la ventana de macros con las dos macros
creadas anteriormente (MiMacro y MiMacro2), y vemos que a su vez ha puesto un nuevo nombre
(Botón2_Haga_clic_en) por si queremos crear una nueva macro con ese nombre. Para nuestro objetivo, le
asignaremos la última macro creada (MiMacro2) y le damos a aceptar.
3. Al pulsar el botón vemos que el resultado es el mismo que tuvimos al ejecutar MiMacro2. Si pulsamos con
el botón derecho sobre el botón podremos cambiarle el nombre, moverlo a otro sitio, o incluso modificar
la macro asociada al mismo.
2. Seleccionamos las 10 celdas que previamente hemos rellenado, y vamos a la ficha de Inicio – Ordenar y
Filtrar – Ordenar de mayor a menor. Seguidamente seleccionamos la celda B1 y escribimos la siguiente
formula; = =A1 * PI()/2.
3. Por último, vamos a copiar esa fórmula a las demás celdas, para ello hacemos clic en el cuadrado inferior
izquierdo del borde de la celda B1 y arrastramos hasta la B10. Ya hemos terminado de grabar nuestra
macro, le damos al botón de finalizar grabación (debajo de Hoja1).
4. Para ver la macro grabada, entramos en el editor de VBA (Menu – Vista – Macros; desde la ficha de
programador, o mediante Alt-F11). Ahí vemos que se ha generado un módulo nuevo (módulo1) y que en
él está nuestra macro. Vemos que el lenguaje utilizado puede ser difícil de comprender a primera vista sin
unas nociones básicas de programación. No nos preocupemos ahora, iremos comprendiendo esto mejor
cuando avancemos por el curso.
Hemos visto en esta lección lo que son las macros, como se crean en MS Excel, hemos introducido
brevemente el editor de VBA que viene integrado con programas de Microsoft, y por último hemos
creado nuestras primeras macros (unas más simples con una sola instrucción, otras más complejas
con varias instrucciones, e incluso un botón para ejecutar las macros directamente). Antes de seguir
avanzando, veremos unos conceptos básicos de programación en Visual Basic que nos serán muy
útiles a la hora de crear nuestras propias macros.
De la misma manera, si creáramos otra variable del tipo Caja cilíndrica , podríamos guardar en
ella el Dato3 y el Dato4, pero no así el Dato2.
El nombre de una variable debe de comenzar por una letra, puede tener hasta 255 caracteres, y debe
de ser único en su ámbito (no nos preocuparemos de esto ahora, ya lo entenderemos mejor más
adelante). Los tipos Integer y Long se usan para guardar números enteros, con la diferencia de que
Long nos permite guardar números más grandes.
Rango del tipo Integer; -32,768 – 32,769
Rango del tipo Long; -2,147,483,648 - 2,147,483,649
¿Cuándo utilizar uno u otro tipo?, aunque Long nos permite guardar números más grandes,
también reserva mayor espacio en la memoria del ordenador.
Para terminar con la declaración de variables, veremos algunos puntos importantes en la
declaración de las mismas.
Podemos declarar más de una variable en una sola línea
Dim Numero As Integer, NumeroLargo As Long, otroNum As Single, Nombre As String
Podemos declarar variables con caracteres tipo
Dim Numero%, NumeroLargo &, otroNum!, Nombre$
Si no especificamos tipo se crea variable de tipo variant (multiuso)
Dim Numero
Podemos utilizar variables sin declarar previamente. Esto no es muy idea pues, puede condudir a
errores inesperados;
Numero1 = 25
Numero2 = 40
Numero3 = Mumero1 + Numero2
¿Cuánto valdrá Numero3?
La instrucción Option Explicit al principio de un módulo obliga a declarar variables en el módulo.
Esta sección se denomina sección de declaraciones, y todo lo que se declare en ella afectará a todos
los procedimientos y funciones que se definan en el módulo (iremos viendo esto más adelante).
La instrucción InputBox nos mostrará una caja de dialogo con el texto especificado (en nuestro caso
Introduce Valor ). Veremos esta caja de diálogo en detalle más adelante.
Salida de datos
Utilizar la caja de diálogo MsgBox
Dim Numero1 As Integer (Declaramos variable)
Numero1 = 45 (Le damos a la variable el valor numérico 45)
MsgBox Numero1 (Muestra una caja de dialogo con el valor de Numero1)
La instrucción MsgBox nos mostrará una caja de dialogo con la variable o el texto que
especifiquemos (en este ejemplo, el valor de la variable Numero1)
Un poco más adelante veremos más en detalle estas dos cajas de diálogo.
Hacer un programa que te pida el nombre con una InputBox y que te diga algo
personalizado con una MsgBox
2. INSTRUCCIONES
Las instrucciones nos permiten elegir entre varias opciones, repetir acciones determinadas, etc. En
este curso veremos las instrucciones lógicas (If…Then), que nos permitirán realizar unas u otras
acciones dependiendo del resultado de una condición; los bucles For …Next y Do … Loop, que nos
permitirán repetir una acción un determinado número de veces; y la sentencia Select Case, que nos
permitirá elegir entre varias opciones a la vez.
Ejercicio 2.
Abrimos un libro nuevo y creamos una macro llamada Macro1. En esta macro vamos a definir 3
variables; Precio (doble), Cantidad (entera) y PrecioT (doble). Les asignaremos valores a Precio y
Cantidad con dos InputBox. Calcularemos PrecioT como el producto de ambas. Sí PrecioT es mayor
que 500 le aplicaremos el 15% de IVA. Visualizaremos el precio total en una MsgBox.
Ejercicio 3.
Repetir el ejercicio 2. Pero ahora si el precio total es mayor de 500 aplicaremos un 20% de IVA, si
está entre 500 y 250 un 15%, y si es menor de 250 un 10%. Visualizaremos el precio total con una
MsgBox.
Ejercicio 4.
Repetir el ejercicio 3. Pero ahora coger los valores de cantidad y precio de las celdas A1, y B1.
Escribir el precio total en la celda C1.
Para darle a una celda el valor de una variable;
Ra ge Celda .Value = Va ia le
Para darle a una variable el valor de una celda;
Va ia le = Ra ge Celda .Value
Ejercicio 5.
Comparar los valores de las celdas A1 y B1. Si son iguales, escribir en C1 "Los valores de A1 y B1 son
iguales", si el valor de A1 es mayor que B1, escribir "A1 mayor que B1"; sino, escribir "B1 mayor que
A1". (Realizar el ejercicio con dos estructuras If anidadas)
Ejercicio 7
Entrar el Nombre, la cantidad y el precio de un producto desde el teclado con InputBox y
guardarlos respectivamente en A1, B1 y C1. Calcular el total y guardarlo en D1. Si el total es
superior a 10.000 o el nombre del producto el "Reloj", pedir un descuento; calcular el total del
descuento y guardarlo en E1, luego restar el descuento del total y guardarlo en F1. (Utilizar un
operador lógico OR)
Ejercicio 8.
Abrimos un nuevo libro de Excel. En la Hoja1 crearemos una tabla con valores como en la figura.
Crearemos una macro que coja los valores de Precio, Cantidad, de las columnas A y B.
Seguidamente la macro calculará el total aplicando el mismo IVA que en el ejercicio 3 (20, 15 o 10%
según el precio total), y escribirá los resultados en la columna C. Podemos copiar partes de código
(Ctrl + c) y pegar (Ctrl + v), como si se tratase de texto normal.
Con esta última macro hemos visto varias cosas; i) que la macro actúa sobre la hoja activa (porque
no le hemos especificado otra cosa) y ii) qué no es práctico escribir tantas líneas de código para una
macro tan simple. Para solucionar esto último, utilizaremos los bucles.
Ejercicio 9.
Hacer un programa que tome el valor de la celda A1 de la Hoja1, calcule su factorial, y escriba el
resultado en la celda B1. Guardar la macro como MacroFact y el libro como CM_E9-11.xlsm .
Al principio de esta macro escribiremos la siguiente instrucción;
ActiveWorkbook.Sheets("Hoja1").Select
Con esto nos aseguramos que la macro se ejecutará en la Hoja 1 (porque la hemos activado).
Ejercicio 10.
Crear una macro que repita el ejercicio 8 pero utilizando un bucle For …Next
Funciones de comprobación
Podemos utilizar dos funciones que nos serán muy útiles para ver si un valor resultado de una
expresión, de una celda, o entrado en una caja de diálogo es numérico, o si está vacío.
La función IsEmpty(expresión) devuelve verdadero si expresión está vacía o falso en
caso de que expresión contenga un valor
La función IsNumeric(expresión), devuelve verdadero si expresión contiene un número
y falso en caso contrario.
Veamos ejemplos de uso de estas dos funciones;
Esta primera macro evalúa si la variable Valor (que se ha definido como Variant), es numérica. Si no
lo es, nos informará de nuestro error, y nos volverá a pedir qué le demos un valor numérico.
Sub Comprueba()
Dim Valor ‘Valo es de tipo Va ia t, a ia á su tipo e fu ió del alo ue te lee os e la I putBo
Valor = InputBox("Introduce un valor numérico:")
Do Until IsNumeric(Valor) = True
MsgBox "No has introducido un valor numérico"
Valor = InputBox("Introduce un valor numérico:")
Loop
MsgBox "Bien!!, has introducido un número"
End Sub
Esta segunda macro nos buscará la primera celda vacía de la columna A.
Sub BuscaCeldaVacía()
Dim i As Long
Dim ValorCelda ‘Valo Celda es Va ia t, a ia á su tipo e fu ió del alo de la elda
i=1 ‘I i ializa os la a ia le o tado
ValorCelda = Cells(i, 1).Value ‘I i ializa os la a ia le ue o te d á los valores de las celdas
Do While IsEmpty(ValorCelda) = False
i=i+1
ValorCelda = Cells(i, 1).Value
Loop
MsgBox "La primera celda vacía es la A" & i
End Sub
Función MsgBox
La función MsgBox, muestra una caja de diálogo en pantalla con el mensaje que queramos. Sin
embargo, podemos utilizar esta función para más cosas, y presentar distintas cajas de diálogo. Su
sintaxis es;
MsgBox(Mensaje, Botones, Título, ArchivoAyuda, NAyuda)
Mensaje: Mensaje que se muestra en la caja
Botones: Constante de tipo entero que determina el botón o botones y el tipo de caja. Podemos introducir su
valor numérico o el nombre de la constante de VB.
Los botones de la caja se determinan según la variable Botones. Dependiendo de este valor, la caja
que se mostrará será de un tipo u otro.
Estos dos ejemplos muestran una MsgBox de tipo información;
MsgBo Esto es una caja informativa , , Cu so Ma os E el
MsgBo Esto es u a aja i fo ati a , V I fo atio , Cu so Ma os E el
Constante Valor Descripción (tipo de caja)
VbOKOnly 0 Muestra solamente el botón Aceptar.
VbOKCancel 1 Muestra los botones Aceptar y Cancelar.
VbAbortRetryIgnore 2 Muestra los botones Anular, Reintentar e Ignorar.
VbYesNoCancel 3 Muestra los botones Sí, No y Cancelar.
VbYesNo 4 Muestra los botones Sí y No.
VbRetryCancel 5 Muestra los botones Reintentar y Cancelar.
VbCritical 16 Muestra el icono de mensaje crítico.
VbQuestion 32 Muestra el icono de pregunta de advertencia.
VbExclamation 48 Muestra el icono de mensaje de advertencia.
VbInformation 64 Muestra el icono de mensaje de información.
Ejercicio 13
Crea un programa que introduzca nombres en las celdas de la columna A. El programa pedirá cada
nombre mediante una InputBox, luego preguntará si deseamos introducir otro nombre mediante
una MsgBox. Si elegimos que SI, nos volverá a pedir un nombre, si pulsamos NO, terminará el
programa. Utilizar un bucle Do.
Ejercicio 14.
Repite el ejercicio 12 pero utilizando la sentencia Select Case
Ejercicio 15
Realizar un programa que pida el nombre de un alumno y sus 4 notas parciales mediante funciones
InputBox. Escribir el nombre del alumno en la celda A1 y las 4 notas parciales en las celdas B1 E1.
La nota final se calculará como la media de las 4 notas, pero teniendo en cuenta que el valor
porcentual de cada una de estas notas parciales será de un 10, 20, 30, y 40% respectivamente.
Escribir la nota final en la celda F1. En la celda G1 dejaremos un texto con la calificación; si la nota
es menor de Suspenso , si está entre y 7 no incluido “probado , si está entre 7 y 9 no
incluido Notable , si está entre 9 y 10 (incluidos ambos) Sobresaliente , y si el valor de la nota no
es ninguno de los anteriores Nota Erronea .
Matrices estáticas
Para declarar una matriz estática especificaremos su nombre, el número de elementos, y su tipo.
Dim NombreMatriz (dimensiones) As TipoDato
NombreMatriz es el nombre que le daremos a la matriz. Dimensiones es una lista de expresiones numéricas,
separadas por comas y que definen las dimensiones y tamaño de la matriz. Las dimensiones se especificarán de
la siguiente manera [inferior To] superior, [ [inferior To] superior ].
TipoDato hace referencia al tipo de datos que guardará la matriz (números enteros, decimales, cadenas de
texto, etc.).
Ejercicio 16.
Declara una matriz unidimensional con los nombres algunos de los alumnos de este curso. Darle los
nombres directamente en la macro. Escribir los nombres en las celdas de la primera columna de la
Hoja1.
Matrices dinámicas
Cuando las dimensiones de una matriz no son siempre las mismas, la mejor forma de especificarlas
es mediante variables. Una matriz declarada de esta forma se denomina matriz dinámica. El espacio
en memoria para una matriz estática se asigna directamente al declarar la matriz, en cambio para
una matriz dinámica, el espacio en memoria se asigna durante la ejecución del programa.
Para crear una matriz dinámica;
Declaramos la matriz en el código, pero dejando la lista de dimensiones vacía
Dim MyArrray() As Long
Redimensionamos con ReDim y una variable que indique el número de elementos.
n=8
ReDim MyArray(n)
Cada vez que ejecutamos la sentencia ReDim, todos los valores almacenados en la matriz se
pierden. Si nos interesa cambiar las dimensiones de la matriz pero conservar los valores de la
misma, utilizaremos ReDim con la palabra clave Preserve.
Al utilizar Preserve, conservamos los valores guardados en la matriz. Imaginemos que nf y nc son
dos variables en las que tenemos guardados el número de filas y columnas de una matriz. Si
aumentamos el tamaño de la matriz, los datos guardados no se perderán. Por el contrario, si
disminuimos el tamaño de la matriz, los datos correspondientes a los elementos eliminados,
lógicamente se perderán.
nf = 4
nc = 4
Ejercicio 17
Abrir el libro de CM_E17.xlsx. Hacer una macro para guardar los datos de las columnas A, B, y C en
una matriz. Las dimensiones de la matriz se las daremos con dos InputBox. En la columna E, se
calcularán las sumas de cada fila.
Ejercicio 18
Abrimos el libro CM_E18.xlsx. Vamos a hacer dos macros;
-Una primera macro, llamada LlenaMatriz , que coja los datos de las columnas A, B, y C y los
guarde en una matriz (podemos utilizar el mismo código que en el ejercicio17). La matriz la
definiremos fuera de la Macro, en la sección de declaraciones del Módulo, así no se borrará cuando
termine la macro.
-Una segunda macro, llamada DetectaCambios , la cual dibujará en rojo cualquier celda a la que le
hayamos cambiado el valor después de ejecutar LLenaMatriz
Nota; para pintar una celda lo haremos de la siguiente manera; [cells(i,j) es la celda que queremos pintar].
Dim Rango1 As Range
Set Rango1 = Cells(i, j)
Rango1.Interior.Color = vbRed
Ejercicio 19. Construir y llenar una matriz de pesos para un análisis estadístico
Abrimos el libro CM_E19.xlsx. En el vemos datos de 3 columnas; X, Y, y Z. Estos datos
corresponden a datos experimentales (columna Z) de localizaciones espaciales (determinadas por
las columnas X, e Y). Unos de los pasos previos a la realización de un análisis de autocorrelación
espacial es la de generar una matriz de pesos (W(i,j)). Esta matriz W, es una matriz cuadrada de
dimensiones [1 To n], [1 To n] (siendo n el número de datos). Los valores de los elementos de esta
matriz serán 1/di-j(siendo di-j la distancia entre los elementos i y j). Es decir, se compara cada dato
experimental con el resto de datos, y se le asigna un peso proporcional a la distancia al mismo.
Realizar un programa que calcule y genere esta matriz de pesos (W(i,j)).
Escribir la matriz completa en la Hoja2.
Consejos;
1. Crea 3 matrices para guardar los datos de X, Y, y Z.
2. Redimensiónalas (1 To n, 1 To n) siendo n el número de datos. Y toma los datos de las columnas A, B, y C.
3. Pa a a ede a los ele e tos de la at iz haz dos u les Fo … Next anidados (contadores i y j).
4. Para calcular la distancia entre dos elementos (i y j) partiendo de sus coordenadas X e Y (proyectadas), y
suponiendo que tenemos tres matrices X(), Y(), y Z() con los valores, podemos utilizar la ecuación;
√ d= Sqr(((X(j) - X(i)) ^ 2) + ((Y(j) - Y(i)) ^ 2))
Propiedades.
Cualquier objeto tiene características o propiedades como por ejemplo el color, la forma, peso,
medidas, etc. Estas propiedades se definen en la clase y luego se particularizan en cada objeto. Así,
en la clase coche se podrían definir las propiedades Color, Ancho y Largo , luego al definir un
objeto concreto como coche ya se particularizarían estas propiedades a, por ejemplo, Color = Rojo,
Ancho = 2 metros y Largo = 3,5 metros. Aunque ya lo veremos más adelante, para referirnos a las
propiedades de un objeto, lo hacemos de la siguiente manera;
NombreObjeto.Propiedad = Valor
Métodos.
La mayoría de objetos tienen comportamientos o realizan acciones, por ejemplo, una acción
evidente de un objeto coche es el de moverse o lo que es lo mismo, trasladarse de un punto inicial a
un punto final. Cualquier proceso que implica una acción o pauta de comportamiento por parte de
un objeto se define en su clase para que luego pueda manifestarse en cualquiera de sus objetos. Así,
en la clase coche se definirían en el método mover todos los procesos necesarios para llevarlo a cabo
(los procesos para desplazar de un punto inicial a un punto final), luego cada objeto de la clase
coche simplemente tendría que invocar este método para trasladarse de un punto inicial a un punto
final, cualesquiera que fueran esos puntos. Para invocar un método, lo hacemos de la siguiente
manera;
NombreObjeto.Metodo
Eventos
Los eventos hacen referencia a aquellas acciones que puedan ocurrir sobre el objeto. Podemos
definir el comportamiento del objeto cuando suceda tal acción o evento.
Esta instrucción es muy útil cuando trabajamos con objetos de objetos de objetos, y necesitamos
escribir mucho código en cada línea. Por ejemplo, si queremos modificar la fuente de un rango de
celdas;
With Worksheets("Hoja1").Range("A1:A10").Font
.Name = "Arial Rounded MT Bold"
.Size = 10
.Bold = True
.Italic = True
.Color = RGB(39, 179, 146)
End With
Vemos que no tenemos que volver a escribir Worksheets("Hoja1").Range("A1:A10").Font para cada
propiedad del objeto Font.
Función RGB()
En el último ejemplo, hemos visto que el color lo hemos definido con la función RGB. Esta función
devuelve un valor (tipo Long) que especifica un color de 24 bits resultado de la mezcla de partes de
Rojo (Red), Verde (Green) y Azul (Blue). Su sintaxis es;
Valor = RGB(Red, Green, Blue)
Valor; es el valor (tipo Long) retornado por la función, especifica un color de 24 bits
Red, Green, Blue; valores para las partes de Rojo, Verde, y Azul. Estos valores irán de 0 a 255 (8 bits)
Objetos de Objetos.
Es muy habitual que una propiedad de un objeto sea otro objeto. Siguiendo con el ejemplo del
coche, una de sus propiedades es el motor, y el motor es un objeto con propiedades como cubicaje,
caballos, número de válvulas, etc. y métodos, como aumentar_revoluciones, coger_combustible,
mover_pistones, etc.
En Excel, el objeto WorkSheets tiene la propiedad Range que es un objeto, Range tiene la propiedad
Font que es también un objeto y Font tiene la propiedad Bold(negrita). Ten esto muy presente ya
que utilizaremos frecuentemente Propiedades de un objeto que serán también Objetos. Dicho de
otra forma, hay propiedades que devuelven objetos, por ejemplo, la propiedad Range de un objeto
WorkSheet devuelve un objeto de tipo Range.
Ejercicio 20.
Hacer una macro que cambie el formato del texto de las celdas A1-A10. Cambiar la fuente a Arial,
negrita y cursiva. El tamaño de la fuente nos lo preguntará con una InputBox, y para el color (tanto
del texto como de fondo) nos preguntará los valores R, G, y B del color deseado mediante InputBox
(recordad qué los valores que introduzcamos tienen que estar entre 0 y 255).Para los valores RGB de
este ejemplo podemos utilizar;
Rojo Verde Azul
Texto (Azul Oscuro) 33 89 103
Fondo (Verde claro) 216 228 188
Módulos estándar
Este tipo de módulo solo contiene declaraciones de funciones y procedimientos, así como variables
y variables tipo. Es el tipo de módulo con el que hemos estado trabajando desde el principio del
curso. Las declaraciones de variables, procedimientos y funciones en este tipo de módulo pueden
ser públicas (por defecto, cualquier procedimiento de cualquier otro módulo puede acceder a ellas)
o privadas (especificando Private en vez de Dim, solo se puede acceder a ellas desde dentro del
mismo módulo).
Formularios
Los formularios son un tipo especial de módulos que proporcionan al usuario una interfaz de
entrada-salida de datos.
Módulos de clase
Son un tipo de módulo especial que se usan para definir clases de objetos. En este curso no veremos
este tipo de módulos.
Como ejemplo vamos a crear un Módulo estándar llamado MiModulo. Abrimos un libro de Excel
nuevo, pulsamos Alt-F11 y entramos en el editor de VBA. Vemos que como no hemos creado
ninguna macro, no se ha creado tampoco ningún módulo estándar. Le damos a insertar Módulo, y
vemos que automáticamente se crea un módulo con el nombre Módulo . Para cambiarle el
nombre a este módulo, en la ventana de propiedades, cambiamos la propiedad de Name a
MiModulo.
Para utilizar un formulario en Excel, tenemos que cargarlo y visualizarlo. Esto lo podemos hacer
creando una macro que llame al formulario (o sea, que lo cargue y visualice), o creando un botón
que lo cargue cuando pulsemos.
Para practicar, vamos a ver las dos opciones;
1. Abrimos un libro nuevo de Excel, y creamos una macro que se llame CargandoFormulario
2. Una vez en el editor, añadimos un formulario (le dejamos el nombre por defecto).
3. En el código de nuestra macro escribimos lo siguiente;
Sub CargandoFormulario()
UserForm1.Caption = "Este es mi primer formulario"
UserForm1.BackColor = &HC0FFC0
Load UserForm1
UserForm1.Show
End Sub
4. Vamos a Excel y ejecutamos la macro.
A continuación escribiremos el código necesario para que al pulsar aceptar, el valor introducido en
la caja de texto, se introduzca en la celda activa del libro activo.
Hacemos doble clic sobre el botón de aceptar, y automáticamente vamos a la parte del código del
formulario, entre Private Sub CommandButton1_Click() y End Sub. Este es el código que se ejecutará
cuando suceda el evento hacer clic sobre el botón. Para referirnos al valor que haya en el cuadro
de texto, utilizaremos su propiedad Text.
Dim Valor As Double
Valor = TextBox1.Text
ActiveCell.Value = Valor
Vemos que este procedimiento, a diferencia de los otros, tiene un argumento; KeyAscii. Este
argumento hace referencia al código ASCII de la tecla pulsada. En este ejemplo utilizaremos este
argumento para ver si se ha pulsado un número o no. Si el código ASCII coincide con un número,
coma, o punto, se escribe en el cuadro de texto; sino es ninguno de esos caracteres, se cancela la
pulsación. Para esto escribiremos el siguiente código dentro del procedimiento;
Private Sub TextBox1_KeyPress(By ValKeyAscii As MSForms.ReturnInteger)
Dim CaracterP As String ‘Defi i os u a a ia le ue gua da á el carácter de la tecla pulsada
CaracterP = Chr(KeyAscii) ‘Co la fu ión Chr() convertimos el código ASCII en un carácter
If InStr("1234567890,.", Ca a te P = The ‘“i el arácter no es un número, punto, o una coma …
Ke As ii = ‘“e a ela la pulsa ió
End If
End Sub
Para este ejemplo hemos utilizado dos funciones más; Chr() e InStr(). Las describiremos
brevemente;
Función InStr
Esta función devuelve un tipo de dato (Long) que indica la primera aparición de la una cadena en
otra. Su sintaxis es la siguiente;
valor = InStr([start,] cadena1, cadena2 [, compare])
valor; valor retornado por la función InStr indicando la primera aparición de la cadena2 en la cadena1
start; (Opcional). Posición inicial para cada búsqueda. Si start contiene un valor Null se produce un error.
cadena1; Cadena de texto en la que se busca
cadena2; Cadena buscada
compare; (Opcional). Especifica el tipo de comparación de cadena.
2. Vamos al editor del VBA (Alt-F11) e insertamos un nuevo formulario. En este formulario vamos a incluir los
siguientes elementos;
Elemento Nombre Caption
Label label1 Nombre
Label label2 Edad
Label label3 Profesión
TextBox tbNombre
TexBox tbEdad
ComboBox cbProfesión
CommandButton c_EntrarDatos Guardar Dato
CONSEJO
La fuente que nos pone VBA por defecto para etiquetas (propiedad Font), puede parecernos poco elegante
(Tahoma, Normal, 8 puntos). Podemos cambiar a otra fuente a las etiquetas, y cajas de texto, cambiando sus
propiedades Font.
¿Tenemos que hacer este cambio para cada control? Pues la verdad es que no, porque VBA nos permite
copiar controles. Al copiar y pegar un control, se copian todas sus propiedades excepto el nombre (no puede
haber dos controles con el mismo nombre). Prueba a insertar el label1, cambiar su fuente, y después
selecciónalo y utiliza copiar y pegar (con el botón derecho o con los botones copiar y pegar). Vemos que se
crea otro control igual en el formulario, que aunque tiene la misma fuente y la misma etiqueta, tiene un
nombre diferente.
CONSEJO
También nos habremos dado cuenta de que la rejilla del formulario es más bien gruesa (es decir, no
podemos mover los controles, ni redimensionar su tamaño de una forma fina). Tenemos dos formas de
variar esto;
Una manera es especificar achos y altos específicos para el control con las propiedades Width y Height, y
controlar su posición dentro de un formulario con las propiedades Top (distancia desde el margen superior
del formulario), y Left (distancia desde el margen izquierdo del formulario).
Otra forma consistirá en variar esta rejilla. Esto lo podemos hacer dentro del editor de VBA en Menu –
Herrameintas – Opciones – Ficha general – y variamos las unidades de la rejilla (por defecto 6).
3. Ahora pasemos a escribir el código. Lo primero que haremos es llenar la comboBox con los elementos
cuando se cargue el formulario. Para ello utilizaremos el evento del Formulario Initialize. En la ventana de
código del formulario, en la parte superior, seleccionamos UserForm y en la siguiente lista Initalize. Entre
el Sub, y en End Sub escribimos el código para llenar la combo; utilizamos el método AddItem y escribimos
4 o 5 profesiones como en el ejemplo siguiente;
4. Una vez llena la combo, escribiremos el código para el botón de comando. Al hacer clic en él, los datos del
formulario se escribirán en las columnas 1, 2 y 3 de la hoja activa. Seleccionamos en la primera lista
desplega le de la ve ta a de ódigo del fo ula io _E t a Datos o e de uest o botón), y en la
segu da Cli k . E t e el “u E d “u , i t odu i os el siguie te ódigo;
Ra ge A .Value = t No e.Text
Ra ge B .Value = tbEdad.Text
Ra ge C .Value = P ofesió .Te t
El aspecto que tendrá la ventana de código de nuestro formulario será el siguiente;
6. Guarda este libro como EjemploCombo1.xlsm. Más adelante modificaremos el código para que al hacer
clic, los datos se introduzcan en la siguiente fila vacía.
Ejercicio 21.
Abre el libro Excel CM_E21.xlsx. Este libro tiene dos hojas, vemos que en la Hoja2 hay nombres de
especies. Crear un formulario con una ComboBox que se llene con los nombres de las especies de
esta Hoja2. Añadir un botón al formulario que permita introducir el valor seleccionado en la combo,
en la celda A1 de la Hoja1.
6. PROCEDIMIENTOS Y FUNCIONES
Argumentos de un procedimiento
Otro concepto importante de los procedimientos son los argumentos. Los argumentos son variables
que usará el procedimiento en su código interno, se especifican entre los paréntesis.
Vamos a ilustrar esto con un sencillo ejemplo;
1. Abre un nuevo libro de Excel, inserta un formulario con 3 labels y un botón de comando;
2. Ahora crearemos un procedimiento llamado LlenarLabels que le cambie el Caption a esas etiquetas. Para
ello, el procedimiento tendrá 3 argumentos de tipo cadena de texto (string). Esto se especifica dentro del
paréntesis detrás del nombre del procedimiento. Deberá quedar así.
Private Sub LlenarLabels(cadena1 As String, cadena2 As String, cadena3 As String)
End Sub
3. Ahora dentro del procedimiento podemos utilizar estas variables para cambiar los caption de las
etiquetas;
4. Es hora de llamar a nuestro procedimiento utilizando argumentos. Nos vamos al procedimiento de clic de
nuestro botón, y ahí escribimos lo siguiente;
Nos hemos dado cuenta de que al llamar al procedimiento esta vez hay que especificar cada uno de los
argumentos separados por comas. Las variables Nombre, Dirección y Teléfono se han pasado como los
argumentos cadena1, cadena2, y cadena3 de nuestro procedimiento. Si no se especifican los argumentos,
se produce un error, puesto que son obligatorios (por defecto). Si alguna de las variables no fuera del
mismo tipo que el argumento se produce un error. Probemos a cambiar el tipo de la variable Teléfono a
Long ¿Qué pasa entonces?
6. En el procedimiento de clic del commandbuton1, añadamos una línea al final para visualizar el contenido
de las variables con una caja de texto;
MsgBox Nombre
MsgBox Dirección
MsgBox Teléfono
7. Ahora ejecutemos el formulario, ¿Qué ocurre? Vemos que al borrar las variables cadena1, cadena2, y
cadena3 (argumentos de nuestro procedimiento), también se borran las variables Nombre, Dirección, y
Teléfono que hemos definido. ¿Cómo podemos evitar esto?, simplemente pasando los argumentos por
valores y no por referencia. Escribamos ByVal delante de cadena1, y cadena2, ByRef delante de cadena3.
Ahora ejecutemos la aplicación y demos clic al botón, ¿vemos cuál es la diferencia?
Ejercicio 22
Abrimos el libro de Excel CM_E22.xls Vamos a crear un procedimiento que coloque la selección en
la primera celda vacía de una columna concreta. El procedimiento tendrá dos argumentos, el
número de la columna y el nombre de la hoja. Para buscar la celda vacía podemos utilizar un bucle
Do y la función IsEmpty
Do Until IsEmpty(Cells(i, Columna).Value)
Loop
Ejercicio 23
Abrimos la macro realizada en el ejercicio 21. Vamos a modificar esta última aplicación. Vamos a
definir un procedimiento privados (OrdenarRango) dentro del formulario. Este procedimiento
llenará la ComboBox.
Como vemos en el gráfico de arriba, una función debe de tener dentro de su código una línea donde
se le asigne el valor a la función. Esto se hace de la siguiente manera; NombreFunción = Valor.
Para llamar una función desde cualquier parte del código;
Variable = NombreFunción (arg1, arg2)
Lo mismo que los procedimientos, las funciones públicas definidas en un módulo estándar se
podrán utilizar desde cualquier procedimiento o formulario. Una función pública también se puede
llamar como una función de Excel.
Ejercicio 25. Crear una función que calcule el índice Moran I de auto-correlación espacial
Este ejercicio requiere una macro más compleja, pero es un ejemplo de toda la funcionalidad que
podemos tener programando nuestras propias funciones. Para hacer este ejercicio, descargarse el
pdf Cálculo del índice MoranI , donde se explica paso a paso la formula y la forma de crear la
Macro.
Ya hemos visto anteriormente varios objetos propios de Excel tales como Range, WorkSheet,
Workbook, etc. En esta parte vamos a ver estos objetos con más detalle para poder exprimir al
máximo sus funcionalidades. Debido al carácter de este curso, las propiedades y métodos de los
objetos que veamos se mostrarán de la manera más simple, es decir, no se verán todos los
argumentos opcionales de muchos métodos y/o propiedades. Para una consulta más detallada
podemos acudir a la ayuda del editor de VB para Excel.
Workbooks.Open
Método que nos permite abrir un libro. Su sintaxis es;
Workbooks.Open(FileName, UpdateLinks, ReadOnly, Format, Password, WriteResPassword,
IgnoreReadOnlyRecommended, Origin, Delimiter, Editable, Notify, Converter, AddToMru, Local,
CorruptLoad)
Ejemplo; abrir un libro desde una macro. Antes de nada, copiemos el libro EjemploAbrir.xlsx al
directorio C:\Temp\. A continuación abriremos un libro nuevo y escribiremos la siguiente macro.
Sub Abrir()
DimNombreLibro As String
NombreLibro = "C:\Temp\EjemploAbrir.xls"
Workbooks.OpenNombreLibro, Password:="alimoche"
End Sub
Con este ejemplo hemos visto una cosa muy importante; aunque hay muchos argumentos
opcionales en el método open, podemos referenciar cualquiera de ellos con la sintaxis
NombreArgumento:= Valor.
En el ejemplo vemos que el argumento FileName es el primero, y Password es el quinto, ¿qué ha
pasado con los otros 3? Como son argumentos opcionales, podemos simplemente no especificarlos.
Si solo queremos especificar dos argumentos (en nuestro ejemplo FileName y Password, podemos
hacerlo de dos maneras;
a) Especificar el nombre de cada argumento y su valor; NombreArgumento:= Valor
b) Poner comas que separarán los valores de los distintos argumentos, dejando en blanco los
argumentos que no queramos especificar.
Estas 3 líneas de código, hacen exactamente lo mismo. Compruébalo por ti mismo.
Workbooks.Open"C:\Temp\EjemploAbrir.xls", Password:= "alimoche"
Workbooks.OpenFileName:="C:\Temp\EjemploAbrir.xls", Pass o d:= ali o he
Workbooks.Open"C:\Temp\EjemploAbrir.xls", , , , ali o he
Al utilizar la grabadora de macros, MS Excel utiliza esta nomenclatura con mucha frecuencia.
Si quisiéramos abrir todos los libros de un directorio, podemos utilizar una matriz de tipo string
con todos los nombres de todos los archivos de Excel de un mismo directorio. Para obtener todos
los nombres, podemos utilizar la función Dir. Veremos un ejemplo de esto más adelante.
Workbook.Close
El método Close cierra el libro especificado (preguntará si deseamos guardar cambios).
Para evitar que la aplicación (MS Excel) muestre alertas (como preguntar si deseamos o no guardar
los cambios, podemos usar la propiedad DisplayAlerts del objeto Application.
Application.DisplayAlerts = False
Este ejemplo cierra el libro activo, sin preguntarnos si deseamos guardar los cambios;
Sub CierraLibro()
Application.DisplayAlerts = False
ActiveWorkbook.Close
End Sub
Si queremos cerrar todos los libros abiertos;
Workbooks.Close
Workbook.Save
Este método guarda los cambios realizados en el libro activo. En la siguiente macro, primero
guardamos los cambios del libro activo, luego cerramos el libro, y por ultimo salimos de Excel.
Sub GuardaCierra()
ActiveWorkbook.Save
ActiveWorkbook.Close
Application.Quit
End Sub
Workbook.Worksheets
Esta propiedad del objeto Workbook devuelve una colección con todas sus hojas (objetos
Worksheet).
Worksheets(Item)
Hace referencia a una hoja concreta (objeto Worksheet) dentro de la colección Worksheets. Item
puede ser un índice, o el nombre de la hoja. Una vez que se referencia una hoja concreta, podemos
acceder a sus propiedades. Las dos siguientes líneas nos muestran una MsgBox con el nombre de la
segunda Hoja del libro activo.
MsgBo A ti eWo k ook.Wo ksheets .Na e, i fo atio , Cu so Ma os pa a E el
MsgBo A ti eWo k ook.Wo ksheets Hoja .Na e, i fo atio , Cu so Ma os pa a E el
Worksheets.Add
Este método agrega una hoja nueva a la colección Worksheets de un libro especificado. Su sintaxis es;
Worksheets.Add(Before, After, Count, Type)
Si no se especifica Before ni After, la nueva hoja se agrega justo después de la hoja activa.
Esta línea inserta 3 hojas delante de la Hoja2 del libro activo
ActiveWorkbook.Worksheets.Add Before:=Worksheets("Hoja2"), Count:=3
Worksheets.Count
Devuelve una variable (tipo Long) con el número de objetos de la colección (número de hojas de la
colección Worksheets). Su sintaxis es;
variable = Worksheets.Count
Con este código podemos mostrar una caja de dialogo que nos informe del número de hojas del
libro activo;
Dim NumeroHojas As Long
NumeroHojas = ActiveWorkbook.Worksheets.Count
MsgBox "El libro active tiene " & NumeroHojas & " hojas."
Worksheet.Name
Devuelve una variable de tipo variant (String) con el nombre de la hoja.
variable = Worksheet.Name
Estas líneas nos muestra el nombre de la hoja activa.
Dim HojaActiva As Worksheet, Nombre As String
Set HojaActiva = ActiveSheet
Nombre = HojaActiva.Name
MsgBox "La hoja activa se llama " & Nombre, vbInformation, "Curso Macros Excel 2011"
Worksheet.Visible
Propiedad que controla si una hoja es visible o no. Sus valores pueden ser verdadero falso. Ejemplo;
Dim MiHoja As Worksheet
Set MiHoja = Worksheets("Hoja3")
MiHoja.Visible = False ‘O ulta os la Hoja del li o a ti o
Worksheet.Activate
Método que activa la hoja especificada, convirtiéndola en la hoja activa (ActiveWorksheet). Con la
siguiente línea de código activamos la Hoja2 del libro activo.
A ti eWo k ook.Wo ksheets Hoja .A ti ate
Worksheet.Select
Método que selecciona la hoja especificada. El siguiente código selecciona la tercera hoja del libro
activo;
ActiveWorkbook.Worksheets(3).Select
Diferencias entre seleccionar y activar;
Cuando seleccionamos varias hojas, tan solo una de ellas puede ser la hoja activa. Podemos probar a
seleccionar dos hojas en un libro de Excel haciendo clic sobre ellas mientras mantenemos pulsada la
tecla Crtl. Las dos hojas pueden estar seleccionadas pero tan solo una de ellas (la que tenga su
nombre en negrita) es la hoja activa. Lógicamente, cuando operamos solo sobre una hoja y la
misma está seleccionada, Select o Activate es lo mismo (es decir seleccionar o activar da igual).
Seleccionando varias hojas a la vez
Con el siguiente código podemos seleccionar las hojas 1 y 2 del libro activo (siempre que no
hayamos cambiado sus nombres, y sigan siendo Hoja1 y Hoja2)
A ti eWo k ook.Wo ksheets A a Hoja , Hoja .“ele t
La función Array, devuelve una variante que contiene una matriz. Su sintaxis es;
Array(lista_argumentos)
El argumento lista_argumentos requerido es una lista de valores delimitados por comas que se
asignan a los elementos de la matriz contenida en el tipo Variant. El límite inferior de una matriz
generada con la función Array, viene determinado por la instrucción Option Base (si no se ha
especificado, será 0). Un ejemplo de su uso sería;
Dim Nombres As String
No es = A a Jua , Gusta o , E i ue
Msg o o es ‘Muest a u a aja MsgBo o el p i e o e de la Mat iz Jua
Para el siguiente ejemplo, abre un nuevo libro y añade 5 hojas. Con el código siguiente
seleccionaremos la primera, la tercera, y la quinta (da igual el nombre qué tengan), y además
determinaremos que la tercera hoja será la hoja activa.
Sub Selecciona()
ActiveWorkbook.Worksheets(Array(1, 3, 5)).Select
ActiveWorkbook.Worksheets(3).Activate
End Sub
Worksheet.Delete
Método que borra la hoja especificada. También podemos utilizar Worksheets con una array;
ActiveWorkbook.Worksheets(Array(3, 5)).Delete
Worksheet.Protect y Worksheet.Unprotect
Estos dos métodos sirven para proteger/desproteger la hoja especificada. Su sintaxis es;
Worksheet.Protect(Password, UserInterfaceOnly,)
Worksheet.Unprotect(Password)
No vamos a definir todos los argumentos de protect, solo dos importantes (si queréis más
información acerca de éste método consultad la ayuda);
Password; variable que identifica la contraseña para proteger/desproteger la hoja.
UserInterfaceOnly; variable que especifica si sólo se protege la hoja de las acciones de usuario normales, no
de las macros. Si su valor es true, se protegerá la hoja de las acciones del usuario, pero no de las macros.
Es muy importante que especifiquemos los nombres de los argumentos como hemos visto
(argumento:= valor), puesto que mientras que Password es el primer argumento, UserInterfaceOnly es
el quinto argumento.
Con este ejemplo, protegemos la Hoja1 de la edición por parte de un usuario, pero no desde una
macro.
Dim MiHoja As Worksheet
Set MiHoja = Worksheets("Hoja1")
MiHoja.Protect Password:="alimoche", UserInterfaceOnly:=True
Con este otro ejemplo, desprotegemos la hoja protegida anteriormente.
Dim MiHoja As Worksheet
Set MiHoja = Worksheets("Hoja1")
MiHoja.UnProtect Password:="alimoche"
Para referirnos a un rango en concreto de una hoja determinada podemos utilizar la nomenclatura;
CSI CID Donde CSI es la Celda Superior Izquierda del rango, y CID es la Celda Inferior Derecha
del rango. No olvidar que se deben poner entrecomilladas y separadas por los dos puntos.
A ti e“heet.Ra ge A :B .“ele t
También podemos expresarlo de esta otra manera;
A ti e“heet.Ra ge Ra ge A , Ra ge B .“ele t
En el ejemplo de arriba; Cell1 = Range “ , y Cell2 = Range ”
O incluso de esta tercera manera (recordamos que el objeto Cells(i, j) era también un objeto de tipo
Range.
ActiveSheet.Range(Cells(1,1), Ra ge B .“ele t
En este último ejemplo; Cell1 = Cells(1,1), y Cell2 = Range ”
Como devuelve un objeto de tipo Range, podemos utilizarlo bien para referenciar una variable-
objeto de tipo Range, o bien para utilizar algunas de las propiedades del propio objeto Range.
Este primer ejemplo utiliza la propiedad Range para referenciar una variable-objeto de tipo Range.
Dim MiRango As Range
Set MiRango = Worksheets("Hoja2").Range("A1:C20")
Este segundo ejemplo utiliza directamente una propiedad del objeto
Worksheets("Hoja2").Range("A1:C20").Select
Range.Value
Propiedad que hace referencia al valor de las celdas. Hemos utilizado varias veces esta propiedad.
Si no especificamos nada, Range actúa directamente sobre la hoja activa. Para darle un mismo valor a todas
las celdas de un rango;
Ra ge A :C .Value = Hola Mu do
Un objeto de tipo Range, está compuesto como hemos dicho anteriormente por una celda o un conjunto de
eldas. “i utiliza os u u le Fo Ea h … Ne t, so e u o jeto de tipo a ge utilizando como contador otro
o jeto de tipo Ra ge, este a go o tado to a á el valo de ada elda del Ra go e ada epeti ió del
bucle. Para ver esto más claramente, fíjate en el ejemplo a continuación. Vamos a rellenar el rango A1:C20
con valores aleatorios entre 100 y 200;
Range.Select
Selecciona un rango concreto. Al seleccionar un rango, el objeto Selection (objeto tipo Range) pasa a
contener la selección.
Ejemplo; vamos a seleccionar un rango de la Hoja2, lo vamos a seleccionar, y después vamos a
referenciar una variable de tipo Range a la selección.
Dim MiRango As Range
Dim MiHoja As Worksheet
Worksheets("Hoja2").Select
Worksheets("Hoja2").Range("A1:B5").Select
Set MiRango = Selection
Para realizar una selección, la hoja tiene que ser la hoja activa. Prueba a eliminar la 3 línea de código
¿ves que pasa?
Es posible realizar una selección de varias celdas, para ello utilizaremos la siguiente sintaxis;
Range( elda , elda , elda , …, elda ).Select
celda1, celda2, celdan; son las referencias a las celdas. Se pueden obtener mediante la propiedad
Range.Adress. Con la siguiente línea realizamos una selección de varias celdas.
Range("A2,B5:B8,C10:G20").Select
Range.Adress
Esta propiedad devuelve un valor de tipo String que representa la referencia del rango en el
lenguaje de la macro. Su sintaxis es;
Range.Address(RowAbsolute, ColumnAbsolute, ReferenceStyle, External, RelativeTo)
RowAbsolute; Variable (true/false) que especifica si la fila se referencia de forma absoluta ($)
ColumnAbsolute; Variable (true/false) que especifica si la columna se referencia de forma absoluta ($)
ReferenceStyle; Constante (XlReferenceStyle) que define el estilo de la referencia (valor predeterminado - xlA1)
External; Variable que especifica si es una referencia externa (true) o local (false, predeterminado).
RelativeTo; Si RowAbsolute y ColumnAbsolute tienen el valor False y ReferenceStyle es xlR1C1, se debe incluir
un punto inicial para la referencia relativa. Este argumento es un objeto Range que define el punto inicial de la
referencia.
Con este ejemplo, obtenemos la referencia de la celda activa (con valores absolutos)
MsgBox ActiveCell.Adress
Para ver un ejemplo y entender mejor esta propiedad (muy importante), vamos a ver un ejemplo;
1. Abre un libro nuevo y selecciona un grupo de celdas en la Hoja1. Podemos colorear el interior de
las celdas para visualizar mejor el ejemplo.
2. Crea una nueva macro y pega el siguiente código (¡Con la selección aún activa!)
Sub Ejemplo_OffSet()
Dim MiRango As Range
Set MiRango = Selection.Offset(2, 2)
MiRango.Value = "Valor"
End Sub
En la siguiente imagen podemos ver lo que ocurre (el rango seleccionado inicialmente es B2:D9)
Range.Item
Representa un rango desplazado con respecto al rango especificado. Sin embargo nosotros vamos a
utilizar esta propiedad para movernos por las celdas del rango*. La sintaxis que utilizaremos será;
Range.Item(Index)
Index; representa la celda a la que se desea obtener acceso, por orden de izquierda a derecha y después hacia
abajo.
En el siguiente ejemplo, utilizamos la propiedad Item para acceder a cada una de las celdas del
rango.
Sub Ejemplo_Item()
Dim MiRango As Range
Dim i As Integer
Set MiRango = Range("A1:C2")
For i = 1 To 6
MiRango.Item(i).Value = "Celda " & i
Next i
End Sub
*Para una descripción más exacta de esta propiedad consultad la ayuda de VBA desde MS Excel.
Ejercicio 26
Abre el libro EjemploCombo1.xlsm que creamos anteriormente. Vimos que cuando introducíamos
datos, siempre lo hacía en la primera fila. Vamos a modificar el código para que cada vez que
introduzcamos un dato, lo hagamos en las celdas seleccionadas y la selección se mueva una fila
hacia abajo.
1. Al cargar el formulario (evento Initalize del UserForm) seleccionar las celdas A2:C2
2. Al pulsar el botón para introducir datos;
Referenciar la selección con un objeto de tipo Range
Introducir los valores de las cajas de texto y combos en las celdas utilizando la propiedad Item(Index)
Hacer que la selección avance una fila hacia abajo (con OffSet)
Ejercicio 27.
Abre el libro Terremotos1990.xlsx. Vamos a crear una macro que seleccione todos los terremotos
que se hayan producido un día 10. Copiaremos estos terremotos en una hoja nueva.
1. Para buscar en las diferentes celdas podemos utilizar;
“et Rg = Ra ge C ‘P i e a elda o alo del día del te e oto
Do until IsEmpty(Rg.value)
[código …]
Set Rg = Rg.Offset(1,0) ‘Nos o e os u a elda ha ía a ajo
Loop
Range.Count
Esta propiedad devuelve un entero largo (Long) con el número de celdas del rango especificado. Si
lo combinamos con las propiedades Range.Columns y Range.Rows podemos saber el número de
columnas y el de filas de un rango en concreto.
Range.Count —————— Número de celdas del rango especificado.
Range.End
Devuelve un objeto Range que representa la celda situada al final de la región que contiene el rango
fuente. Equivale a presionar las teclas FIN+FLECHA ARRIBA, FIN+FLECHA ABAJO,
FIN+FLECHA IZQUIERDA o FIN+FLECHA DERECHA. Su sintaxis es;
Range.End(Direction)
Direction; es una constante de tipo XlDirection que especifica la dirección de búsqueda.
Esta propiedad es muy útil para situarnos al principio o final de rangos. En el siguiente ejemplo
vamos a mover la celda activa a la última celda hacia la derecha de la región actual (equivale a
hacer FIN + Flecha Derecha).
Ra ge A1 .“ele t
Selection.End(XlToRight).Select
Con el siguiente ejemplo vamos a seleccionar todas las celdas hacia la derecha. Para ello
utilizaremos la propiedad Range(Cell1, Cell2).
Ra ge A .“ele t
Range(Selection, Selection.End(XlToRight)).Select
Range.CurrentRegion
Esta propiedad devuelve un objeto de tipo Range que representa la región actual del rango
especificado. El siguiente ejemplo selecciona la región actual a la que pertenezca la celda A1.
Ra ge A .“ele t
Selection.CurrentRegion.Select
Ejemplo; abre el libro Terremotos1990.xlsx. Vamos a ver las diferencias entre varios de los códigos
mostrados anteriormente. Vamos a crear dos macros; Macro1 y Macro2. Les daremos el código a
continuación para cada una de ellas.
Sub Macro2() Sub Macro1()
Dim Micelda As Range Dim Micelda As Range
Set Micelda = ActiveCell Set Micelda = ActiveCell
Range(Micelda, Micelda.End(xlToRight)).Select ActiveCell.CurrentRegion.Select
Range(Selection, Selection.End(xlDown)).Select End Sub
End Sub
Ahora prueba a seleccionar la celda A1, y ejecutar la primera Macro. Repite pero ahora ejecuta la
segunda. ¿Ves alguna diferencia?
Ahora en vez de seleccionar la celda A1, seleccionemos la D6. Ejecutemos la primera macro, y luego
la segunda ¿Observamos diferencias?
Ejercicio 28.
Abre de nuevo el libro del ejercicio 26. Vamos a modificar de nuevo el programa, para que al
iniciarse, la selección se coloque en las siguientes 3 columnas vacías. Para ello utilizaremos las
propiedades vistas anteriormente.
Ejercicio 29
Vamos a practicar un poco todo lo visto con un ejercicio.
Un compañero nuestro nos ha pasado una carpeta con libros de Excel correspondientes a datos de
terremotos en los alrededores de Granada (carpeta Datos Terremotos Granada). Vamos a hacer una
macro que combine todos los datos de todos los libros en uno solo.
1. A tes de ada ea u li o e la o lla ado Te e otos G a ada. ls guá dalo e la is a
carpeta. Lo volvemos a abrir y creamos la macro (haciendo esto cogeremos la ruta de este libro).
Para obtener la ruta podemos utilizar la propiedad de nuestro libro Te e otos G a ada. ls
Dim MiLibro As Workbook
Set MiLibro = ThisWorkbook
Ruta = MiLi o.Path & \
Función Dir
Esta función devuelve una variable String con el nombre de un archivo (si existe), o grupo de
archivos que coincida con un patrón. Su sintaxis es
Dir (nombre_Ruta, atributos)
Nombre_Ruta; representa el nombre de un archivo con su ruta completa
Atributos; Constante o expresión numérica, cuya suma especifica los atributos de archivo. (opcional)
Range.ColumnDifferences y Range.RowDifferences
Estos dos métodos devuelven un objeto Range que representa todas las celdas cuyo contenido es
diferente del de la celda de comparación de cada columna o fila respectivamente. Sus sintaxis son;
Range.ColumnDifferences(Comparison)
Range.RowDifferences(Comparison)
Sub DiferenciasFilas()
Dim MiRango As Range
Dim Rg As Range
Dim valor As Variant
Set MiRango = Range("A1").CurrentRegion
MiRango.RowDifferences(Range("A1")).Select
End Sub
Esté método también puede ser muy útil para seleccionar datos de una columna dada. Para ello el
rango deberá de ser solo la columna donde queremos buscar las diferencias. El siguiente ejercicio
nos muestra un ejemplo de ello.
Ejercicio 30.
Abre el libro Terremotos Granada.xlsm creado en el ejercicio anterior. Vemos que la columna G
contiene el tipo de terremoto. Los designados con LP corresponden a explosiones, y queremos
eliminarlos de nuestra tabla. Para ello haremos una macro que nos seleccione todos los terremotos
que sean L y los copie en una segunda hoja Terremotos ”uenos . Utilizar ColumnDifferences.
Type; tipo de relleno. Constante de tipo XlAutoFillType. (XlFillCopy –copia valores; XlFillFormat – copia
formatos; XlFillDefault – copia formulas [valor por defecto])
Ejercicio 31.
“bre el libro de Excel EjemploFormatos.xlsx . Hacer una macro que copie los formatos de la
primera fila con datos a las demás.
Range.Sort
Ordena un rango de valores. Su sintaxis es;
Range.Sort(Key1, Order1, Key2, Type, Order2, Key3, Order3, Header, OrderCustom, MatchCase,
Orientation, SortMethod, DataOption1, DataOption2, DataOption3)
Key1; Especifica el primer campo de ordenación, ya sea como nombre de rango (cadena) u objeto Range;
determina los valores que se deben ordenar.
Order1; Determina el criterio de ordenación para los valores especificados en Key1. Constante XlSortOrder.
Order2; Determina el criterio de ordenación para los valores especificados en Key2. Constante XlSortOrder.
Order3; Determina el criterio de ordenación para los valores especificados en Key3. Constante XlSortOrder.
Header; Especifica si la primera fila contiene información de encabezado. xlNo es el valor predeterminado.
Ordercustom; Especifica un entero en base uno que constituye la posición en la lista de criterios de ordenación
personalizados.
MatchCase; Se debe establecer en True para realizar una ordenación que distinga entre mayúsculas y
minúsculas, o en False para no tener en cuenta las mayúsculas y minúsculas al llevar a cabo la ordenación; no se
puede utilizar con tablas dinámicas.
Orientation; Especifica si la ordenación debe realizarse por filas o por columnas. Constante XlSortOrientation.
DataOption1; Especifica cómo se debe ordenar el texto del rango especificado en el parámetro Key1; no se
aplica a la ordenación de tablas dinámicas.
DataOption1; Especifica cómo se debe ordenar el texto del rango especificado en el parámetro Key2; no se
aplica a la ordenación de tablas dinámicas.
DataOption1; Especifica cómo se debe ordenar el texto del rango especificado en el parámetro Key3; no se
aplica a la ordenación de tablas dinámicas.
Ejercicio 32
“bre el libro de Excel ListaEspecies para ordenar.xlsx . Este libro representa un inventariado de
árboles de un jardín botánico en la que a cada especie se l ha asignano un número identificador y se
le ha medido la altura y el diámetro. Haz una macro que ordene el inventario según dos claves;
clave1 será el nombre de la especie, y la clave2 será o bien la altura o bien el diámetro (la macro nos
preguntará que clave queremos aplicar como clave2)