Introducción.
La semana pasada creamos una nueva clase contenedora ClsTiles, usando la clase ClsArea dos veces en el nuevo módulo de clase, una instancia para Floor valores de dimensión y la segunda instancia para Floor-Tile dimensión, para calcular el número de mosaicos para la habitación.
En el nuevo módulo Wrapper Class, transformaremos la clase de volumen (ClsVolume2) en la clase de ventas (ClsSales). Con algunos cambios estéticos, le daremos un lavado de cara total a la Clase Envoltura, ocultando su verdadera identidad como Clase de cálculo de Volumen y la usaremos para calcular el Precio de Venta de Productos con Descuento.
No debemos olvidar que la Clase ClsVolume2 es una Clase Derivada , creado con ClsArea como clase base.
Revisitación de la clase ClsVolume2.
Pero, primero, el código VBA del módulo de clase ClsVolume2 (la clase base para nuestro nuevo módulo de clase ClsSales) se reproduce a continuación como referencia:
Option Compare Database Option Explicit Private p_Height As Double Private p_Area As ClsArea Public Property Get dblHeight() As Double dblHeight = p_Height End Property Public Property Let dblHeight(ByVal dblNewValue As Double) p_Height = dblNewValue End Property Public Function Volume() As Double Volume = CArea.dblLength * CArea.dblWidth * Me.dblHeight End Function Public Property Get CArea() As ClsArea Set CArea = p_Area End Property Public Property Set CArea(ByRef AreaValue As ClsArea) Set p_Area = AreaValue End Property Private Sub Class_Initialize() Set p_Area = New ClsArea End Sub Private Sub Class_Terminate() Set p_Area = Nothing End Sub
El único problema que nos impide usar ClsVolume2 Class directamente para las Ventas la entrada de datos es que los nombres de procedimiento de propiedad dblLength, dblWidth, dblHeight no coinciden con los valores de propiedad de ventas Cantidad, Precio unitario, Porcentaje de descuento. Los tipos de datos numéricos de la Clase ClsVolume2 son todos números de doble precisión y son adecuados para nuestra Clase de Ventas y se pueden usar sin cambiar el tipo de datos. Los nombres de las funciones públicas Área() y Volumen() tampoco son adecuados, pero su fórmula de cálculo se puede utilizar para los cálculos de Ventas sin cambios.
a) Area =dblLength * dblWidth es adecuado para TotalPrice =Cantidad * UnitPrice
b) Volumen =Área * dblHeight es bueno para DiscountAmount =TotalPrice * DiscountPercentage
Aquí, tenemos dos opciones para utilizar la clase ClsVolume2 como clase ClsSales.
- La forma más fácil es hacer una copia de la clase ClsVolume2 y guardarla en un nuevo módulo de clase con el nombre ClsSales. Realice los cambios apropiados en el procedimiento de propiedad y los nombres de funciones públicas adecuados para los valores y cálculos de ventas. Agregue más funciones, si es necesario, en el nuevo módulo de clase.
- Cree una clase contenedora usando ClsVolume2 como clase base y cree procedimientos de propiedad adecuados y cambios de nombre de funciones públicas, enmascarando los procedimientos de propiedad y los nombres de funciones de la clase base. Cree nuevas funciones en la clase contenedora, si es necesario.
La primera opción es algo sencilla y fácil de implementar. Pero seleccionaremos la segunda opción para aprender cómo abordar las propiedades de la clase base en la nueva clase contenedora y cómo enmascarar sus nombres de propiedad originales con otros nuevos.
La clase ClsVolume2 transformada.
- Abra su base de datos y muestre la ventana de edición de VBA (Alt+F11).
- Seleccione el Módulo de clase de Insertar Menú, para insertar un nuevo Módulo de Clase.
- Cambie el valor de la propiedad Nombre del módulo de clase de Class1 a ClsSales .
- Copie y pegue el siguiente código VBA en el módulo y guarde el código:
Option Compare Database Option Explicit Private m_Sales As ClsVolume2 Private Sub Class_Initialize() 'instantiate the Base Class in Memory Set m_Sales = New ClsVolume2 End Sub Private Sub Class_Terminate() 'Clear the Base Class from Memory Set m_Sales = Nothing End Sub Public Property Get Description() As String Description = m_Sales.CArea.strDesc 'Get from Base Class End Property Public Property Let Description(ByVal strValue As String) m_Sales.CArea.strDesc = strValue ' Assign to Base Class End Property Public Property Get Quantity() As Double Quantity = m_Sales.CArea.dblLength End Property Public Property Let Quantity(ByVal dblValue As Double) If dblValue > 0 Then m_Sales.CArea.dblLength = dblValue ' Assign to clsArea, Base Class of ClsVolume2 Else MsgBox "Quantity: " & dblValue & " Invalid.", vbExclamation, "ClsSales" Do While m_Sales.CArea.dblLength <= 0 m_Sales.CArea.dblLength = InputBox("Quantity:, Valid Value >0") Loop End If End Property Public Property Get UnitPrice() As Double UnitPrice = m_Sales.CArea.dblWidth End Property Public Property Let UnitPrice(ByVal dblValue As Double) If dblValue > 0 Then m_Sales.CArea.dblWidth = dblValue ' Assign to clsArea, Base Class of ClsVolume2 Else MsgBox "UnitPrice: " & dblValue & " Invalid.", vbExclamation, "ClsSales" Do While m_Sales.CArea.dblWidth <= 0 m_Sales.CArea.dblWidth = InputBox("UnitPrice:, Valid Value >0") Loop End If End Property Public Property Get DiscountPercent() As Double DiscountPercent = m_Sales.dblHeight End Property Public Property Let DiscountPercent(ByVal dblValue As Double) ' Assign to Class .dblHeight of ClsVolume2 Select Case dblValue Case Is <= 0 MsgBox "Discount % -ve Value" & dblValue & " Invalid!", vbExclamation, "ClsSales" Do While m_Sales.dblHeight <= 0 m_Sales.dblHeight = InputBox("Discount %, Valid Value >0") Loop Case Is >= 1 m_Sales.dblHeight = dblValue / 100 Case 0.01 To 0.75 m_Sales.dblHeight = dblValue End Select End Property Public Function TotalPrice() As Double Dim Q As Double, U As Double Q = m_Sales.CArea.dblLength U = m_Sales.CArea.dblWidth If (Q * U) = 0 Then MsgBox "Quantity / UnitPrice Value(s) 0", vbExclamation, "ClsVolume" Else TotalPrice = m_Sales.CArea.Area 'Get from Base Class ClsArea End If End Function Public Function DiscountAmount() As Double DiscountAmount = TotalPrice * DiscountPercent End Function Public Function PriceAfterDiscount() PriceAfterDiscount = TotalPrice - DiscountAmount End Function
¿Qué hicimos en la Clase Wrapper? Creó una instancia de la clase ClsVolume2 y cambió sus nombres de propiedades, nombres de funciones y agregó verificaciones de validación con mensajes de error apropiados y evitó que cayera en la verificación de validación de la clase base con mensajes de error inapropiados, como 'Valor en dblLength La propiedad no es válida' puede aparecer en la clase de volumen.
Verifique las líneas que he resaltado en el Código anterior y espero que pueda averiguar cómo se asignan/recuperan los valores de propiedad a/desde la Clase base ClsVolume2.
Puede pasar por el módulo de clase ClsArea primero y luego al módulo de clase ClsVolume2:la clase derivada que usa la clase ClsArea como clase base. Después de pasar por estos dos Códigos, puede echar un segundo vistazo al Código en esta Clase de Contenedor.
Programa de prueba para la clase ClsSales en el módulo estándar.
Escribamos un programa de prueba para probar la clase contenedora.
- Copie y pegue el siguiente código VBA en un módulo estándar.
Public Sub SalesTest() Dim S As ClsSales Set S = New ClsSales S.Description = "Micro Drive" S.Quantity = 12 S.UnitPrice = 25 S.DiscountPercent = 0.07 Debug.Print "Desccription", "Quantity", "UnitPrice", "Total Price", "Disc. Amt", "To Pay" With S Debug.Print .Description, .Quantity, .UnitPrice, .TotalPrice, .DiscountAmount, .PriceAfterDiscount End With End Sub
Ejecute el código.
- Mantenga abierta la ventana de depuración (Ctrl+G).
- Haga clic en algún lugar en medio del Código y presione F5 para ejecutar el código e imprimir el resultado en la ventana de depuración.
- Puede seguir probando el código ingresando cualquiera de los valores de entrada con un número negativo y ejecutando el código para activar el nuevo mensaje de error. Deshabilite cualquiera de las líneas de entrada, con un símbolo de comentario ('), ejecute el código y vea qué sucede.
Calcular precio/descuento para una variedad de productos.
El siguiente código de prueba crea una matriz de tres productos y valores de ventas ingresando directamente desde el teclado.
Copie y pegue el siguiente código en un módulo estándar y ejecútelo para probar aún más la clase contenedora.
Public Sub SalesTest2() Dim S() As ClsSales Dim tmp As ClsSales Dim j As Long For j = 1 To 3 Set tmp = New ClsSales tmp.Description = InputBox(j & ") Description") tmp.Quantity = InputBox(j & ") Quantity") tmp.UnitPrice = InputBox(j & ") UnitPrice") tmp.DiscountPercent = InputBox(j & ") Discount Percentage") ReDim Preserve S(1 To j) As ClsSales Set S(j) = tmp Set tmp = Nothing Next 'Output Section Debug.Print "Desccription", "Quantity", "UnitPrice", "Total Price", "Disc. Amt", "To Pay" For j = 1 To 3 With S(j) Debug.Print .Description, .Quantity, .UnitPrice, .TotalPrice, .DiscountAmount, .PriceAfterDiscount End With Next For j = 1 To 3 Set S(j) = Nothing Next End Sub
Después de ingresar con éxito los valores correctos en el Array, los nombres de los productos y los valores de venta se imprimen en la ventana Depuración.
MÓDULOS DE CLASES.
- Módulo de clase MS-Access y VBA
- Matrices de objetos de clase VBA de MS-Access
- Clase base de MS-Access y objetos derivados
- Clase base de VBA y objetos derivados-2
- Variantes de clase base y objeto derivado
- Conjunto de registros y módulo de clase Ms-Access
- Módulo de clase de acceso y clases contenedoras
- Transformación de la funcionalidad de la clase contenedora
OBJETO DE COLECCIÓN.
- Conceptos básicos de Ms-Access y objetos de colección
- Módulo de clase Ms-Access y objeto de colección
- Registros de tabla en objeto y formulario de colección
OBJETO DE DICCIONARIO.
- Conceptos básicos de objetos de diccionario
- Conceptos básicos de objetos de diccionario-2
- Ordenar elementos y claves de objetos del diccionario
- Mostrar registros del diccionario al formulario
- Agregar objetos de clase como elementos de diccionario
- Actualizar elemento del diccionario de objetos de clase en el formulario