Trucos y Tretas en Excel VBA para Programadores

Descargar como docx, pdf o txt
Descargar como docx, pdf o txt
Está en la página 1de 18

Trucos y tretas en Excel VBA para

programadores
Comstar
(13/12/2011)17 comentarios
Este post no está hecho para novatos que no sepan nada del macros de Excel,
sino aquellos que saben algo de programación de Visual Basic. Si eres neófito en
macros de Excel en Visual Basic, deberías ver mi post Excel VBA y macros: Una
herramienta muy útil para trabajar hojas de cálculo (1). Me han de perdonar la
manera en que aparece el código, pero es un problema en la manera en que
aparece el código HTML para desplegar código con indentación en este sitio.
Especialmente en finanzas o en bolsa, pero también en negocios de todo tipo,
programar macros de Excel suele ser sumemante útil y por eso he querido deicar
este post a transmitir algunos trucos para ahorrarte tiempo. Cuando programamos
código para macros de Excel VBA a menudo nos encontramos con que los
detalles de cómo invocar tal o cual cosa de Excel termina siendo muy críptica y
debes navegar por foros, tutoriales o incontables páginas ininteligibles de
Microsoft que no te responden lo que andas buscando.
X
by Counterflix
Si sabes Visual Basic, lo más lógico es que para elaborar macros, trates de grabar
una macro primero, y luego empiezas a ver el código de muestra para ver cómo
hacer determinadas cosas. En este post se pretende proveer trucos de
programación en Excel VBA para efectuar tareas que no se pueden derivar del
código grabado en una macro en Excel. Estos trucos son el resultado de resolver
una serie de problemas que en su momento significaron un dolor de cabeza.

Obtener valor de una celda


Cells(4,5)=23
x = Cells(4,5)+1
Este ejemplo inserta el valor 23 en la celda de la fila 4 y columna 5. Luego la
variable x toma ese valor y le suma 1. Cabe añadir que cada vez que llamamos
una celda, una cantidad muy grande de código de Excel es invocada, de modo
que si piensas trabajar con muchas celdas o muchas veces con la misma
celda, es mejor que pases los valores a variables, en lugar de llamar a la celda en
sí misma.
Cells(2,3).Select
Selection.HorizontalAlignment = xlCenter
Selection.VerticalAlignment = xlCenter

En este ejemplo, la celda de la fila 2 columna 3 es seleccionada, y la selección


luego es objeto de centrado vertical y horizontal usando Selection.
Usando rangos
Pasar de la notación de fila y columna a la de celdas suele ser un poco
incómodo. Normalmente para seleccionar un rango usaríamos algo como esto:

Range("A5:B8").Select
Como has visto, lo que está procesando la función Range() entre comillas es una
hilera de caracteres. Para efectos de escribir código, podemos usar esta expresión
equivalente:
Range(Cells(5,1),Cells(8,2)).Select
Convertir números en letras (pasar de la notación fila 5 columna 1 a "A5") suele
ser sumamente incómodo. Para ello he construido una función que hace el trabajo.

Private Function GetColumnLetter(index) As String


Dim FL, LL As Long

GetColumnLetter = ""
LL = (index - 1) Mod 26 + 65
If LL > 63 Then GetColumnLetter = Chr(LL)
If index > 26 Then
FL = Int((index - 1) / 26) + 64
GetColumnLetter = Chr(FL) & GetColumnLetter
End If

End Function
La función convierte el número en letras, en caracteres. Cabe anotar que sólo
sirve para llegar hasta columna ZZ, de modo que si se pasa de esa columna, esta
función no te servirá. Para llamar esta función con las mismas coordenadas (5,1) y
(8,2) harías algo como esto para convertir en hilera:

Range(GetColumnLetter(5) & Format(1,"0") & ":" & GetColumnLetter(8) &


Format(2,"0")).Select
Como habrás notado he usado la función Format() que evita que se agreguen
espacios al convertir de número a hilera, como pasaría con la función Str().
Ventana emergente para que el usuario
ingrese un rango

Si quieres que aparezca una ventana emergente con la cual puedas pedir al
usuario que seleccione un rango de datos, puedes usar el código que se muestra
a continuación. Lo que se hace es declarar un objeto de
tipo Range llamado celdasSeleccionadas. A ese objeto se le asigna el resultado
de la función Application.InputBox que despliega la ventana emergente que solicita
la información al usuario. Si el usuario no ingresa ningún rango, el valor que
tendrá el objeto es Nothing.
El comando On Error Resume Next indica que si ocurre un error, entonces ignore
el error y proceda conla siguiente instrucción. El comando On Error Goto 0 indica
que se cancela la detección de errores. El comando Msgbox despliega
información en una ventana emergente.
He aquí el código:

Dim celdasSeleccionadas As Range

On Error Resume Next


Set celdasSeleccionadas = Application.InputBox(prompt:="Seleccione un
rango de celdas", Type:=8)
On Error GoTo 0
If celdasSeleccionadas Is Nothing Then
'Aquí va el código que se ejecuta si no se selecciona ninguna
celda.
'En este caso se despliega una ventana emergente con un mensaje.
MsgBox "No se ha seleccionado ninguna celda."
Else
'Aquí va el código que se ejecuta si se se seleccionó celdas.
'En este caso se despliega una ventana emergente con el resultado
de la suma de celdas.
MsgBox
Application.WorksheetFunction.Sum(celdasSeleccionadas.Cells)
End If

Como habrás notado en este código lo que se hace si el usuario digita un código
es desplegar el valor de la suma de todos los valores del rango usando la
función Application.WorksheetFunction.Sum, pero tú puedes hacer que haga algo
distinto.
Si quisieras obtener el valor contenido en el rango seleccionado puedes usar este
código.

MiVariable = celdasSeleccionadas.Value

En este caso el contenido del rango se almacena en una variable


llamada MiVariable.
Acelerar la ejecución
Cuando un programa corre, todo lo que tiene que ver con actualización de pantalla
es sumamente lento, y lo mejor es desconectar toda actualización de video. Para
ello debes agregar el siguiente código al inicio de la macro.

Application.ScreenUpdating = False
Application.DisplayStatusBar = True
Application.StatusBar = "Iniciando..."
Y este código al final.

Application.ScreenUpdating = True
Application.StatusBar = "Ejecución terminada."
Application.ScreenUpdating se encarga de encender y apagar la actualización de
video. Application.DisplayStatusBar = True habilita la barra de estado que está en
la parte inferior de la ventana de Excel, y allí despliegas mensajes asignando una
hilera a Application.StatusBar. La idea de usar la barra de estado es que si la
ejecución de la macro tarda mucho, es bueno que el usuario sepa que la macro
está trabajando, y que no se ha quedado atascada.
No hay nada que fastidie más que tener un programa atascado frente a uno. Por
eso sería bueno que dentro de la macro agregues otros mensajes donde el
usuario pueda ver que la macro va caminando, pero si pones mensajes con
demasiada frecuencia eso ralentizará la ejecución, porque como dijimos, la
actualización de video consume mucho tiempo de la máquina.
X
by Counterflix
Esto es especialmente útil cuando vas a correr una macro que pasa de un libro de
Excel a otro o que se mueve mucho a lo largo de las páginas o celdas de manera
muy intensiva.

Obtener posición de la última celda


Cuando tienes hojas de Excel de tamaño variable y necesitas ubicar la última
celda ocupada (la que está más abajo y más a la derecha), puedes usar lo
siguiente:

ActiveCell.SpecialCells(xlLastCell).Select
UltimaFila = ActiveCell.Row
UltimaColumna = ActiveCell.Column
Si buscas en Internet acerca de cómo obtener posición de la última celda,
encontrarás maneras muy diversas. Sin embargo, esta es la mejor que he
encontrado. Si agregas valores más allá de la última celda, el valor se
actualiza. El único problema es que si borras filas o columnas, este número no
cambiará, sino hasta que abras de nuevo el archivo de Excel. Sin embargo eso es
mejor que nada, y puedes verificar si encuentras celdas en blanco, así que eso no
debería ser problema.

Obtener los nombres de libros de Excel


abiertos.
En ocasiones ocupas una lista de los libros de Excel que están abiertos. Para ello
te vales del objeto Workbooks de Excel.
Dim NombreDeArchivo() as String

Redim NombreDeArchivo(Workbooks.Count-1)
For i = 1 To Workbooks.Count
NombreDeArchivo(i-1) = Workbooks.Item(i).Name
Next i
El arreglo NombreDeArchivo almacenará los nombres de los archivos de Excel
que están abiertos en un momento dado.
Obtener la lista de páginas del libro de
Excel
Puedes usar el siguiente código.

Dim NombreDePagina()
Dim Cantidad as Long

Cantidad = Sheets.Count
redim NombreDePagina(n)
For i = 1 To Cantidad
NombreDePagina(i) = Sheets(i).Name
Next i
Los nombres se almacenan en el arreglo NombreDePagina.
Obtener los nombres de las gráficas
(charts) que hay en una página de Excel
Hay ocasiones en que ocupas buscar todas las gráficas contenidas en una página
de Excel. para ello te vales de ActiveSheet.ChartObjects

Dim NombreDeChart()

Redim NombreDeChart(ActiveSheet.ChartObjects.Count-1)
For i = 1 To ActiveSheet.ChartObjects.Count
NombreDeChart(i-1) = ActiveSheet.ChartObjects(i).Name
Next i
El arreglo NombreDeChart contendrá los nombres de las gráficas de la hoja de
Excel en que nos encontramos.
Obtener el nombre del libro de Excel en
que te encuentras actualmente
Existen algunas situaciones donde ocupas saber el nombre del libro de Excel en
que te encuentras actualmente.

LibroActual = ActiveWorkbook.Name
El nombre de la hoja actual será guardado en la variable LibroActual.
Cambiar de libro o de hoja
Si deseas pasarte a otro libro abierto u otra hoja, puedes usar el siguiente código.

Workbooks("MiLibro.xls").Activate
Sheets("Sheet1").Select
Este código hará que te pases al libro de Excel MiLibro.xls y a la página Sheet1 de
ese libro. Como ves, el valor entre comillas puede ser reemplazado por una
variable tipo String si lo deseas.
Cómo lidiar con libros de
Excel protegidos por password
If ActiveSheet.ProtectContents Then
ActiveSheet.Unprotect Password:="XYZ"
End If
Este código se encargará de eliminar la protección contra password. En este caso
el password es XYZ. Cuando trabajas con hojas protegidas con password,
obtendrás errores al tratar de acceder a material protegido y por eso debes
desproteger la hoja para trabajar en ella.

Enviar un correo con archivo adjunto


Si quieres generar un correo y pegarle un archivo adjunto, puedes usar
el siguiente código:

Dim oLook As Object


Dim oMail As Object

Set oLook = CreateObject("Outlook.Application")


Set oMail = oLook.createitem(0)
With oMail
.To = "[email protected]"
.body = "Este es el cuerpo del mensaje. Ver archivo adjunto"
.Subject = "Asunto. Envio de archivo adjunto"
.Attachments.Add ("C:\MiArchivo.xlsx")
.Send
End With

Set oMail = Nothing


Set oLook = Nothing
Este código buscará el archivo MiArchivo.xlsx ubicado en C:\, construirá el
mensaje y lo enviará a la dirección [email protected]. La lógica de este
código usa un poco de programación orientada a objetos. oLook es un objeto que
se encarga de manejar la aplicación Outlook, y oMail es un objeto que se encarga
de manejar el correo.

Ocultar una hoja e impedir que el


usuario la vea
Si quieres ocultar una hoja de Excel para que el usuario no la pueda ver, y no
pueda mostrar su contenido usa este código:

Set hide_sheet = Sheet1


hide_sheet.Columns.Hidden = True
hide_sheet.Visible = False
El código lo que hace es ocultar todas las columnas de la hoja Sheet1 y luego
oculta la hoja. Cabe notar que Sheet1 no es el nombre de la hoja visible para el
usuario, sino el nombre del objeto que aparece en el editor de código de Excel
VBA fuera de los paréntesis.

Crear un botón en una hoja de cálculo


Si quieres crear un botón:
ActiveSheet.Buttons.Add ActiveCell.Left, ActiveCell.Top,
ActiveCell.Width, ActiveCell.Height
El código crea un botón sobre la celda en la que estás ubicado actualmente.

Cargar, refrescar, salvar y cerrar una


hoja de cálculo
Si quieres efectuar esas tareas:

Workbooks.Open Filename:="C:\MiArchivo.xlsx", UpdateLinks:=3


Workbooks("MiArchivo.xlsx").RefreshAll
ActiveWorkbook.Save
ActiveWindow.Close
El código efectúa las cuatro tareas descritas en ese orden.

Cómo usar el portapapeles


El portapapeles no viene incluido en la versión básica de Excel VBA, así que
primero tenemos que configurar algunas cosas.
 Ve al editor de Visual Basic (Alt F11).
 Selecciona Tools > References
 Activa Microsoft Forms Object Library y presiona Ok.

Si no aparece Microsoft Forms 2.0 Object Library en la lista, quizás quieras usar el
botón Browse para buscar el archivo FM20.DLL que se encuentra en la ubicación
en disco duro que se muestra en la imagen.
Ahora que ya configuramos todo, veamos el código.
Primero deberías declarar el objeto de portapapeles (en este caso le llamaremos
doClip)
Dim doClip As DataObject
Este sería el método para crear el portapapeles en memoria.
Sub CrearClipboard()
Set doClip = New DataObject
End Sub

Con este método puedes destruir el objeto portapapeles en memoria para liberar
espacio.
Sub DestruirClipboard()
Set doClip = Nothing
End Sub

Con este método copias un texto al portapapeles.

Sub CopiarAlClipboard(sTexto As String)


doClip.Clear
doClip.SetText sTexto
doClip.PutInClipboard
End Sub
Con esta función extraes el texto del portapapeles.

Function ClipboardTexto() As String


doClip.GetFromClipboard
ClipboardTexto = doClip.GetText
End Function

Cómo configurar área de impresión


Para configurar el área de impresión ocupas la orientación portrait o
landscape. He puesto las muestras de las líneas para ambos casos, aunque tú
sólo ocuparías una. Si vas a ajustar a una o más páginas horizontal o
verticamente, primero necesitas poner el modo Zoom en apagado y luego puedes
configurar los ajustes. Y también debes delimitar el área de impresión que en este
ejemplo es desde A1 hasta H25.

ActiveSheet.PageSetup.Orientation = xlPortrait
ActiveSheet.PageSetup.Orientation = xlLandscape

ActiveSheet.PageSetup.Zoom = False
ActiveSheet.PageSetup.FitToPagesWide = 1
ActiveSheet.PageSetup.FitToPagesTall = 1
ActiveSheet.PageSetup.PrintArea = "A1:H25"

Cómo crear una lista de archivos y


directorios
Para obtener una lista de archivos, ve al siguiente sitio: List all files in a directory.
Para listar archivos y subdirectorios ve al sitio List folders and subdirectories.
Otros trucos
Existen trucos para optimizar el desempeño de Visual Basic, tales como:
 Evitar al máximo el uso de propiedades de controles. Las celdas de Excel son
controles. Los forms (formulario, ventana) y los controles sobre un form son
controles. Usar propiedades de controles agrega mucha carga de procesamiento
innecesario. Por ejemplo, el valor de una celda es una propiedad del control
llamado celda. El texto de un control de texto es una propiedad. Hay que
minimizar la referencia a controles hasta donde sea posible, pasando los valores
de los controles a una variable, se trabaja todo en la variable, y al final se actualiza
la propiedad del control con el valor final de la variable.
 Apaga la actualización de video, porque el tiempo de actualizar la pantalla
innecesariamente consume enormes cantidades de tiempo de procesamiento.
 Evitar el uso de variables tipo Variant. Estas variables generalmente aparecen
cuando no se declaran las variables. Para hacer que el Visual Basic muestre un
error cuando vea variables no declaradas, puedes poner esto al inicio de cada
módulo.
Trucos y tretas en Excel VBA para
programadores (usando clases y objetos)
Comstar
(10/11/2014)2 comentarios
Este post no está hecho para novatos que no sepan nada del macros de Excel,
sino aquellos que saben algo de programación de Visual Basic. Si eres neófito en
macros de Excel en Visual Basic, deberías ver mi post Excel VBA y macros: Una
herramienta muy útil para trabajar hojas de cálculo (1).
En este post asumo que ya conoces las bases sobre cómo declarar variables a
nivel de módulo y a nivel de procedimiento, y que dominas los conceptos sobre
construcción de procedimientos (también llamados métodos o subrutinas). Si no
los conoces, puedes preguntar aquí. Empecemos...

¿Se puede usar objetos en Excel VBA?


El lenguaje Visual Basic es una versión para Windows del BASIC. Visual Basic
incorpora programación estructurada y objetos, un lenguaje que se deriva del
Fortran.
Como hemos visto en post anteriores, en Visual Basic para Aplicaciones en Excel
(Excel VBA) es posible programar usando programación estructurada, pero llega
un momento en que manejar demasiadas cosas a la vez resulta extremadamente
complicado (y además permite muchos errores). Para simplificar, existe la
programación basada en objetos (OOP, Object Oriented Programming).
X
by Counterflix
No es tan fácil crear un objeto en Excel VBA como en C++, pues tendrás que
escribir mucho más, y el manejo de objetos no te permite administrar memoria con
el control absoluto que el uso de punteros da en C++. Es como tener un coche
automático, donde no tienes tanto control como en los coches no
automáticos. Hay un precio que pagar. Sin embargo, es lo que tienes en Excel y
con ello tendrás que jugar.
Si hacemos un programa para establecer ajustes para impresión para una hoja de
Excel, con programación estructurada basta, sin necesidad de usar OOP. Usar
OOP implica un esfuerzo de diseño y la construcción de clases, antes de que
siquiera puedas probar una porción de programa. Con Excel VBA puedes
programar a la antigua para cosas pequeñas, lo cual ofrece ventajas de tiempo de
programación si tu programa es pequeño y no maneja cosas muy complicadas.
Ahora bien, hay situaciones mucho más complejas donde eso no
basta. Imaginemos por un momento que vamos a programar un juego
de ajedrez en Excel. Para hacerlo con programación estructurada, necesitarías
almacenar toda la información de cada una de las piezas y empezar a hacer un
recorrido por cada pieza, analizando las posibles actuaciones o la situación táctica
de cada una, y haciendo que el código administre las conductas de todas las
piezas.
Compliquemos más el cuadro. Si fueras a hacer un juego de carreras de
coches, donde no tienes una idea clara de la cantidad de coches, calcular las
estrategias y maniobras de cada coche resulta sumamente complicado, y debes
reservar todo el espacio en memoria que necesitarás para esos coches. Imagina
que además de coches tienes obstáculos móviles que habrán de interactuar con
los coches, y cada uno de esos obstáculos tiene su conducta propia. Al final
terminas haciendo malabarismos de alta complejidad con el código, y terminas
enredándote sobremanera y las probabilidades de cometer errores se disparan.
X
by Counterflix
Lo mejor es usar OOP. Con OOP sólo debes programar las características
funcionales genéricas de un sólo coche u obstáculo (clase), y luego crear muchos
coches y obstáculos (objetos) en memoria, y le darás cierta información a cada
coche y obstáculo para que el cada uno analice su propia situación y decida que
hacer y cómo hacerlo de manera independiente. Entonces la cantidad de código
se reduce significativamente, lo cual presenta muchas ventajas.
No voy a entrar a analizar las características y principios del OOP en detalle (pues
ya hay suficientes sitios web que lo indican), sino explicarte cómo se implementa
el código para objetos en VBA. Cuando se usa OOP es evidente que tenemos
que diseñar el objeto de forma suficientemente genérica para ajustarse a todos los
tipos de objetos y tareas que debamos efectuar, para diseñar una sola clase y no
muchas para usos particulares, y debemos prediseñar la interfaz que tendrá el
objeto para comunicarse desde y hacia afuera.
Un objeto en VBA tiene lo siguiente:
 Propiedades: Son características que se pueden parametrizar. Por ejemplo, en
un coche tienes el color, la cantidad de asientos, el tipo de motor, nivel de
inteligencia del chofer (para fijar la dificultad), etc.
 Métodos: Se refiere a las conductas o acciones que puede realizar. En un coche,
podrías tener virar, acelerar y frenar.
 Eventos: Se refiere a eventos externos que desencadenan acciones
internamente. No voy a cubrir este tema.
TYPE: EL ANCESTRO DE LOS OBJETOS
Si revisamos la historia antigua del Basic, el ancestro de los objetos que
conocemos hoy incorporaba sólo propiedades, y le creábamos mediante una
declaración Type.
Antes de que existiera el Type en los tiempos primitivos, si íbamos a crear un
arreglo de datos para empleados, debíamos crear un arreglo de texto para
nombre, otro de texto para dirección y otro numérico para el salario. Nombre,
dirección y salario son características o propiedades del empleado.
Empezamos declarando los arreglos.
Dim Nombre(100) as String
Dim Direccion(100) as String
Dim Salario(100) as Single
Y para usarlos, lo haríamos como se muestra abajo. Vamos a agregar los datos
del quinto empleado de la lista de 100 empleados.

Nombre(5) = "Juan Pérez"


Direccion(5) = "Calle 5, Avenida 10, casa npumero 20"
Salario(5) = 2500
Con el Type hacemos una declaración genérica de un "tipo" que contiene varias
propiedades y luego asignamos el tipo al arreglo.
Private Type TipoEmpleado
Nombre as String
Direccion as String
Salario as String
End Type
Dim Empleado(100) as TipoEmpleado
para usar el arreglo Type haríamos esto:

Empleado(5).Nombre = "Juan Pérez"


Empleado(5).Direccion = "Calle 5, Avenida 10, casa npumero 20"
Empleado(5).Salario = 2500
¿Verdad que se mira más intuitivo? ¿Problemas con el Type?
 Tiene una funcionalidad limitada.
 Todo se hace a nivel de declaración en tiempo de diseño. Para hacer cambios en
tiempo de ejecución tendrías que usar el comando Redim Preserve que es una
tarea que consume mucho tiempo-máquina.
 No puedes validar la información que ingresa en el arreglo, pues debes validar los
datos ingresados en el código de programa, pues Type no incorpora validación de
información.
USANDO CLASES
¿Recuerdas cuando dije que debíamos crear el código para un objeto, como un
coche o una pieza de ajedrez? La "clase" se puede entender como "los planos
para construir un objeto". No es el objeto en sí mismo, pero con estos planos
podremos construir muchos objetos en tiempo de ejecución.
Un módulo de clase es el lugar para poner el código que dará funcionalidad a los
objetos. En lugar de crear un módulo normal, creamos un módulo de clase en
Excel.
En ese módulo pondremos todo el código para un objeto genérico, y cuando
estamos en tiempo de ejecución creamos o destruimos los objetos. Para una clase
necesitarás propiedades, métodos y eventos para el objeto en cuestión.

CREANDO LAS PROPIEDADES

Como sabemos las propiedades son datos que nos describe una cualidad del
objeto, y como tal, tendremos que declarar variables a nivel de módulo. Estas
variables serán la que almacenarán la información de propiedades internamente
dentro del módulo. Son variables privadas, pues desde afuera no podrán ser
accedidas.
Private pNombre As String
Private pDireccion As String
Private pSalario As Double
Si desde afuera no podemos acceder a estas variables privadas, ¿cómo vamos a
leer o asignar valores al objeto? Usamos un tipo de procedimiento especial para
extraer (Property Get) o para insertar valores (Property Let) dentro del objeto.
 Programa principal -> Property Let -> Variable interna del objeto
 Variable interna del objeto -> Property Get -> Programa principal
Y estos procedimientos son públicos, lo cual significa que pueden accederse
desde afuera. Así, los procedimientos Property Let y Property Get tienen la única
función de insertar o extraer datos en las variables privadas que se manejan
dentro del objeto. ¿Por qué no simplemente hacer públicas las variables
internas? Porque estos procedimientos permiten incorporar funciones adicionales
de validación de información, o entregar sólo valores determinados a partir del
contenido de las variables internas. A estas variables internas le he agregado una
"p", de modo que pNombre es la variable interna para la propiedad Nombre.
''''''''''''''''''''''
' Propiedad Nombre
''''''''''''''''''''''
Public Property Get Nombre() As String
Nombre = pNombre
End Property
Public Property Let Nombre(Valor As String)
pNombre = Valor
End Property

''''''''''''''''''''''
' Propiedad Direccion
''''''''''''''''''''''
Public Property Get Direccion() As String
Direccion= pDireccion
End Property
Public Property Let Direccion(Valor As String)
pDireccion = Valor
End Property

''''''''''''''''''''''
' Propiedad Salario
''''''''''''''''''''''
Public Property Get Salario() As Double
Salario = pSalario
End Property
Public Property Let Salario(Valor As Double)
pSalario = Valor
End Property
Ahora bien, imaginemos que el usuario ingresa un número negativo. Tendrías que
validar que el salario sea un número positivo.

Public Property Let Salario(Valor As Double)


pSalario = Abs(Valor)
End Property
Como vemos, el objeto acepta un valor numérico, de modo que si le envían un
valor de texto, tendrás un error que Excel ubicará en la clase, cuando en realidad
viene del código del programa principal. Entonces podrías hacer que el objeto
reciba cualquier valor, mediante una variable de tipo Variant, y si el valor
ingresado es texto, entonces activar el código que maneja errores.

Public Property Let Salario(Valor As Variant)


If IsNumeric(Valor) Then
pSalario = Abs(Valor)
Else
'Agregar aquí el código para manejo de error
End If
End Property
Como ves, puedes incorporar código para validación y manejo de errores en los
procedimientos que reciben valores o envían valores desde el objeto que has
creado. Además, si creas sólo el código para el procedimiento Property
Get (omitiendo el de Property Let) entonces tienes una propiedad que es sólo para
lectura. Pensemos que al salario se le aplicará un 9% de deducciones salariales,
un valor que realmente no debería ser insertado en el objeto Empleado desde
afuera, sino calculado a partir del salario.
Public Property Get Deducciones()
Deducciones = pSalario * 0.09
End Property
CREANDO LOS MÉTODOS
Una vez que ya tienes claras las propiedades, es tiempo de agregar los
métodos. Los métodos son procedimientos ordinarios, pero trabajarán con los
datos del objeto. En un coche, virar a la derecha o a la izquierda, es un método,
una conducta, una acción que tiene lugar en el objeto, y como podrás imaginar, si
creas múltiples coches, cada uno conducirá por cuenta propia. Si tenemos un
objeto llamado empleado, al imprimir el comprobante, en realidad estás
imprimiendo el comprobante para el empleado que está cubierto por el objeto que
creaste.

Public Sub ImprimirComprobanteDePago()


'Agregar código para imprimir comprobante aquí
End Sub
PONER NOMBRE A LA CLASE
Aún no hemos terminado. Todavía falta ponerle nombre a la clase, para que
pueda ser llamada desde afuera, para crear objetos usando esta clase. En la
propiedad (Name) del editor, pondré el nombre cEmpleado.

Estamos listos para usar la clase.


USANDO LA CLASE
En el programa principal usaremos la clase para crear objetos en tiempo de
ejecución. Lo primero es declarar la variable que contendrá el objeto.

Dim Empleado As cEmpleado


Dentro del procedimiento del programa principal tendrías que crear el
objeto. Como puedes ver, se usa el compando Set, y la palabra New indica que
estás creando un nuevo objeto en memoria.

Set Empleado = New CEmployee


Y luego puedes usar el objeto.

Empleado.Nombre = "Juan Pérez"


Empleado.Direccion = "Calle 5, Avenida 10, casa npumero 20"
Empleado.Salario = 2500
DeduccionesDelEmpleado = Empleado.Deducciones
ImprimirComprobanteDePago
Cuando ya hayas dejado de usar el objeto, y antes de terminar el programa, sería
bueno que destruyas el objeto para que no ocupe memoria.

Set Empleado = Nothing


Dejar objetos sin destruir en memoria al terminar el programa, se conoce como
"memory leak", y es una buena manera de desperdiciar memoria RAM que
seguramente ocuparás luego.
USAR OBJETOS DE EXCEL
No sólo puedes crear objetos para manejar clases hechas por tí, sino que también
puedes crear objetos usando objetos existentes en Excel o usando clases que ya
vienen dadas por Excel. Veamos por ejemplo este código que te permite enviar
un correo electrónico.
Sub SendEmail(sTo As String, sSubject As String, sBody As String,
sAttachmentFilename As String)
On Error GoTo EmailError
Dim oLook As Object
Dim oMail As Object

Set oLook = CreateObject("Outlook.Application")


Set oMail = oLook.createitem(0)
With oMail
.To = sTo
.body = sBody
.Subject = sSubject
.Attachments.Add (sAttachmentFilename)
.Send
End With

Set oMail = Nothing


Set oLook = Nothing
Exit Sub
EmailError:
On Error Resume Next
AddErrorMessage "Unable to send email"
End Sub
Miramos que el objeto oLook creado como Object, y que en lugar de
usar New como se usaría con una clase creada por tí, usa CreateObject, que crea
un objeto "manejador de Outlook", que tiene un método llamado createitem con el
cual se crea el objeto oMail que tiene las propiedades To, body, Subject y permite
usar los métodos Attachments.Add y Send. Parece un poco complicado al inicio,
pero en realidad sucede que un objeto puede crear otros objetos dentro de él, y
así tienes el manejador de Outlook y el manejador de correos individuales.
Miramos el código del manejador de portapapeles para Excel.
Dim doClip As DataObject

Sub CrearClipboard()
Set doClip = New DataObject
End Sub
Sub DestruirClipboard()
Set doClip = Nothing
End Sub

Sub CopiarAlClipboard(sTexto As String)


doClip.Clear
doClip.SetText sTexto
doClip.PutInClipboard
End Sub

Function ClipboardTexto() As String


doClip.GetFromClipboard
ClipboardTexto = doClip.GetText
End Function
Como podemos observar, existe la clase DataObject que te permite crear un
manejador de portapapeles. Cuando creas o destruyes el manejador del
portapapeles, no estás creando o destruyendo el portapapeles, sino que estás
creando o destruyendo un objeto que te permite comunicarte con el portapapeles.
CLASES PARA CREAR MANEJADORES DE HOJAS DE EXCEL
El concepto de "manejador" también puede servirte cuando tienes que manejar
múltiples hojas de Excel. Si cada objeto maneja un libro de Excel, y al usar el
objeto, te mueves al libro de Excel correspondiente, puedes saber exactamente en
qué libro estás trabajando. Y también tiene la ventaja de que puedes trasladar
valores entre libros de Excel de manera más efectiva y sin mucho papeleo.
Set Reporte = New clsExcelFile
Set HojaDeMacros = New clsExcelFile
Set Transacciones = New clsExcelFile

HojaDeMacros.NombreDeLibro = HojaDeMacros.NombreDeLibroActual
Transacciones.NombreDeLibro = "Transacciones.xlsx"
Reporte.NombreDeLibro = "Reporte_Anual.xlsx"

HojaDeMacros CargarArchivoTransacciones
Transacciones.CrearReporte Reporte.NombreDeLibro
Reporte.ImpuestoDeRenta = HojaDeMacros.ParámetroImpuestos
Reporte.ImprimirReporte
Transacciones.CerrarArchivo
HojaDeMacros.CerrarArchivo

Set HojaDeMacros = Nothing


Set Transacciones = Nothing
En el ejemplo anterior tenemos una clase que es un manejador de libros de Excel,
con las siguientes propiedades:
 NombreDeLibro
 ImpuestoDeRenta
Y tiene los siguientes métodos:
 ParámetroImpuestos: Busca el parámetro de la tasa de impuesto a pagar en la
hoja de Excel.
 NombreDeLibroActual: Busca el nombre del libro de Excel que está activo.
 CargarArchivoTransacciones: Busca y carga el libro de Excel de transacciones en
una ubicación determinada
 CerrarArchivo: Cierra el libro.
 CrearReporte: Crea un libro nuevo de Excel y crea la plantilla de reporte con datos
de transaciones.
 ImprimirReporte: Hace los cálculos usando el parámetro de impuestos e imprime.
Entonces, con una sola clase, manejamos tres libros de Excel, y nunca tenemos
confusión acerca qué archivos estamos manejando. El programa principal es muy
corto y usa 3 objetos, donde cada uno maneja un libro de Excel particular. Y como
puedes ver, sólo cargamos el archivo con las macros, las transacciones se cargan
automáticamente, y el reporte se genera automáticamente.
OTROS USOS PARA LAS CLASES
Imagina que tienes una lista de productos, y una lista de tipos de
cliente. Determinados productos se ofrecen a determinados tipos de cliente,
porque de otro modo los productos podrían no satisfacer las necesidades de los
clientes. Tienes una lista de los productos que se vendió a determinados clientes
cuyo tipo ya conoces. Quieres determinar si hubo alguna venta de producto que
no satisface a clientes. Entonces tienes que sacar cada combinación de producto
con el tipo de cliente y comparar para ver si hay alguna combinación que calce
con las ventas realizadas. Normalmente este proceso sería muy complicado y
engorroso de programar con programación estructurada, de modo que puedes
crear un manejador de listas, ya sea de productos o de tipos de cliente, para
hacerte más fácil el trabajo.
X
by Counterflix
En general el uso de objetos se usa cuando tienes que hacer malabares con datos
y donde hay muchos entes similares que deben ser manejados a la vez o cuya
interacción necesita ser evaluada o simulada.
Espero que te sirva. No estoy seguro de si logré explicar con claridad, pero si no
es así, puedes anotar tus consultas y con gusto buscaré una manera de hacer la
explicación más clara.

 Empresas

También podría gustarte