MACROS VBA EXCEL Objetos, propiedades y métodos Los objetos en Excel (VBA) son cosas. Una celda es un objeto, una hoja es un objeto, un libro es un objeto y de esta manera existen muchos más objetos en Excel. A esto lo conocemos como el modelo de objetos de Excel. Cada uno de los objetos de Excel tiene propiedades y métodos. Las propiedades son las características del objeto y los métodos son las acciones que el objeto puede hacer. Propiedades de un objeto Si una persona fuera un objeto de Excel sus propiedades serían el color de sus ojos, el color de su cabello, su estatura, su peso. De la misma manera, un objeto de Excel tiene propiedades por ejemplos, una celda (Range) tiene las propiedades valor (Value) y dirección (Address) entre muchas otras. Estas propiedades describen mejor al objeto. Métodos de un objeto Siguiendo con el ejemplo de una persona, si fuera un objeto de Excel sus métodos serían correr, caminar, hablar, dormir. Los métodos son las actividades o acciones que el objeto puede realizar. Los objetos de Excel se comportan de la misma manera que el ejemplo de una persona. Una celda (Range) tiene los métodos activar (Activate), calcular (Calculate), borrar (Clear) entre muchos más. Utilizando las propiedades y los métodos Para acceder a las propiedades y métodos de un objeto lo hacemos a través de una nomenclatura especial. Justo después del nombre del objeto colocamos un punto seguido del nombre de la propiedad o del método. Observa este ejemplo donde hacemos uso de la propiedad Value para la celda A1: Range("A1").Value = "Hola" De esta manera asignamos una cadena de texto al valor de la celda A1. Ahora bien, si queremos borrar ese valor que acabamos de colocar en la celda podemos utilizar el método Clear de la siguiente manera: Range("A1").Clear Ver todas las propiedades y métodos Los objetos tienen muchas propiedades y métodos y a veces es difícil pensar que los llegaremos a memorizar todos por completo. Sin embargo, el Editor de Visual Basic es de gran ayuda porque justamente al momento de escribir nuestro código nos proporciona la lista completa de propiedades y métodos para un objeto. Esto sucede al momento de introducir el punto después del nombre del objeto. Puedes distinguir entre las propiedades y métodos porque tienen iconos diferentes. En la imagen de arriba los métodos son los que tienen el icono de color verde. Recuerda, los objetos son cosas en Excel y sus características las llamamos propiedades las cuales nos ayudan a definir al objeto. Los métodos son las acciones que cada objeto puede realizar. VBA – Objeto Worksheets La colección Worksheets es el conjunto de todos los objetos Worksheet de un libro especificado o activo. Las colecciones son objetos por sí mismos. El objeto WorkSheet representa una hoja de cálculo. El objeto Worksheet también es un miembro de la colección Sheets. La colección Sheets contiene todas las hojas del libro (hojas de gráficos y hojas de cálculo). En la jerarquía de objetos de Excel los objetos pueden actuar como recipientes de otros objetos. Un objeto Workbook puede contener otros objetos como Worksheet y Chart. Un objeto Worksheet puede contener objetos como Range, Pivot Table entre otros. Así, se puede hacer referencia a la Hoja1 del Libro1 del siguiente modo: Aplication.Worbooks(“Libro1.xlsx”).Worksheets(“Hoja1”) Se usa Worksheets(índice), donde índice es el nombre o número índice de la hoja de cálculo, para obtener un solo objeto Worksheet. El número de índice de la hoja de cálculo representa la posición de la hoja en la barra de fichas del libro. Worksheets(1) es la primera hoja (en el extremo izquierdo) del libro y Worksheets(Worksheets.Count) es la última. Propiedades del objeto Worksheets Las principales propiedades y su descripción se encuentran en la Ayuda Excel y son: Application, Count, HpageBreaks, Item, Parent, Visible y VpageBreaks Detalle de uso de: Worksheets.Visible (propiedad) Devuelve o establece un valor de tipo Variant que determina si el objeto es visible. Sintaxis expresión.Visible expresión: Variable que representa un objeto Worksheet. Ejemplo: Con el siguiente código se oculta la hoja de cálculo 1 de un libro activo: Worksheets(1).Visible=False Métodos del objeto Worksheets Las principales métodos y su descripción se encuentran en la Ayuda Excel y son: Add, Copy, Delete, FillAcrossSheets, Move, PrintOut, PrintPreview y Select. Detalle de uso de: Worksheets.Add (método) Crea una hoja de cálculo, un gráfico o una hoja de macros. La nueva hoja de cálculo se convierte en la hoja activa. Sintaxis expresión.Add(Before, After, Count, Type) expresión : Variable que representa un objeto Worksheets. Los parámetros son opcionales (Before/After especifica las hoja antes/después de la cual se agregará la hoja, Count por default es 1 y Type por default es una hoja de cálculo) Ejemplo: Se creará una nueva hoja en el libro activo y que será colocada a la derecha de todas las demás hojas, mediante la siguiente sintaxis: Sub Agregar() Dim Hoja As Worksheet Set Hoja = Worksheets.Add(After:=Sheets(Worksheets.Count)) End Sub Esta macro crea una nueva hoja y la coloca después de la última hoja, a la cual hacemos mención con “Sheets(Worksheets.Count)”. Algunos ejemplos: 1. Cómo seleccionar una celda en la hoja activa Para seleccionar la celda D5 en la hoja activa, puede utilizar cualquiera de los ejemplos siguientes: ActiveSheet.Cells(5, 4).Select -o bienActiveSheet.Range("D5").Select 2. Cómo seleccionar una celda en otra hoja del mismo libro Para seleccionar la celda E6 en otra hoja del mismo libro, puede utilizar cualquiera de los ejemplos siguientes: Application.Goto ActiveWorkbook.Sheets("Sheet2").Cells(6, 5) O bien, Application.Goto (ActiveWorkbook.Sheets("Sheet2").Range("E6")) O bien, puede activar la hoja y usar el método 1 anterior para seleccionar la celda: Sheets("Sheet2").Activate ActiveSheet.Cells(6, 5).Select 3. Cómo seleccionar una celda en una hoja de un libro diferente Para seleccionar la celda F7 en una hoja de un libro diferente, puede utilizar cualquiera de los ejemplos siguientes: Application.Goto Workbooks("BOOK2.XLS").Sheets("Sheet1").Cells(7, 6) O bien, Application.Goto Workbooks("BOOK2.XLS").Sheets("Sheet1").Range("F7") O bien, puede activar la hoja de cálculo y, a continuación, usar el método 1 anterior para seleccionar la celda: Workbooks("BOOK2.XLS").Sheets("Sheet1").Activate ActiveSheet.Cells(7, 6).Select 4. Cómo seleccionar un rango de celdas en la hoja activa Para seleccionar el rango C2:D10 en la hoja activa, puede utilizar cualquiera de los ejemplos siguientes: ActiveSheet.Range(Cells(2, 3), Cells(10, 4)).Select ActiveSheet.Range("C2:D10").Select ActiveSheet.Range("C2", "D10").Select 5. Cómo seleccionar un rango de celdas en otra hoja del mismo libro Para seleccionar el rango D3:E11 en otra hoja del mismo libro, puede utilizar cualquiera de los ejemplos siguientes: Application.Goto ActiveWorkbook.Sheets("Sheet3").Range("D3:E11") Application.Goto ActiveWorkbook.Sheets("Sheet3").Range("D3", "E11") O bien, puede activar la hoja y usar el método 4 anterior para seleccionar el rango: Sheets("Sheet3").Activate ActiveSheet.Range(Cells(3, 4), Cells(11, 5)).Select 6. Cómo seleccionar un rango de celdas en una hoja de un libro diferente Para seleccionar el rango E4:F12 en una hoja de otro libro, puede utilizar cualquiera de los ejemplos siguientes: Application.Goto Workbooks("BOOK2.XLS").Sheets("Sheet1").Range("E4:F12") Application.Goto _ Workbooks("BOOK2.XLS").Sheets("Sheet1").Range("E4", "F12") O bien, puede activar la hoja y usar el método 4 anterior para seleccionar el rango: Workbooks("BOOK2.XLS").Sheets("Sheet1").Activate ActiveSheet.Range(Cells(4, 5), Cells(12, 6)).Select 7. Cómo seleccionar un rango con nombre en la hoja activa Para seleccionar el rango con nombre "Test" de la hoja activa, puede utilizar cualquiera de los ejemplos siguientes: Range("Test").Select Application.Goto "Test" 8. Cómo seleccionar un rango con nombre en otra hoja del mismo libro Para seleccionar el rango con nombre "Test" en otra hoja del mismo libro, puede utilizar el ejemplo siguiente: Application.Goto Sheets("Sheet1").Range("Test") O bien, puede activar la hoja y usar el método 7 anterior para seleccionar el rango con nombre: Sheets("Sheet1").Activate Range("Test").Select 9. Cómo seleccionar un rango con nombre en una hoja de un libro diferente Para seleccionar el rango con nombre "Test" en una hoja de otro libro, puede utilizar el ejemplo siguiente: Application.Goto _ Workbooks("BOOK2.XLS").Sheets("Sheet2").Range("Test") O bien, puede activar la hoja y usar el método 7 anterior para seleccionar el rango con nombre: Workbooks("BOOK2.XLS").Sheets("Sheet2").Activate Range("Test").Select 10. Cómo seleccionar una celda relativa a la celda activa Para seleccionar una celda que se encuentra cinco filas más abajo y cuatro columnas a la izquierda de la celda activa, puede utilizar el ejemplo siguiente: ActiveCell.Offset(5, -4).Select Para seleccionar una celda que se encuentra dos filas más arriba y tres columnas a la derecha de la celda activa, puede utilizar el ejemplo siguiente: ActiveCell.Offset(-2, 3).Select Nota: se producirá un error si intenta seleccionar una celda que esté "fuera de la hoja de cálculo". El primer ejemplo anterior devolverá un error si la celda activa se encuentra entre en las columnas A y D, ya que si se mueve cuatro columnas a la izquierda, la celda activa se desplazaría a una dirección de celda no válida. 11. Cómo seleccionar una celda relativa a otra celda (que no sea la celda activa) Para seleccionar una celda que se encuentra cinco filas más abajo y cuatro columnas a la derecha de la celda C7, puede utilizar cualquiera de los ejemplos siguientes: ActiveSheet.Cells(7, 3).Offset(5, 4).Select ActiveSheet.Range("C7").Offset(5, 4).Select 12. Cómo seleccionar un rango de celdas separadas por un rango específico Para seleccionar un rango de celdas que sea del mismo tamaño que el rango con nombre "Test" pero que estén desplazadas cuatro filas más abajo y tres columnas a la derecha, puede utilizar el ejemplo siguiente: ActiveSheet.Range("Test").Offset(4, 3).Select Si el rango con nombre está en otra hoja (que no sea la activa), active primero esa hoja y, a continuación, seleccione el rango con el ejemplo siguiente: Sheets("Sheet3").Activate ActiveSheet.Range("Test").Offset(4, 3).Select 13. Cómo seleccionar un rango especificado y cambiar el tamaño de la selección Para seleccionar el rango con nombre "Database" y, a continuación, extender la selección cinco filas, puede utilizar el ejemplo siguiente: Range("Database").Select Selection.Resize(Selection.Rows.Count + 5, _ Selection.Columns.Count).Select 14. Cómo seleccionar un rango especificado, desplazarlo y cambiar su tamaño Para seleccionar un rango cuatro filas más abajo y tres columnas a la derecha del rango con nombre "Database" e incluir dos filas y una columna más que el rango con nombre, puede utilizar el ejemplo siguiente: Range("Database").Select Selection.Offset(4, 3).Resize(Selection.Rows.Count + 2, _ Selection.Columns.Count + 1).Select 15. Cómo seleccionar la unión de dos o más rangos especificados Para seleccionar la unión (es decir, el área combinada) de los dos rangos con nombre "Test" y "Sample", puede utilizar el ejemplo siguiente: Application.Union(Range("Test"), Range("Sample")).Select Tenga en cuenta que ambos rangos deben estar en la misma hoja para que este ejemplo funcione. Observe también que el método Union no funciona entre diferentes hojas. Por ejemplo, esta línea funciona correctamente Set y = Application.Union(Range("Sheet1!A1:B2"), Range("Sheet1!C3:D4")) Pero esta línea Set y = Application.Union(Range("Sheet1!A1:B2"), Range("Sheet2!C3:D4")) Devuelve el mensaje de error: Error en la clase de aplicación del método Union 16. Cómo seleccionar la intersección de dos o más rangos especificados Para seleccionar la intersección de los dos rangos con nombre "Test" y "Sample", puede utilizar el ejemplo siguiente: Application.Intersect(Range("Test"), Range("Sample")).Select Tenga en cuenta que ambos rangos deben estar en la misma hoja para que este ejemplo funcione. Los ejemplos 17 a 21 de este artículo hacen referencia al siguiente conjunto de datos de ejemplo. En cada ejemplo se especifica el rango de celdas de los datos del ejemplo que se seleccionarían. A1: A2: A3: A4: A5: R6: Nombre a b c Total B1: Ventas B2: $10 B3: B4: $10 B5: B6: $20 C2: C3: C4: C5: C6: C1: Cantidad 5 10 5 20 17. Cómo seleccionar la última celda de una columna de datos contiguos Para seleccionar la última celda de una columna contigua, utilice el ejemplo siguiente: ActiveSheet.Range("a1").End(xlDown).Select Cuando este código se utilice con la tabla de ejemplo, se seleccionará la celda A4. 18. Cómo seleccionar la celda en blanco en la parte inferior de una columna de datos contiguos Para seleccionar la celda situada debajo de un rango de celdas contiguas, utilice el ejemplo siguiente: ActiveSheet.Range("a1").End(xlDown).Offset(1,0).Select Cuando este código se utilice con la tabla de ejemplo, se seleccionará la celda A5 19. Cómo seleccionar un rango completo de celdas contiguas en una columna Para seleccionar un rango de celdas contiguas en una columna, utilice uno de los ejemplos siguientes: ActiveSheet.Range("a1", ActiveSheet.Range("a1").End(xlDown)).Select O bien, ActiveSheet.Range("a1:" & ActiveSheet.Range("a1"). _ End(xlDown).Address).Select Cuando este código se utilice con la tabla de ejemplo, se seleccionarán las celdas A1 a A4. 20. Cómo seleccionar un rango completo de celdas que no sean contiguas en una columna Para seleccionar un rango de celdas que no sean contiguas en una columna, utilice uno de los ejemplos siguientes: ActiveSheet.Range("a1",ActiveSheet.Range("a65536").End(xlUp)).Select O bien, ActiveSheet.Range("a1:" & ActiveSheet.Range("a65536"). _ End(xlUp).Address).Select Cuando este código se utilice con la tabla de ejemplo, se seleccionarán las celdas A1 a A6. 21. Cómo seleccionar un rango rectangular de celdas Para seleccionar un rango de celdas rectangular alrededor de una celda, utilice el método CurrentRegion. El rango seleccionado mediante el método CurrentRegion es un área limitada por cualquier combinación de filas en blanco y columnas vacías. A continuación se muestra un ejemplo de cómo utilizar el método CurrentRegion: ActiveSheet.Range("a1").CurrentRegion.Select Este código seleccionará las celdas entre A1 y C4. Otros ejemplos para seleccionar el mismo rango de celdas son los siguientes: ActiveSheet.Range("a1", _ ActiveSheet.Range("a1").End(xlDown).End(xlToRight)).Select O bien, ActiveSheet.Range("a1:" & _ ActiveSheet.Range("a1").End(xlDown).End(xlToRight).Address).Select En algunos casos, es posible que desee seleccionar las celdas entre A1 y C6. En este ejemplo, el método CurrentRegion no funcionará porque hay una línea en blanco en la fila 5. Los ejemplos siguientes seleccionarán todas las celdas: lastCol = ActiveSheet.Range("a1").End(xlToRight).Column lastRow = ActiveSheet.Cells(65536, lastCol).End(xlUp).Row ActiveSheet.Range("a1", ActiveSheet.Cells(lastRow, lastCol)).Select O bien, lastCol = ActiveSheet.Range("a1").End(xlToRight).Column lastRow = ActiveSheet.Cells(65536, lastCol).End(xlUp).Row ActiveSheet.Range("a1:" & _ ActiveSheet.Cells(lastRow, lastCol).Address).Select 22. Cómo seleccionar varias columnas no contiguas de longitud variable Para seleccionar varias columnas no contiguas de longitud variable, utilice la tabla de ejemplo siguiente y el ejemplo de macro: A1: 1 A2: 2 A3: 3 A4: A5: R6: B1: B2: B3: B4: B5: B6: 1 2 3 4 5 C1: C2: C3: C4: C5: C6: 1 2 3 4 5 6 D1: D2: D3: D4: D5: D6: 1 2 3 4 StartRange = "A1" EndRange = "C1" Set a = Range(StartRange, Range(StartRange).End(xlDown)) Set b = Range(EndRange, Range(EndRange).End(xlDown)) Union(a,b).Select Cuando este código se utilice con la tabla de ejemplo, se seleccionarán las celdas A1:A3 y C1:C6. NOTAS SOBRE LOS EJEMPLOS Normalmente se puede omitir la propiedad ActiveSheet, ya que se considera implícita si una hoja concreta no tiene nombre. Por ejemplo, en lugar de escribir ActiveSheet.Range("D5").Select puede utilizar: Range("D5").Select Generalmente también se puede omitir la propiedad ActiveWorkbook. A menos que se nombre un libro concreto, el libro activo se considera implícito. Cuando use el método Application.Goto, si desea utilizar dos métodos Cells dentro del método Range cuando el rango especificado esté en otra hoja (no en la activa), debe incluir el objeto Sheets cada vez. Por ejemplo: Application.Goto Sheets("Sheet1").Range( _ Sheets("Sheet1").Range(Sheets("Sheet1").Cells(2, 3), _ Sheets("Sheet1").Cells(4, 5))) Para cualquier elemento entre comillas (por ejemplo, el rango con nombre "Prueba"), también puede utilizar una variable cuyo valor sea una cadena de texto. Por ejemplo, en lugar de escribir: ActiveWorkbook.Sheets("Sheet1").Activate Puede utilizar ActiveWorkbook.Sheets(myVar).Activate Donde el valor de myVar es "Sheet1". VARIABLES Variables Locales Las variables Locales son aquellas que se declaran dentro de un módulo o procedimiento y sólo pueden ser utilizadas en éste. Éstas dejan de existir una vez que el procedimiento termina su ejecución. Se pueden usar en otros módulos o procedimientos pero sus características nada tienen que hacer con la declaración dada en otro módulo o procedimiento. Para declararlas se debe usar la sentencia DIM. Por ejemplo: Sub procedimiento() Dim nDat As Integer Dim Cadena As String Sentencias .... End Sub Variables Públicas Si se quiere que una variable esté disponible para todos los procedimientos de todos los módulos VBA de un proyecto, se la debe definir a través de la sentencia PUBLIC (y no DIM). Por ejemplo: Public NTotal As Integer Las variables públicas se deben definir antes del primer procedimiento de un módulo de VBA; no deben definirse en los módulos correspondientes a las hojas del Libro de Trabajo ni en los módulos correspondientes a UserForms. Variables Estáticas Si se desea que una variable definida en un procedimiento conserve su valor una vez terminado éste, e ingresado a otro procedimiento, ésta se debe definir a través de la sentencia STATIC. Por ejemplo: Sub Procedimiento() Static nDat As Integer [ Sentencias ...] End Sub Option Explicit La sentencia Option Explicit permite que el programa se detenga cada vez que VBA encuentre una variable que no ha sido definida. Esto es de gran utilidad cuando se usan muchas variables ya que nos permite identificar rápidamente errores o uso no deseado en el nombre de la variable. Esta sentencia se debe escribir al comienzo del módulo. Constantes A diferencia de las variables, cuyo valor cambia al ejecutarse un procedimiento, hay valores que no cambian durante la ejecución de un procedimiento, estos valores se denominan Constantes. Las constantes se definen a través de la sentencia Const. Por ejemplo; Const Nivel As Integer Las constantes también pueden declararse como Públicas para que estén disponibles en todos los procedimientos de todos los módulos, esto se hace a través de la sentencia PUBLIC Public Const TasaActiva As Integer Esta sentencia debe incluirse en un módulo antes del primer procedimiento. Para definir constantes Locales, basta definirlas sentencia Const dentro de un procedimiento o función. a través de la Módulos Un módulo es un ambiente, es un entorno de trabajo compuesto por sentencias de declaración de variables y por uno o más procedimientos. Procedimientos Un procedimiento está formado por un conjunto de sentencias que permite resolver un problema. Un módulo está formado por uno o más procedimientos. Un procedimiento se declara a través de la sentencia Sub y puede ser Privado,Público o Estático. Procedimiento Privado Un procedimiento privado sólo es accesible por otros procedimientos dentro del mismo módulo. Su sintaxis es: Private Sub Procedimiento (Argumento1,Argumento2,.....) [sentencias] End Sub Procedimiento Público Un procedimiento público es accesible por todos los procedimientos de todos los módulos VBA de un proyecto, su sintaxis es: Public Sub Procedimiento(Argumento1,Argumento2,.....) [Sentencias] End Sub Procedimiento Estático Para que las variables de un procedimiento se conserven una vez terminada su ejecución, éste debe definirse como Estático: Static Sub Procedimiento(Argumento1,Argumento2,.....) [Sentencias] End Sub La sentencia Sub y End Sub son obligatorias al definir cualquier procedimiento. Los argumentos y las sentencias Private, Public y Static son opcionales. Es importante mencionar que al definir un procedimiento sin ninguna de las sentencias anteriores, por defecto éste se define como Público, es decir: Sub Procedimiento(argumento1,argumento2,.....) [Sentencias] End Sub Es equivalente a : Public Sub Procedimiento(argumento1,argumento2,.....) [Sentencias] End Sub Existe una instrucción que permite terminar la ejecución de un procedimiento, ésta es la instrucción Exit Sub. Por ejemplo, si tenemos el siguiente procedimiento: Sub Procedimiento(argumento1,argumento2,.....) [Sentencias] Exit Sub [Sentencias] End Sub Llamar a un procedimiento desde otro Para llamar a un procedimiento desde otro procedimiento, se puede utilizar la sentencia Call o simplemente el nombre del procedimiento. Por ejemplo: Sub Proced1 (Argumento1,Argumento2,.....) [Sentencias] Proced2 [Sentencias] End Sub En este caso, el procedimiento Proced1 llama al procedimiento Proced2. La sentencia Call se utiliza cuando se requiere llamar a un procedimiento al cual hay que pasarle un argumento, por ejemplo: Sub Procedimiento1(argumento1,argumento2,.....) [Sentencias] indice= ........ Call Proced2(indice) [Sentencias] End Sub En este caso, el procedimiento Procedimiento1 llama al procedimiento Procedimiento2 al cual se le debe pasar el argumento índice. Es recomendable utilizar siempre la sentencia Call para llamar a otro procedimiento, aunque a éste no se le tengan que pasar argumentos, esto permite identificar más fácilmente las llamadas a otros procedimientos.