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 AddIns auszulagern. Dies würde nur Mehraufwand bedeuten, ohne dass der Entwickler oder der Anwender daraus einen Vorteil ziehen kann.

AddIns

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 diesem Anwendungsfall bieten sich AddIns 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 AddIns auszulagern, um diese auch dem neuen Programm bereitstellen zu können.

Problematik private vs. publicNotCreatable

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 AddIn 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).

Lösung

Tja. Keine der beiden Varianten ist anwendbar, was nun… Mit Sicherheit hat sich der verantwortliche Microsoft-Chefentwickler dabei was gedacht. Mir hingegen hat sich der Sinn dahinter bisher noch 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 Lösung – sogar von der offiziellen Seite – dazu:

  • man deklariert nämlich die Klasse als PublicNotCreatable
  • man legt ein allgemeines Modul mit einer öffentlichen Funktion an
  • diese öffentliche Funktion übernimmt die Objekterzeugung und stellt dieses als Rückgabewert bereit
Public Function getKlasseninstanz() As summenprotokoll
    Set getKlasseninstanz = New summenprotokoll
End Function

Anschließend habe ich dieses neu AddIn in der eigentlichen Anwendung im VBE-Editor unter „Verweise“ eingebunden. Um nun ein Objekt der Klasse Summenprotokoll in der Anwendung zu erhalten, ruft man lediglich Klassenfunktion getKlassenInstanz auf. Von hier an lässt sich dieses Objekt wie gewohnt verwenden und bietet den Zugriff auf alle öffentlichen Methoden der Klasse.

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

Alles in einem war dieser Umweg und der damit verbundene Rechercheaufwand schon lästig. Allerdings wäre das Duplizieren der Klassen in jeder Anwendung gar keine Alternative, zumal wir hier von insgesamt 11 Klassen reden 🙂

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.