programming - vba excel pdf
¿VBA es un lenguaje OOP, y es compatible con el polimorfismo? (2)
En realidad estoy trabajando en mi primer proyecto de VBA . (viene de C ++ )
Me gustaría mejorar un proyecto de VBA existente utilizado en un libro de trabajo de Microsoft Excel implementando clases y polimorfismo.
Mi problema es:
1 - Leí muchos artículos / foros que explican que VBA no es un lenguaje de Programación Orientada a Objetos ( OOP ) y no es compatible con el Polimorfismo.
Algunos de ellos proponen una solución mediante la palabra clave Implements .
2 - También encontré algunas páginas web como esta que explican cómo realizar OOP y polimorfismo en VBA usando palabras clave como Inherits , Overrides , Overridable , MustOverrides .
Entonces mi pregunta es:
¿ VBA es un lenguaje OOP , y es compatible con el polimorfismo?
Las respuestas cortas son no y no.
VBA está basado en objetos, lo que le permite definir clases y crear instancias de objetos, pero carece de las características que normalmente se asociarían con un lenguaje OOP completo, por ejemplo:
- Encapsulación y abstracción: VBA proporciona esto en cierta medida. Las clases se pueden mantener privadas con interfaces públicas definidas, sin embargo, no hay ninguna disposición para los constructores dentro de las clases. Las clases tienen un evento
Class_Inititalize
que puede hacer algunas construcciones pero no puede tomar argumentos. Pasar argumentos requeriría una función de fábrica pública. Se requieren soluciones temporales para crear un patrón de diseño de estilo constructor. - Herencia: no existe realmente en VBA, pero puede ser casi replicado
- Polimorfismo: se puede lograr en cierta medida a través de interfaces (usando
Implements
) aunque la capacidad de sobrecargar funciones (por ejemplo) no existe y cada "sobrecarga" requeriría técnicamente un nombre de función único. Puede solucionar esto pasando un objeto como el único parámetro a una función o sub y puede variar el procedimiento según los valores de las propiedades.
Entonces, si bien puede trabajar con objetos hasta cierto punto y las aplicaciones de MS Office se basan en un modelo de objetos, VBA no es verdaderamente un lenguaje orientado a objetos. El polimorfismo no se puede lograr en la medida en que usted esté familiarizado con C ++.
OOP está sentado en 4 "pilares":
Abstracción : la lógica y los conceptos de abstracción se pueden hacer fácilmente definiendo objetos en los módulos de la clase . Estrictamente hablando, la abstracción también se logra mediante el uso de identificadores significativos y la extracción de código de procedimiento en los métodos (miembros de la clase).
Aquí hay un ejemplo de un procedimiento escrito en VBA que demuestra la abstracción :
Public Sub Test(ByVal checkin As Date, ByVal checkout As Date, ByVal custType As CustomerType) Dim finder As New HotelFinder InitializeHotels finder Debug.Print finder.FindCheapestHotel(checkin, checkout, custType) End Sub
Es fácil saber qué hace este procedimiento de
Test
un vistazo, porque el nivel de abstracción es muy alto: los detalles de implementación se abstraen en objetos y métodos más especializados.Encapsulación : las clases pueden tener campos privados expuestos por propiedades; las clases se pueden hacer
PublicNotCreatable
, exponiendo efectivamente tipos a otros proyectos VBA, y con un poco de esfuerzo (exportando el módulo de clase, abriéndolo en su editor de texto favorito, editando atributos de clase manualmente, y reimportando el módulo), usted puede alcanzar tipos reales de solo lectura. El hecho de que no haya constructores parametrizados es irrelevante; simplemente escriba un método de fábrica que tome todos los parámetros que desee y devuelva una instancia. Esto es COM, y COM le gusta fábricas de todos modos.A continuación, se muestra un ejemplo de cómo la clase
HotelFinder
del fragmento anterior encapsula un objetoCollection
y solo lo expone a través de un acceso de acceso deProperty Get
. El código fuera de esta clase simplemente no puedeSet
esta referencia, está encapsulado :Private Type TFinder Hotels As Collection End Type Private this As TFinder Public Property Get Hotels() As Collection Set Hotels = this.Hotels End Property Private Sub Class_Initialize() Set this.Hotels = New Collection End Sub Private Sub Class_Terminate() Set this.Hotels = Nothing End Sub
Polimorfismo :
Implements
permite implementar interfaces abstractas (y clases concretas, también), y luego puede escribir código contra una abstracción deISomething
que bien puede ser unFoo
o unBar
(dado queFoo
yBar
implementanISomething
), y todo el el código siempre necesita ver esISomething
. La sobrecarga de métodos es una característica del lenguaje que VBA carece, pero la sobrecarga no tiene nada que ver con el polimorfismo, que es la capacidad de presentar la misma interfaz para diferentes formas subyacentes (tipos de datos) .Aquí hay un ejemplo de polimorfismo aplicado: el método
LogManager.Register
se complace en trabajar con cualquier objeto que implemente la interfaz deILogger
; aquí están siendo registrados unDebugLogger
y unFileLogger
, dos implementaciones muy diferentes de esa interfaz; cuandoLogManager.Log(ErrorLevel, Err.Description)
se invoca más tarde, las dos implementaciones harán lo suyo;DebugLogger
saldrá a laDebugLogger
inmediata , yFileLogger
escribirá una entrada en un archivo de registro específico:LogManager.Register DebugLogger.Create("MyLogger", DebugLevel) LogManager.Register Filelogger.Create("TestLogger", ErrorLevel, "C:/Dev/VBA/log.txt")
Herencia : VBA no le permite derivar un tipo de otro: la herencia no es compatible.
Ahora la pregunta es, ¿ puede un lenguaje que no admite herencia ser calificado como "orientado a objetos"? Resulta que la composición a menudo es preferible a la herencia, que tiene varias salvedades. Y VBA te permitirá componer objetos al contenido de tu corazón.
¿VBA es un lenguaje OOP?
Dado que todo lo que falta es herencia, y esa composición es preferible a la herencia, estoy tentado de responder "Sí". He escrito un código OOP VBA en toda regla antes (Model-View-Presenter con Unit-of-Work and Repository, anyone?), Que no habría escrito de manera diferente en un lenguaje "OOP real" que admite la herencia.
Aquí hay algunos ejemplos, todos 100% VBA:
- Un indicador de progreso reutilizable
- Modelo-Vista-Presentador
- Patrón UnitOfWork with Repository
- Registrador polimórfico
- Marco de Prueba de Unidad Automática
El código en este último enlace finalmente fue portado a C #, y rápidamente se convirtió en un complemento COM para el IDE de VBA que le proporciona refactorizaciones, una mejor navegación, inspecciones de código y otras herramientas.
VBA es tan limitante como lo haces.