jueves, 28 de abril de 2022

VBA: Instrucción Implements en módulos de clase

Con sinceridad, llevaba tiempo sin programar en VBA, y lo echaba de menos... :D
Hace unos días tuve necesidad de desarrollar cierto código para un cliente y recorde una intrucción que ayuda a facilitar la programación a implementar, y como tuve que buscar documentación al respecto... había olvidado su uso en concreto, decidí publicar al respecto por si sirviera a alguien ;-)

La verdad es que la documentación de Microsoft al respecto no es muy esclarecedora...
pero la idea fundamental de esta intrucción es que facilita referirnos a nuestra biblioteca de tipos, funciones, procedimientos, propiedades, métodos, etc. generados dentro de nuestros Módulos de clase.

Planteemos el siguiente supuesto.
Partimos de una sencilla tabla ('TblPPAL') con movimientos sobre tres países: ES, FR e IT
VBA: Instrucción Implements en módulos de clase

Por supuesto esta tabla estará en constante crecimiento y además es susceptible de incorporar nuevos países.

Nuestro objetivo es obtener para cada registro de la tabla dada un cantidad en euros correspondiente de aplicar un precio y un descuento fijos, por país, informados en nuestra programación.
Nota: sí, lo se.. hay formas más sencillas de conseguirlo ;-)

Vamos con ello!.
En primer lugar crearemos los distintos Módulos de clase necesarios.
El primer módulo de clase se llamará 'clsPaises' y tendrá el siguiente código
Sub CalculoPVP(ByVal base As Double)
    
End Sub
''''''''''''''''''''''''''''''''''''''
Sub CeldaHojaCalculo(celda As Range)
    
End Sub

Estos dos procedimientos, tal cual, sin código a ejecutar... son los que llenaremos de contenido en los siguientes módulos de clase.
Es fundamental que se llamen exactamente igual, y contengan idénticos parámetros.

Crearemos ahora un nuevo Módulo de clase por cada país existente (en el presente y en el futuro...). Será por tanto una labor de mantenimiento a considerar!!.
Un módulo de clase llamado 'clsES' con el código siguiente:
Private d_calculo As Double
'permite dirigirnos a la biblioteca del módulo de clase 'clsPaises'
Implements clsPaises

'deberemos comenzar el procedimiento con el prefijo del Modulo de clase
Sub clsPaises_CalculoPVP(ByVal base As Double)
    d_calculo = base * (1 - 0.05)
End Sub

'deberemos comenzar el procedimiento con el prefijo del Modulo de clase
Sub clsPaises_CeldaHojaCalculo(celda As Range)
    'haría visible el resultado en
    'la ventana de inmediato
    Debug.Print TypeName(Me) & "-" & Format(d_calculo, "#,##0.00")
    'y en una celda de la hoja de cálculo
    celda.Value = CDbl(d_calculo)
End Sub


Un módulo de clase llamado 'clsFR' con el código siguiente:
Private d_calculo As Double
'permite dirigirnos a la biblioteca del módulo de clase 'clsPaises'
Implements clsPaises

'deberemos comenzar el procedimiento con el prefijo del Modulo de clase
Sub clsPaises_CalculoPVP(ByVal base As Double)
    d_calculo = base * (1 - 0.23)
End Sub

'deberemos comenzar el procedimiento con el prefijo del Modulo de clase
Sub clsPaises_CeldaHojaCalculo(celda As Range)
    'haría visible el resultado en
    'la ventana de inmediato
    Debug.Print TypeName(Me) & "-" & Format(d_calculo, "#,##0.00")
    'y en una celda de la hoja de cálculo
    celda.Value = CDbl(d_calculo)
End Sub


Un módulo de clase llamado 'clsIT' con el código siguiente:
Private d_calculo As Double
'permite dirigirnos a la biblioteca del módulo de clase 'clsPaises'
Implements clsPaises

'deberemos comenzar el procedimiento con el prefijo del Modulo de clase
Sub clsPaises_CalculoPVP(ByVal base As Double)
    'realizamos el cálculo...
    d_calculo = base * (1 - 0.15)
End Sub

'deberemos comenzar el procedimiento con el prefijo del Modulo de clase
Sub clsPaises_CeldaHojaCalculo(celda As Range)
    'haría visible el resultado en
    'la ventana de inmediato
    Debug.Print TypeName(Me) & "-" & Format(d_calculo, "#,##0.00")
    'y en una celda de la hoja de cálculo
    celda.Value = CDbl(d_calculo)
End Sub


Como se observa el código de estos tres módulos de clase son casi iguales a excepción de las condiciones particulares de cada país.
Nota: sigo insistiendo que hay formas más óptimas de conseguirlo... pero me intersa mostrar el uso de la intrucción 'Implements'.

Con los procesos generados en estos módulos de clase podremos generar y llamar en forma de objetos desde nuestros módulos estándar para facilitar los cálculos y procesos.. quedando más límpios y claros!!.

Con nuestros módulos de clase creados ya podemos insertar un módulo estándar que procese la información:
Sub Proceso()
Dim arrDatos As Variant
'cargamos los datos de la tabla en una matriz
arrDatos = Hoja1.Range("TblPPAL")

Dim sPais As clsPaises

'recorremos los datos de esa matriz
For i = LBound(arrDatos) To UBound(arrDatos)
    pais = arrDatos(i, 1)
    uds = arrDatos(i, 2)
    
    If pais = "ES" Then
        'definimos el objeto asociado a ES con sus condiciones de descuento particulares
        Set sPais = New clsES
        importe = uds * 11  'y obtenemos su precio base en euros
        
    ElseIf pais = "FR" Then
        'definimos el objeto asociado a FR con sus condiciones de descuento particulares
        Set sPais = New clsFR
        importe = uds * 9.52    'y obtenemos su precio base en euros
        
    ElseIf pais = "IT" Then
        'definimos el objeto asociado a IT con sus condiciones de descuento particulares
        Set sPais = New clsIT
        importe = uds * 12.13   'y obtenemos su precio base en euros
        
    Else
        'nada
    End If
    
    'Ejecutamos los procesos creados ad-hoc en nuestros módulos de clase
    '1-proceso el cálculo y carga la variable....
    sPais.CalculoPVP importe
    '2-la recuperamos en la hoja de cálculo y en la ventana de inmediato
    sPais.CeldaHojaCalculo Hoja1.Cells(i + 2, "E")
Next i

End Sub

Tras ejecutar la macro recién creado vemos los resultados...
VBA: Instrucción Implements en módulos de clase


Este sería un ejemplo de como con un trabajo previo, con nuestros módulos de clase, el trabajo posterior en los módulos estándar se facilita y queda más legible ;-)

No hay comentarios:

Publicar un comentario

Nota: solo los miembros de este blog pueden publicar comentarios.