martes, 9 de agosto de 2016

VBA: Los Módulos de Clase en Excel (Class Modules) - parte I.

Abordaremos hoy un punto importante para los amantes de la programación en VBA para Excel... y que tengan ya un nivel algo avanzado: Los Módulos de Clase (Class Modules).

Sabemos que el lenguaje y la programación en VBA para Exel está estructurada y orientada a objetos OOPL (Object Oriented Programming Language).. piensa durante un segundo todos los objetos habituales con los que trabajas al programar en VBA para Excel (objeto Workbook, Sheets, Range, Chart, y un largo etcétera).
Sin duda alguna para pequeñas y/o grandes cosas empleamos el VBA 'normal' empleando los objetos ya definidos por las distintas librerías y referencias que existen en Excel, y nos basta emplear los módulos de programación estándar, así como otras ventanas de código.
Ahora bien, existen situaciones más complicadas donde esto no es suficiente, donde realizar un proceso con programación estructurada (la estándar de toda la vida), necesitaríamos una vida y muchas líneas de código que recogieran todas las posibilidades... o en un escenario peor, donde no tuviéramos cerrado el número de variables... es aquí donde el uso de las 'Clases' nos aporta fortaleza a nuestra programación, evitando de paso, posibles fallos y errores de programación.

Parece claro que la posibilidad de programar características o propiedades genéricas de un objeto, para luego utilizar estas propiedades reducirá la cantidad de código significativamente, así como ganar en claridad (ventajas fundamentales).

En definitiva, emplear las clases (propiedades, métodos y eventos) propias, generadas y definidas por nosotros, es una forma de optimizar nuestras programaciones en VBA.

Tres puntos básicos que comparan el uso del módulo estándar frente al módulo de clase:
1-En un módulo estándar sólo hay una copia de los datos ; sin embargo, en un módulo de clase se crea por separado para cada instancia de la clase. De ahí que cada instancia de la clase tiene su propio conjunto de variables de clase individual al objeto.
2-Los datos, en un módulo estándar, existen tanto como su ámbito de aplicación del programa - el proyecto de VBA. Sólo cuando se cierra el archivo se pierden los datos de todas las variables globales. En un módulo de clase, sin embargo, existen datos para cada instancia sólo durante el tiempo de vida del objeto. Deja de existir cuando la clase de objeto es destruido; por ejemplo, cuando el objeto de clase se establece en Nothing (Set clase = Nothing).
3-Las variables declaradas pública en un módulo estándar son visibles en cualquier parte de su proyecto. Sin embargo, las variables públicas en un módulo de clase son accesibles únicamente si tiene una variable de objeto que contiene una referencia a una instancia particular de esa clase.


Entrando en materia, es muy importante conocer que en un objeto que vayamos a crear existen y podemos trabajar con:
1-Propiedades: Serían las características concretas que se pueden definir o parametrizar. Emplearemos la propiedad Get, la propiedad Let y Set:
a)Get := devuelve/extrae el valor del objeto.
b)Let := inserta el valor dentro del objeto.
c)Set := si aplica, configura el objeto. Establecer el valor de una propiedad que contiene una referencia a un objeto

2-Métodos: Se refiere a las conductas o acciones que puede realizar. Una vez claras las propiedades, agregamos los métodos (procedimientos ordinarios, que trabajarán con los datos del objeto).

3-Eventos: Se refiere a eventos externos que desencadenan acciones de manera interna. Son básicamente dos: Class_Initialize() y Class_Terminate().


Para asentar tanta 'palabrería' propongo generar una Clase a modo de ejemplo: La Clase SmartPhone
Desde el Editor de VBA seleccionamos Insertar > Módulo de clase.

VBA: Los Módulos de Clase en Excel (Class Modules) - parte I.


Es importante tener en cuenta que:
* todo objeto personalizado (toda clase) debe de tener su propio módulo.
* el módulo de clase es necesario renombrarlo para reflejar el objeto personalizado!!.


Ahora que tenemos creado nuestro módulo de clase, definiremos cuales son las propiedades y los métodos que necesitamos.
Tres características que definen de manera concreta un SmartPhone (todas las que necesitemos):
1- Marca
2- Modelo
3- Memoria

Estas variables serán la que almacenarán la información de propiedades internamente dentro del módulo. Optamos por variables privadas, ya que no queremos que desde afuera sean accesible (podríamos haber optado por definirlas como Public según necesidades).
Private pMarca As String
Private pModelo As String
Private pMemoria As Double


No importa que las hayamos definido como Private, ya que para poder emplearlas desde cualquier lugar de nuestro proyecto, usaremos las propiedades Get y Let (que son Públicas).


'''''''''''''''''''''''''''''''''''''''''''''
'Propiedad Marca
Public Property Get Marca() As String
    Marca = pMarca
End Property
Public Property Let Marca(Valor As String)
    pMarca = Valor
End Property

'''''''''''''''''''''''''''''''''''''''''''''
' Propiedad Modelo
Public Property Get Modelo() As String
    Modelo = pModelo
End Property
Public Property Let Modelo(Valor As String)
    pModelo = Valor
End Property

'''''''''''''''''''''''''''''''''''''''''''''
' Propiedad Memoria
Public Property Get Memoria() As Double
    Memoria = pMemoria
End Property
Public Property Let Memoria(Valor As Double)
    'controlamos que se introduce un número
    If IsNumeric(Valor) Then
        'y además con ABS lo gestionamos siempre como positivo
        pMemoria = Abs(Valor)
    Else
        'si no fuera un número, forzamos el valro como cero
        pMemoria = 0
    End If
End Property


Como puedes observar, se puede 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 (Get y Let).
Además, es posible crear sólo el código para el procedimiento Property Get (omitiendo el de Property Let), teniendo entonces una propiedad que es sólo de lectura.
'''''''''''''''''''''''''''''''''''''''''''''
' Propiedad solo lectura: MemoriaLibre
Public Property Get MemoriaLibre() As Double
    MemoriaLibre = pMemoria * 0.85
End Property



Finalmente (de momento) podríamos definir dentro de nuestro módulo de clase, además de las propiedades anteriores, métodos que son procedimientos Sub que realizan una acción u operación; y/o procedimientos Function que devuelven un valor después de realizar una operación.
Un planteamiento de métodos de nuestra clase podría ser:
Public Sub Llamada()
    'código aquí
    MsgBox "Hemos realizado una llamada"
End Sub
 
Public Sub SMS()
    'código aquí
    MsgBox "Acabas de enviar un SMS"
End Sub
 
Public Sub Datos()
    'código aquí
    MsgBox "Estás consumiento datos"
End Sub



Estos métodos representan tres acciones posibles que podemos realizar con nuestro objeto(SmartPhone)...

Acabamos hoy con un simple ejemplo de cómo poder hacer uso de nuestra recién creada clase.
Para crear un objeto de nuestra clase 'SmartPhone_Class', haríamos lo siguiente:
Dim Smart1 As New SmartPhone_Class


Otra posibilidad es primero declarar la clase y luego asignar un objeto:
Dim Samrt1 As SmartPhone_Class
Set Smart1 = New SmartPhone_Class


Y podríamos 'inicializar' sus propiedades así:
Smart1.Marca = "LG"
Smart1.Modelo = "G4"
Smart1.Memoria = "8"


Para usar los métodos declarados:
Smart1.Llamada
Smart1.SMS
Smart1.Datos



En un módulo estándar del proyecto insertamos lo siguiente:

Sub Ejemplo1()
Dim Smart1 As New SmartPhone_Class
'resto de código
End Sub

Sub Ejemplo2()
Dim Samrt1 As SmartPhone_Class
Set Smart1 = New SmartPhone_Class
'resto de código

Set Smart1 = Nothing
End Sub

Sub Ejemplo3()
Dim Samrt1 As SmartPhone_Class
Set Smart1 = New SmartPhone_Class

'asignamos valores a las variables...
Smart1.Marca = "LG"
Smart1.Modelo = "G4"
Smart1.Memoria = "8"

Set Smart1 = Nothing
End Sub

Sub ejemplo4()
Dim Samrt1 As SmartPhone_Class
Set Smart1 = New SmartPhone_Class

'lanzará los métodos creados...
Smart1.Llamada
Smart1.SMS
Smart1.Datos

Set Smart1 = Nothing
End Sub



En el siguiente post mostraré un ejemplo completo del uso de los módulos de clase.

No hay comentarios:

Publicar un comentario en la entrada