Entwicklung von Klassen-AddIns(VBA)

In kleineren VBA-Projekten, die ihre komplette Geschäftslogik in einer einzelnen Datei beherbergen, gibt es wenig Gründe, Teile dieser Geschäftslogik in separate Add-Ins auszulagern. Dies würde nur Mehraufwand bedeuten, ohne dass der Entwickler oder der Anwender daraus einen Vorteil ziehen kann.

Sobald jedoch ein Projekt eine gewisse Komplexität erreicht hat, ist so ein Vorgehen wenig praktikabel. Als Beispiel möchte ich mein größtes Projekt aufführen. Dieses Projekt besteht aus zwei Excelanwendungen, die zwar komplett unterschiedliche Verarbeitung „im Bauch“ haben, jedoch nahezu identische Grundklassen verwenden. So lesen beide Anwendungen aus unterschiedlichen Datenquellen Personendaten ein und erzeugen Fehler- sowie Summenprotokolle. In so einer Situation bieten sich Add-Ins richtig an – sie kapseln eine in sich abgeschlossene fachliche Verarbeitung und stellen diese so bereit, dass sie in unterschiedlichen Excelanwendungen genutzt werden kann.

Als sich in diesem Projekt herauskristallisiert hat, dass es neben der ersten Anwendung noch eine weitere dazu kommt, die dieselbe Grundfunktionalität benötigen wird, begann ich, die vorhandenen Klassen in einzelne Add-Ins auszulagern, um diese auch dem neuen Programm bereitstellen zu können. Dabei stieß ich auf eine VBA-Besonderheit, die ich bisher nicht kannte und die mir nach wie vor nicht sehr schlüssig erscheint. Legt man nämlich in VBA ein Klassenmodul an, hat man im Attribut Instancing zwei Ausprägungen zur Auswahl:
1- Private
2- PublicNotCreatable

Dieses Attribut legt fest, wer Objekte dieser Klasse erzeugen kann. Solange sich die Klasse in der selben Datei wie die eigentliche Anwendung befindet, ist es kein Problem. Man belässt einfach die Standardeinstellung private und kann dabei Objekte dieser Klasse erzeugen und damit arbeiten. Lagert man jedoch diese Klasse in ein separates Add-In aus, ist sie für die Anwendung aufgrund der Ausprägung private nicht mehr sichtbar, sodass kein Objekt dieser Klasse erzeugt werden kann. Da dachte ich – ja, ist eigentlich auch logisch und kein Problem, dann stelle ich es einfach auf public um. Das Problem dabei war, dass es nicht einfach public, sondern publicNotCreatable heißt. Das bedeutet, dass die Klasse für die Anwendung zwar sichtbar ist, jedoch die Erzeugung von Objekten dieser Klasse von externen Anwendungen explicit untersagt ist (NotCreatable).

Tja. Keine der beiden Varianten ist anwendbar, was nun… Ich bin mir ziemlich sicher, dass der verantwortliche Chefentwickler bei Microsoft sich dabei was gedacht hat – mir hat sich der Sinn dahinter bisher aber nicht erschlossen. Wenn einer unter euch ein VBA-Guru ist, der er es mir erklären kann, wäre ich echt dankbar.

Zum Glück fand ich im Internet eine gute Alternative dazu. Diese sieht so aus, dass man die Klasse als PublicNotCreatable deklariert und dazu noch ein allgemeines Modul mit einer öffentlichen Funktion anlegt, die von dieser Klasse ein Objekt erzeugt und es als Rückgabewert zurück gibt.

Public Function getKlasseninstanz() As summenprotokoll
    
    Set getKlasseninstanz = New summenprotokoll

End Function

Nachdem ich dieses Add-In so fertiggestellt und abgelegt habe, habe ich dieses in der eigentlichen Anwendung im VBE-Editor unter „Verweise“ eingebunden. Auch seine Verwendung sieht anders aus, als bei Klassen, die sich direkt in der Anwendung befinden. Nach der obligatorischen Deklaration verwendet man für die Objekterzeugung kein New-Operator (was wie oben beschrieben eh nicht gehen würde), sondern ruft die Funktion getKlassenInstanz auf und legt den Verweis auf das zurückgelieferte Objekte mit Hilfe des Set-Operators in der Objektvariable ab. Ab dieser Stelle lässt sich dieses Objekt dann wie gewohnt verwenden und bietet den Zugriff auf alle öffentlichen Methoden der Klasse.

Dim summenProtokoll As klasseSummenprotokoll.summenProtokoll
Set summenProtokoll = klasseSummenprotokoll.getKlasseninstanz

Alles in einem war dieser Umweg und der damit verbundene Rechercheaufwand schon etwas lästig – allerdings wäre das Duplizieren und das Ablegen der Klasse in jeder Anwendung gar keine Alternative, zumal wir hier nicht von einer, sondern von insgesamt 11 Klassen reden 🙂

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.