martes, 23 de enero de 2018

Las variables de objetos

En el VBA, al igual que en otros lenguajes de programación, un objeto representa un elemento de una aplicación; en el caso del Excel estos son las hojas, las celdas, los gráficos, los formularios de VBA (UserForm), etc. Los objetos de Excel tienen métodos, eventos y propiedades.

En muchas ocasiones es necesario usar objetos en nuestros procedimientos, para ello debemos declarar los objetos como variables. Las variables de objeto se declaran como cualquier otra solo que haciendo referencia al objeto. De este modo se puede establecer y/o cambiar sus propiedades o usar cualquiera de sus métodos:

'Objeto rango
 Dim MiCelda As Range
'Objeto hoja
Dim MiHoja As WorkSheet
'Objeto libro
Dim MiLibro As WorkBook 

En ocasiones quizá tengamos que declarar una variable de objeto con el tipo de datos “Object” pues quizá el tipo específico del objeto no se conoce. Este tipo hace referencia a cualquier objeto pero consume más recursos que un tipo específico:

Dim MiObjeto As Object

Para asignar valor (objetos) a este tipo de variable usaremos la instrucción “Set”:

Set MiCelda = Range("A1:A10") 
Set MiHoja = Worksheets("Hoja1") 

Una vez asignado el objeto a la variable, podemos hacer referencia y/o cambiar, por ejemplo, sus propiedades o valores:

MiCelda.Value = “Hola a todos” 
MiHoja.Name = "Nueva Hoja" 

En el primer caso asignamos la frase “Hola a todos” a todas las celdas del rango asignado al objeto “MiCelda” y en el segundo caso cambiamos la propiedad “Name” (el nombre) del objeto “MiHoja”.

Después de trabajar con nuestras variables de objeto, una buena costumbre es limpiar la variable y de ese modo dejar libre memoria (aunque al terminar la rutina las variables igual quedan libres y por ende la memoria). Para ello utilizaremos la instrucción “Nothing”:

Set MiCelda = Nothing 
Set MiHoja = Nothing 

Y esos son algunos consejos e indicaciones para que podamos trabajar con variables de objetos.

Hasta la próxima.

Abraham Valencia

miércoles, 10 de enero de 2018

El gran problema de los archivos lentos y "pesados"

Pasan los años, se crean versiones más modernas y potentes de Excel, pero entre los usuarios(as) sigue existiendo el gran problema de que se generan archivos que ocupan muchos megas y que se vuelven cada vez más lentos.

Excel es una hoja de cálculo parte del paquete de Office y, dependiendo del tipo de producto Office, viene acompañada de Access que, a pesar de las críticas, es un buen sistema gestor de base de datos (SGBD). Me imagino que algunas personas ya se estarán preguntando “¿y qué tiene que ver eso con los archivos “pesados” y lentos? Pues mucho.

Excel es una hoja de cálculo pero por su masivo uso y aparente mayor facilidad de aprenderlo que Access, es usada como SGBD ¿es necesariamente un error eso? No, pero a diferencia de los SGBD, no almacena los datos de forma “plana”  (como las tablas de los SGBD) sino que los datos almacenados en las hojas están acompañados de diversos formatos (de tipo o color de letra, de color de fondo, de color de bordes, etc.), de fórmulas, de imágenes y un largo etcétera de cosas. Eso, a la larga, genera que los archivos crezcan de modo muchas veces desmesurado y hasta se pongan lentos al cargar.  Esto, finalmente, no es un problema del Excel sino de los propios usuarios(as).

He aquí algunas de las causas, y soluciones,  que ocasionan esos problemas:

Uno:

Por una cuestión visual muchas veces le damos formatos que usan color a nuestros datos, ya sea al color de relleno de las celdas, al color de la fuente o algún otro que nos permita Excel. El problema con ello es que en lugar de dar el formato al rango de celdas que usamos, le damos formato a toda la columna o a toda la fila, o incluso en muchos casos a varias filas o columnas e incluso a todas las celdas de las hojas:

Un ejemplo de que no hacer:

Un segundo ejemplo de que no hacer:

Un ejemplo de que como se debe aplicar formatos:

Evitemos eso, demos el formato deseado solo al rango de celdas que estamos usando y sí vamos a ingresar más datos, esperemos a ello antes de aplicar los formatos que deseemos.

Dos:

En ocasiones se usa Excel prácticamente como catálogo de imágenes, no solo decenas sino hasta cientos de imágenes se insertan en sus hojas haciendo que los megas del archivo crezcan y crezcan. Lo primero es recomendar no usar Excel para mostrar imágenes y de insistir en ello al menos comprimirlas:

Eso ayudará en algo a evitar que su archivo sea demasiado “pesado”.


Tres:

Muchas veces se aplica fórmulas sobre columnas o filas completas y no solo sobre los rangos que tienes datos. No es raro ver fórmulas de estos tipos:
=SUMA(A:A)
Las fórmulas así, tienen que analizar cada una de las celdas de dicha columna, en este caso más de un millón de celdas cuando lo ideal es solo aplicarla sobre el rango con datos:
=SUMA(A2:A1232)
Cuatro:
Se usan fórmulas en celdas en las que no se esperan resultados porque se supone que a futuro dichas celda tendrán datos. A pesar de estar vacías, Excel igual analiza dichas celdas causando que se use más memoria y, como ya saben, poniendo lento el archivo además de incrementar su “peso”.  He visto archivos con 100 filas ocupadas y fórmulas en al menos diez mil filas.  Lo ideal es solo tener fórmulas en aquellas celdas que esperamos resultados inmediatos, asimismo en aquellas celdas en las que ya tenemos resultados y aquellos no van a cambiar, lo ideal es cambiar las fórmulas por los valores obtenidos, lo que se puede hacer fácil y rápidamente con “Pegado Especial”  y la opción de “Pegar Valores”.
De ser necesario que tengas muchas fórmulas, y de aquellas sí se espera resultado inmediato, lo ideal es cambiar el “Cálculo” a “Manual”.

 

Cinco:
Aunque hay varias cosas más he tratado de colocar algunas de las que considero son las principales pero igual, como para terminar, podríamos mencionar que es bueno, también, no usar muchas funciones volátiles como “HOY”, no hay que abusar de los “Formatos Condicionales” así como tampoco de las fórmulas matriciales.

Hasta la próxima.

Abraham Valencia

martes, 19 de diciembre de 2017

El indiscriminado uso de las variables tipo Variant

En un artículo anterior (https://abrahamexcel.blogspot.pe/2017/11/consejos-para-el-uso-de-variables-en.html) ya comentábamos sobre los constantes problemas de la mala declaración de variables o de no declararlas y como aquello consumía recursos innecesarios.

Cuando usamos variables y no las hemos declarado VBA les asigna, automáticamente, el tipo Variant. El tipo de variables Variant admite números enteros, decimales, texto y en general cualquier tipo de dato que podamos usar, pero es justamente esa capacidad la que hace que dicho tipo de variable requiera una gran cantidad de memoria. Las variables Variant reservan 22 bytes de la memoria (en algunos casos 16 bytes) y a eso hay que sumarle lo que ocupa el valor que le asignemos a la variable.

Para entenderlo mejor tratemos de ejemplificarlo pero primero recordemos que, de modo general, un carácter cualquiera ocupa 1 byte (hay variaciones por si acaso).  Entonces veamos:

Sub Probando ()
CadenadeTexto = “Abraham” 
End Sub 

Como no se declaró la variable “CadenadeTexto”, nuestro VBA le reservo 22 bytes de la memoria y al tener siete caracteres la palabra “Abraham”, en total la variable está ocupando 29 bytes.  Pero, veamos ahora que pasaría si declarábamos la variable de forma adecuada:

Sub Probando ()
Dim CadenadeTexto As String 
Let CadenadeTexto = “Abraham"
End Sub 

En ese caso, al ser del tipo String, se le reservó 10 bytes, a eso le sumamos los siete que ocupa la palabra y tenemos en total que nuestra variable ocupó 17 bytes, bastante menos que los 29 bytes que ocupó como tipo Variant.

¿Por eso deberíamos dejar de usar variables del tipo Variant? No necesariamente pero no es recomendable usar siempre ese tipo de variable cuando hay varias del tipo adecuado para nuestras necesidades  (String, Double, etc.). Como bien dicen muchos programadores, las características de las actuales computadoras permiten tener varios Gigabytes de memoria que, aparentemente, no harían que se perciba problema con el uso indiscriminado de las variables tipo Variant pero, no olvides que la programación no solo debería ser eficaz, sino que también debe de ser eficiente y además, nuestras macros no será lo único que ocupe la memoria de nuestra computadora.

Para terminar, hay ocasiones en que será necesario usar las variables del tipo Variant como cuando no tengamos la certeza, por algún motivo, de qué tipo de valores usarán nuestros usuarios finales.

Abraham Valencia

sábado, 2 de diciembre de 2017

El uso, y abuso, de Select y Selection en Excel (VBA)

Primero que nada debemos recordar que “Select” es un método del VBA de Excel que se aplica a objetos y que nos permite, justamente, seleccionarlos para, si deseamos, trabajar con y/o sobre ellos. Segundo, hay que recordar que “Selection” es una propiedad que representa la selección realizada, en ese momento, de algún objeto.

Un ejemplo muy común de su uso es el código generado por nuestra vieja amiga la “Grabadora de Macros”:

Un ejemplo de macro grabada en donde colocamos color de relleno a un rango de celdas:

Sub Macro1()
'
' Macro1 Macro
'
'
Range("A1:B6").Select
With Selection.Interior         
.Pattern = xlSolid 
.PatternColorIndex = xlAutomatic  
.Color = 65535         
.TintAndShade = 0 
.PatternTintAndShade = 0     
End With     
Range("A1").Select 
End Sub 

Para, sobre todo, quienes se inician en el mundo del VBA, definitivamente la grabadora es una herramienta muy útil y ayuda mucho a aprender el uso métodos y las propiedades de los objetos pero hay que saber que hay mucho código innecesario que termina, no solo alargando nuestra macro, sino que en muchos casos hace más lentos lo procesos. Por ejemplo, lo que nos ha generado la grabadora en el ejemplo anterior, podríamos dejarlos así:

Sub Mi_Macro()
Range("A1:B6").Interior.Color = 65535 
End Sub 

Como se puede ver, no es necesario el uso de “Select” o de “Selection” para conseguir el mismo resultado, las propiedades de los objetos, en este caso un objeto “Range” (Rango), pueden ser modificadas sin necesidad de seleccionarlo.

Un ejemplo más como para que nos quede totalmente claro. Activamos la grabadora y borramos el contenido de un grupo de celdas:

Sub Macro4()
'
' Macro4 Macro
'
'
Range("A1:H5").Select
Selection.ClearContents 
End Sub 

Para, sobre todo, quienes se inician en el mundo del VBA, definitivamente la grabadora es una herramienta muy útil y ayuda mucho a aprender el uso métodos y las propiedades de los objetos pero hay que saber que hay mucho código innecesario que termina, no solo alargando nuestra macro, sino que en muchos casos hace más lentos lo procesos. Por ejemplo, lo que nos ha generado la grabadora en el ejemplo anterior, podríamos dejarlo así:

Sub BorrandoCeldas()
Range("A1:H5").ClearContents 
End Sub 

Aunque solo son dos líneas, podría quedar en una sola y además no olvidemos que es menos tiempo, y recursos en general, si no seleccionamos los objetos.

A veces nos acostumbramos tanto a seleccionar los objetos que aún sin usar la grabadora continuamos haciéndolo. He visto eso, sobre todo, cuando de copiar y pegar celdas se trata:

Sheets(“Hoja1”).Select 
Range(“A1:A10”).Select
Selection.Copy
Sheets(“Hoja2”).Select
Range(“D1”).Select
ActiveSheet.Paste

Todas esas líneas podríamos dejarlas de la siguiente forma sin recurrir a seleccionar objetos:

Sheets(“Hoja1”).Range(“A1:A10”).Copy Destination:= Sheets(“Hoja2”).Range(“D1”)  

Entonces, evitemos, de ser posible tanto el uso de “Select” como de “Selection”. Hasta la próxima.

Abraham Valencia