Language: Deutsch English















Last Update: 2017 - 03 - 20





Objekte und Klassen in der VBA-Entwicklung verwenden

von Philipp Stiefel, ursprünglich veröffentlich 9.August 2016


Building Blueprints, article header image

Photo by Wokandapix used here under CC0 licensing

Wenn du bereits ein paar VBA Prozeduren geschrieben hast, hast du höchstwahrscheinlich auch Objekte in deinem VBA-Code verwendet. Aber bist du dir wirklich über das Konzept hinter Objekten und Klassen bewusst?

Wenn du noch bereits Erfahrungen in einer anderen Programmiersprache hast, oder bereits sehr weit fortgeschrittene VBA-Kenntnisse hast, wahrscheinlich nicht. – Und das ist etwas, dass du ändern solltest, um deine VBA Programmierkenntnisse zu verbessern. Fang doch gleich damit an, indem du weiterliest…

Was sind Objekt und Klassen?

Objekte und Klassen hängen sehr eng miteinander zusammen. Zuerst werde ich die Funktionsweise von Objekten etwas erläutern, die du wahrscheinlich bereits verwendet hast. Danach ist es einfacher den Zweck der Klassen hinter den Objekten zu verstehen.

Objekte

Es sind bereits sehr viele Objekte direkt in den „eingebauten“ Objektbibliotheken von Access, DAO und/oder ADO und, in geringerem Maße, auch in der VBA Basisbibliothek vorhanden. Häufig verwendete Beispiele dafür sind die Access.Form- oder -.Report-Objekte oder das DAO.- Oder ADO.Recordset.

Sehr wichtig für das Verständnis von Objekte, ist die Tatsache, dass Objekte ihren Zustand behalten. Sie unterscheiden sich darin von den gewöhnlichen Funktionen und Prozeduren, die (fast) immer im gleichen Ursprungszustand sind, wenn sie aufgerufen werden. Wenn die Ausführung einer normale Prozedur (oder Funktion) abgeschlossen ist, wird der komplette Zustand den sie während ihrer Laufzeit intern verwaltet hat, wieder zurückgesetzt.

Objekte behalten ihren Zustand über ihre komplette Lebensdauer. Wenn du die Eigenschaft eines Objektes auf einen bestimmten Wert setzt, wird diese üblicherweise den Wert so lange behalten, wie das Objekt im Speicher bleibt.

Ein einfaches Beispiel für diesen Sachverhalt ist die Titel-Eigenschaft (Caption)eines Formulars. Sobald du für diese einen bestimmen Text eingestellt hast, behält das Formular diesen Titel bis du das Formular schließt. – Oder den Titel auf einen anderen Wert setzt.

Ähnlich gilt das für Prozeduren (Methoden) von Objekten. Wenn du sie aufrufst, können sie den Zustand des Objektes und damit einer oder mehrerer seiner Eigenschaften verändern. Der neue Zustand bleibt dann bis zu einem weiteren Methodenaufruf bestehen.

Ein gutes Beispiel dafür sind die Methoden eines Recordsets. Das Recordset enthält Datensätze aus deiner Datenbank. Wenn du die MoveNext-, MovePrevious- oder MoveLast-Methode aufrufst, ändert sich der Zustand des Recordsets. Der interne Zeiger auf den aktuellen Datensatz wird auf den nächsten, vorigen oder letzten Datensatz geändert. Dadurch ändert sich automatisch und zwingend die AbsolutPosition-Eigenschaft. Abhängig von der jeweiligen Position innerhalb der Datensatzgruppe können sich auch die EOF- oder BOF-Eigenschaften ändern.

Verwendung des DAO.Recordset Objektes in VBA

Wenn du diese wenigen, gängigen Beispiele für Objekte betrachtest, solltest du schnell verstehen, wie nützlich Objekte in der Programmierung sind.

Klassen

Nun zu den Klassen. Die vorigen Beispiele haben sich mit Objekten beschäftigt, die in den eingebauten Objektbibliotheken vordefiniert sind.

Wäre es nicht nützlich, wenn du deine eigenen Objekte definieren könntest? – Ja, natürlich wäre es das! Und das kannst du auch.

Jetzt kommen die Klassen ins Spiel. Klassen, oder Klassenmodule im VBA-Terminus, sind die Blaupausen für Objekte. Wenn du also in VBA ein Klassenmodul schreibst, definierst du damit (d)ein eigenes Objekt.

Klassenmodule in VBA erstellen

Wenn du mit „normalen“ VBA-Module bereits vertraut bist, hast du bereits die viele der Grundkenntnisse, die erforderlich sind, um eine Klasse zu schreiben.

Innerhalb der VBA-Entwicklungsumgebung erstellst du eine neue Klasse, indem du entweder das Einfügen Menü, oder den entsprechenden Button in der Symbolleiste verwendest, um eine neues Klassenmodul in dein VBA-Projekt einzufügen.

Button in der Symbolleiste für neues Klassenmodul

Eigenschaften und Methoden

Wie bei „normalen“ Modulen auch, sind der wichtigste Teil eines Klassenmoduls die Funktionen und (Sub-)Prozeduren (zusammen Methoden) und die Property Prozeduren (Eigenschaften).

Ein Unterschied besteht jedoch bei den Variablen. In „normalen“ Modulen wirst du üblicherweise alle deinen Variablen lokal (innerhalb) der jeweiligen Prozeduren mit dem Dim-Schlüsselwort deklarieren. Diese Variablen verlieren ihre Werte wieder, sobald die Ausführung der jeweiligen Prozedur abgeschlossen ist.

Innerhalb der Methoden von Klassenmodulen wirst du weiterhin die diese meisten Variablen auf die oben beschriebene Weise deklarieren. Aber fast jede Klasse wird auch ein paar Variablen enthalten, die im Gültigkeitsbereich der Klasse deklariert sind. Diese Variablen werden verwendet, um den Zustand der Objekte zu speichern, die basierend auf deiner Klasse instanziiert werden.

Diese Variablen werden im Kopfbereich des Klassenmoduls, vor dem Beginn der ersten Prozedur  deklariert. Üblicherweise wirst du das Private Schlüsselwort anstelle von Dim verwenden, um diese klassenweit gültigen Variablen zu deklarieren.

Deklaration Privater Variablen in einem VBA Klassenmodul

Einfach, oder?

Nun sind diese Variablen innerhalb aller Prozeduren deines Klassenmoduls gültig und du kannst ihre jeweiligen Werte aus jeder Prozedur der Klasse auslesen und auch ändern.

Wenn du auf die Werte dieser Variablen auch von außerhalb der Klasse zugreifen willst, solltest du für diesen Zweck eine besondere Art von Prozedur schrieben. Eine Property Prozedur.

Property Prozeduren gibt es in drei verschieden Varianten. Get-, Let- und Set-Property-Prozeduren.

Der Zweck der Get Property Prozeduren lässt sich anhand des Namens erraten. Sie werden üblicherweise verwendet, um den Wert einer internen Variable der Klasse an die Außenwelt zu übermittelt.

Die Set- und Let-Property-Prozeduren haben beide im Wesentlichen den Zweck um die Werte von klasseninternen Variablen von außen setzen zu können. Sie unterscheiden sich darin, dass die Set-Prozeduren verwendet werden, um den Wert von Objektvariablen zu setzen, während die Let-Prozeduren für einfache, eingebaute Datentypen verwendet werden.

Property Get/Let/Set-Prozeduren in einem VBA Klassenmodul

Ich habe oben ganz bewusst die Formulierungen „üblicherweise“ und „im Wesentlichen“ im obigen Absatz verwendet.  - Property Prozeduren schränken dich in keiner Weise darin ein, was du in ihrem Code tun kannst. Aber die oben jeweils genannten Verwendungszwecke sind das, was diese Prozeduren konventionsgemäß tun. So lange du keinen wirklich guten Grund dafür hast, von dieser Konvention abzuweichen, solltest du den Code von Property Prozeduren auf Dinge beschränken, die unmittelbar mit dem Lesen und Schreiben der internen Variablen zusammenhängen.

Das Me-Schlüsselwort

Du hast wahrscheinlich das Me-Schlüsselwort bereits in deinem VBA-Code innerhalb von Formularen Berichten (Übrigens auch Klassenmodule!) verwendet. Me wird innerhalb eines Klassenmoduls verwendet, um auf die jeweils eigene Objektinstanz des Klassenmoduls zu verweisen. Also zeigt Me als Referenz immer auf das Objekt in dem der Code jeweils ausgeführt wird.

Eigene Ereignisse definieren

Anders als in normalen Modulen, kannst du in Klassenmodulen deine eigenen Ereignisse definieren. Ereignissen für sich genommen stehen für ein mächtiges und umfangreiches Programmierparadigma. Ereignisse in der Tiefe zu beschreiben, die sie verdienen, würde den Rahmen dieses Artikels bei weitem sprengen. Tatsächlich verdienen sie eine ganze Artikelserie, von der ich bisher allerdings nur den ersten Einführungsartikel zu Ereignissen geschrieben habe.

Eigene Objekte im Code verwenden

Da ich mir ziemlich sicher bin, dass du bereits Objekte in deinem Programmcode verwendet hast, werde ich mich hier eher kurz fassen.

Der Teil mit dem du bisher vielleicht nicht so vertraut bist, ist die Instanziierung von Objekten. Für die gängigen Objekte aus den eingebauten Objektbibliotheken stehen Factory-Methoden bereit, die die Objekte für dich erzeugen und initialisieren. Beispiele dafür sind die CurrentDb-Methode um ein DAO.Database-Objekt zu erhalten oder die .OpenRecorset-Methode um, basierend auf einem SQL-Statement, ein bereits geöffnetes Recordset zu erhalten.

Du kannst dir natürlich ähnliche Factory-Methoden auch für deine eigenen Objekte schreiben, aber an einer Stelle musst du eine neue Objektinstanz mit dem New Operator erzeugen. Die Syntax dafür ist:

Dim yourObjectVariable as YourClassName Set yourObjectVariable = New YourClassName yourObjectVariable.DoSomething

Danach kannst du dann weitere Eigenschaften (Properties) des Objektes setzen, das du somit aus deiner Klasse erzeugt hast, und jede der (öffentlichen/public) Methoden des Objektes aufrufen.

Das wirklich nützliche an Objekten ist, wie eingangs schon erwähnt, dass sie ihren Zustand zwischen den einzelnen Aufrufen ihrer Methoden behalten. Dies macht es wesentlich einfacher komplexe, mehrschrittige Prozesse zu implementieren.

Zuletzt möchte ich nochmal in Erinnerung rufen, was wir zu Beginn über die Lebensdauer von Variablen gelernt haben. Im obigen Beispiel haben wir unser Objekt innerhalb einer Prozedur instanziiert. Wie alle anderen Variablen auch, wir unsere Objektvariable zerstört und ihr Wert geht verloren, wenn die Ausführung der Prozedur abgeschlossen ist.

Wenn du deine Objektvariable in Deklarationsbereich eines anderen (Klassen-)Moduls (z.B. eines Formulars) deklarierst, dann bleibt dein Objekt solange mit seinem aktuellen Zustand bestehen, wie auch die Instanz des deklarierenden Klassenmoduls (z.B. des Formulars) existiert. Du kannst das Objekt also in anderen Prozeduren wieder-/weiterverwenden.

Sei dir aber auch darüber bewusst, dass auch mit Objektvariablen mit modulweiter oder sogar globaler Gültigkeit das Risiko von schwer nachvollziehbaren Fehlern einhergeht. Z.B. wenn eine Objektvariable nicht (mehr) den Zustand hat, den du an der jeweiligen Stelle erwartest. Also sei vorsichtig, wenn du Objektvariablen (irgendwelche Variablen) mit einen Gültigkeitsbereich deklarierst, der über eine konkrete Prozedur hinausgeht. - Tu das nur, wenn es wirklich unbedingt notwendig ist.

Fazit

Eigene Klassen in VBA zu programmieren und die darauf basierenden Objekte zu verwenden ist ein sehr mächtiges Konzept. Einige bewährte Programmiermuster kannst du in VBA (und den meisten anderen Sprachen auch) nur dann einsetzen, wenn du dieses Basiswissen zu Klassen und Objekten anwendest.

Du solltest die Konzepte von Klassen und Objekten verinnerlichen, um deine Programmierkenntnisse auf eine neue Stufe zu bringen.

Share this article: Share on Facebook Tweet Share on LinkedIn Share on XING

Abonniere meinen Newsletter

*

Ich werde Deine Email-Addresse niemals weitergeben. Du kannst den Newsletter jederzeit abbestellen.



© 1999 - 2016 by Philipp Stiefel