¿Cómo usar métodos de comparación entre módulos de objetos de clase en VBA de una manera similar a VB.NET?

Debido al nuevo proyecto en VBA, me mudé de VB.NET, para ser honestos, realmente no sé cómo tratar las clases de objetos aquí. Lo que quiero alcanzar es comparar objetos entre diferentes módulos de objetos de clase.

p.ej

Empleado de clase
propiedades: Name , Age
el punto es: comparar Name entre dos empleados

clases: Empleado y Gerente
El punto es: comparar el Name del empleado con el Name del gerente

Sé cómo hacerlo en VB.NET, pero ¿cómo comparo las propiedades de diferentes objetos de módulos de clase en VBA?

VBA no es compatible con el polymorphism de clase, por lo que recomiendo cambiar la forma en que piensas sobre las clases Employee y Manager .

No puede tener una clase Employee como clase base y luego una clase Manager separada que se deriva de Employee . Podrían ser 2 clases separadas implementando una interfaz común.

Voy a hablar sobre esto en detalle en un momento. Veamos ahora algunos ejemplos …


↓ Acercamiento fácil ↓


Una clase base ( Person ) y clases secundarias que derivan de la clase base. (se aplica a C #, VB.NET, etc. )

pero en VBA debes pensarlo así:

Una clase base que expone una propiedad enum que describe la posición.

Algo como

enter image description here

enter image description here

Esta es la forma más fácil de tener una clase exponiendo algunas propiedades. Le permite agregar sus objetos Person en una colección e iterar usando el fácil for each ciclo con Intellisense .

enter image description here

El sistema de comparación de propiedades sería muy, muy fácil

enter image description here

nota: lo mismo se aplica a enum ya que se convierte implícitamente en un número


↓ Enfoque más complejo ↓


Dos clases separadas que exponen propiedades públicas. Por ejemplo, tiene una clase Employee y Manager que implementan una interfaz de Person y una clase Comparer adicional que expone un método Compare()

enter image description here

En su proyecto VBA necesita 4 módulos de clase y un módulo estándar

enter image description here

Person (esta es su interfaz)

 Public Property Get Name() As String End Property Public Property Get Age() As Long End Property 

esta clase es la interfaz que tanto el Employee como el Manager deben implementar para compartir algunas funciones comunes (captadores de nombres y edades). Tener la interfaz le permite hacer para cada ciclo utilizando la variable de tipo de interfaz como el enumerador. Verás en un minuto .

Employee y el Manager son idénticos. Obviamente, puede modificarlos para adaptarlos a su solución de la vida real .

 Implements Person Private name_ As String Private age_ As Long Public Property Get Name() As String Name = name_ End Property Public Property Let Name(ByVal Value As String) name_ = Value End Property Public Property Get Age() As Long Age = age_ End Property Public Property Let Age(ByVal Value As Long) age_ = Value End Property Private Property Get Person_Name() As String Person_Name = Name End Property Private Property Get Person_Age() As Long Person_Age = Age End Property 

ComparerCls usará una instancia de esta clase para comparar dos objetos, propiedades o referencias . No necesariamente es necesario tener una clase para esto, pero lo prefiero de esa manera.

 Public Enum ComparisonMethod Names = 0 ' default Ages = 1 References = 2 End Enum ' makes names the default comparison method Public Function Compare(ByRef obj1 As Person, _ ByRef obj2 As Person, _ Optional method As ComparisonMethod = 0) _ As Boolean Select Case method Case Ages Compare = IIf(obj1.Age = obj2.Age, True, False) Case References Compare = IIf(obj1 Is obj2, True, False) Case Else Compare = IIf(obj1.Name = obj2.Name, True, False) End Select End Function 

Y su código Module1

 Option Explicit Sub Main() Dim emp As New Employee emp.Name = "person" emp.Age = 25 Dim man As New Manager man.Name = "manager" man.Age = 25 Dim People As New Collection People.Add emp People.Add man Dim individual As Person For Each individual In People Debug.Print TypeName(individual), individual.Name, individual.Age Next End Sub 

ejecuta el sub Main() y mira los resultados en la ventana Inmediato

enter image description here

La mejor parte del código anterior es el hecho de que está creando una variable de referencia de la interfaz de Person . Le permite recorrer todos los elementos de la colección que implementan la interfaz. Además, puede usar el Intellisense, que es genial si ha tenido muchas más propiedades y funciones.


Comparación


Eche un vistazo nuevamente al código en la clase ComparerCls

enter image description here

Espero que veas ahora por qué he separado esto para ser una clase. Su propósito es solo cuidar la forma en que se comparan los objetos. Puede especificar el orden Enum y modificar el método Compare() para compararlo de manera diferente. Tenga en cuenta el parámetro opcional que le permite llamar al método Comparar sin el método de comparación.

enter image description here

Ahora puedes jugar pasando diferentes parámetros a la función de comparación. Vea cómo son los resultados.

Prueba combinaciones:

 emp.Name = "name" man.Name = "name" Comparer.Compare(emp, name, Names) Comparer.Compare(emp, name, References) Comparer.Compare(emp, emp, References) 

Si algo no está claro, consulte esta respuesta sobre la palabra clave Implements en VBA