VBA è un linguaggio OOP e supporta il polimorfismo?

In realtà sto lavorando al mio primo progetto VBA . (vieni da C ++ )

Vorrei migliorare un progetto VBA esistente utilizzato da una cartella di lavoro di Microsoft Excel implementando classi e polimorfismo.

Il mio problema è:

1 – Ho letto molti articoli / forum che spiegano che VBA non è un linguaggio di programmazione orientata agli oggetti ( OOP ) e non supporta il polimorfismo.

Alcuni di loro propongono una soluzione alternativa utilizzando la parola chiave Implements .

2 – Ho trovato anche alcune pagine web come questa che spiegano come eseguire OOP e il polimorfismo in VBA usando parole chiave come Erediti , Sostituzioni , Overridable , MustOverrides .

Quindi la mia domanda è:

VBA è un linguaggio OOP e supporta il polimorfismo?

OOP è seduto su 4 “pilastri”:

  • dai un'occhiata Astrazione – Astrazione logica e concetti possono essere facilmente fatti definendo oggetti nei moduli di class . A rigor di termini, l’ astrazione si ottiene anche utilizzando identificatori significativi ed estraendo codice procedurale in metodi (membri della class).

    Ecco un esempio di una procedura scritta in VBA che dimostra l’ astrazione :

     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 

    È facile dire quale sia la procedura di questo Test a colpo d’occhio, perché il livello di astrazione è molto elevato: i dettagli dell’implementazione sono astratti in oggetti e metodi più specializzati.

  • dai un'occhiata Incapsulamento : le classi possono avere campi privati ​​esposti per proprietà; le classi possono essere rese PublicNotCreatable , esponendo in modo efficace i tipi ad altri progetti VBA e con un piccolo sforzo (esportando il modulo di class, aprendolo nel tuo editor di testo preferito, modificando manualmente gli attributi di class e reimportando il modulo), può raggiungere tipi di sola lettura reali. Il fatto che non ci siano costruttori parametrici è irrilevante – basta scrivere un metodo factory che tenga tutti i parametri che ti piacciono e restituisca un’istanza. Questo è COM, e COM ama le fabbriche comunque.

    Ecco un esempio di come la class di HotelFinder dallo snippet sopra riportato incapsula un object Collection e lo espone solo tramite una Property Get accessor: il codice esterno a questa class non può semplicemente Set questo riferimento, è incapsulato :

     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 
  • dai un'occhiata PolymorphismImplements ti permette di implementare interfacce astratte (e anche classi concrete), e poi puoi scrivere il codice contro un’astrazione ISomething che può anche essere un Foo o una Bar (dato che Foo e Bar implementano entrambi ISomething ) – e tutto il il codice che deve mai vedere è ISomething . L’overloading del metodo è una caratteristica del linguaggio che manca a VBA, ma l’overloading non ha nulla a che fare con il polimorfismo, che è la capacità di presentare la stessa interfaccia per i diversi moduli sottostanti (tipi di dati) .

    Ecco un esempio di polimorfismo applicato: il metodo LogManager.Register è felice di lavorare con qualsiasi object che implementa l’interfaccia di ILogger ; qui un DebugLogger e un FileLogger – due implementazioni completamente diverse di quell’interfaccia, sono state registrate; quando LogManager.Log(ErrorLevel, Err.Description) viene richiamato in un secondo momento, le due implementazioni faranno ognuna la propria cosa; DebugLogger apparirà nella finestra degli strumenti immediata e FileLogger scriverà una voce in un file di registro specificato:

     LogManager.Register DebugLogger.Create("MyLogger", DebugLevel) LogManager.Register Filelogger.Create("TestLogger", ErrorLevel, "C:\Dev\VBA\log.txt") 
  • no Ereditarietà : VBA non consente di derivare un tipo da un altro: l’ereditarietà non è supportata.


Ora la domanda è: un linguaggio che non supporta l’ereditarietà può essere qualificato come “orientato agli oggetti”? Risulta che la composizione è molto spesso preferibile all’ereditarietà, che ha un numero di avvertimenti. E VBA ti consentirà di comporre oggetti a tuo piacimento.

VBA è un linguaggio OOP?

Dato tutto ciò che manca è l’ereditarietà, e quella composizione è preferibile all’ereditarietà, sono tentato di rispondere “Sì”. Ho scritto codice VBA OOP completo prima (Model-View-Presenter con Unit-of-Work e Repository, chiunque?), Che non avrei scritto diversamente in un linguaggio “reale OOP” che supporta l’ereditarietà.

Ecco alcuni esempi, tutti VBA 100%:

  • Un indicatore di progresso riutilizzabile
  • Modello Model View-Presenter
  • UnitOfWork con pattern Repository
  • Logger polimorfico
  • Quadro di prova di unità automagiche

Il codice in questo ultimo collegamento è stato infine trasferito su C # e rapidamente si è evoluto in un componente aggiuntivo COM per l’IDE VBA che fornisce refactoring, migliore navigazione, ispezioni di codice e altri strumenti.

VBA è solo limitante come lo si fa.

Le risposte brevi sono no e no.

VBA è basato su oggetti, che consente di definire classi e creare istanze di oggetti, ma manca delle funzionalità che sarebbero normalmente associate a un linguaggio OOP completo, ad esempio:

  • Incapsulamento e astrazione: VBA fornisce questo in misura. Le classi possono essere mantenute private con le interfacce pubbliche definite, tuttavia non è prevista alcuna disposizione per i costruttori all’interno delle classi. Le classi hanno un evento Class_Inititalize che può fare un po ‘di costruzione ma non può accettare argomenti. Passare argomenti richiederebbe una soluzione di fabbrica pubblica per risolvere i problemi ancora necessari per creare un modello di progettazione in stile costruttore.
  • Ereditarietà: non esiste realmente in VBA ma può essere quasi replicato
  • Polimorfismo: può essere raggiunto in una certa misura attraverso le interfacce (utilizzando gli Implements ) anche se la capacità di sovraccaricare le funzioni (ad esempio) non esiste e ogni “sovraccarico” richiederebbe tecnicamente un nome di funzione univoco. È ansible aggirare il problema passando un object come unico parametro a una funzione o sub e variando la procedura in base ai valori delle proprietà.

Quindi, mentre puoi lavorare con gli oggetti in una certa misura e le applicazioni di MS Office sono basate su un modello di oggetti, VBA non è davvero un linguaggio orientato agli oggetti. Il polimorfismo non può essere raggiunto nella misura in cui avresti familiarità con il C ++.