Tipps & Tricks: Propertys

Was ist eine Property oder: Wie schütze ich meine Variablen?

Wir wissen, dass es neben Sub und Function Prozeduren sog. Property (Eigenschaften) Prozeduren gibt. Aber um welche bzw. wessen Eigenschaften geht es dabei überhaupt?

Im Rahmen dieser Einführung beschränken wir uns auf die einfache Nutzung von Property-Prozeduren zur „Kapselung“ von Variablen.

Option Explicit
 
Dim sMeinDateiPfad As String
 
Sub Schreibe_in_die_Datei()
    Dim i As Integer
    Open sMeinDateiPfad For Input As #i
    '...
    Close #i
End Sub

In dieser Routine (Schreibe_in_die_Datei) wird direkt versucht, eine Datei zu öffnen, dessen Pfad in der Variable sMeinDateiPfad steht bzw. stehen sollte.

Ist dies jedoch nicht der Fall, kommt es hier zu einem Programmfehler. Jetzt kann man vor dem Öffnen der Datei zunächst prüfen, ob die Variable bereits den richtigen Dateipfad enthält. Das muss aber dann jedes Mal und in jeder Routine erfolgen, die über diese modulglobale Variable versuchen, auf die Datei zuzugreifen; dies ist äußerst umständlich und auch nicht ganz ungefährlich. Ändern sich nämlich der Dateipfad, muss dies in allen Routinen „nachgezogen“ werden, die auf diesen Dateipfad zugreifen.

Die Lösung heißt: Kapselung der Variabelen-Initialisierung und –Prüfung innerhalb einer Property-Prozedur. Hierbei werden allen notwendigen Schritte Property-Prozedur durchgeführt. Die Routine Schreibe_in_die_Datei würde lediglich die Property-Prozedur aufrufen, die dann den korrekten Dateipfad zurückliefert.

Es gibt grundsätzlich immer 2 Varianten einer Property-Prozedur: eine Get und eine Let-Variante.

  • Die Get Variante funktioniert wie Funktion und gibt einen Wert zurück.
  • Die Let Variante ist dafür zuständig, die betroffene Variable zu initialisieren.

Nennen wir unsere Property beispielsweise MeinDateiPfad. Damit wir nicht die Arbeit haben, jetzt direkt 2 Prozedurblöcke erstellen zu müssen, nutzen wir einen Assistenten, den VBA uns zur Verfügung stellt:

Über das Menü im VBA-Editor Einfügen - Prozedur... rufen wir einen kleinen Dialog auf, in dem wir den Namen der Prozedur, seinen Typ und seinen Gültigkeitsbereich eintragen.

VBA erstellt uns nach Klick auf die OK-Schaltfläche in diesem Fall direkt 2 neue Prozeduren; diese werden i.d.R. am Ende unseres Codebereichs eingefügt.

Private Property Get MeinDateiPfad() As Variant
 
End Property
 
Private Property Let MeinDateiPfad(ByVal vNewValue As Variant)
 
End Property

Etwas unschön dabei ist die automatische Vergabe des Datentyps Variant für beide Prozeduren. Es ist zu empfehlen hier „typsicher“ zu bleiben und jeweils den Datentyp in String zu ändern.

Diese beiden Prozeduren haben jetzt ausschließlich die Aufgabe, sich um die Variable sMeinDateiPfad zu kümmern.

Die Let-Prozedur ist dafür zuständig, der Variablen sMeinDateiPfad einen Wert zuzuweisen; und zwar genau den Wert, der im Argument vNewValue übergeben wird.

Die Get-Prozedur wiederum ist dafür zuständig, den Wert der Variablen sMeinDateiPfad zurückzugeben.

Dim sMeinDateiPfad As String
 
Private Property Get MeinDateiPfad() As String
 
    MeinDateiPfad = sMeinDateiPfad
 
End Property
 
Private Property Let MeinDateiPfad(ByVal vNewValue As String)
 
    sMeinDateiPfad = vNewValue
 
End Property

Wir haben jetzt den Zugriff auf die Variable durch entsprechende Property-Prozeduren gekapselt. Der Zugriff erfolgt entsprechend über deren Bezeichnung:

Sub Main()
 
    MeinDateiPfad = "C:\MeineDatei.txt"
    MsgBox "Der aktuelle Dateipfad lautet: " & MeinDateiPfad
 
End Sub

Wo liegt denn jetzt der Vorteil?

Der Vorteil liegt in der Möglichkeit, die Variable vor Rückgabe bzw. beim „Setzen“ zu plausibilisieren. Wenn man den Wert einer Variablen ermittelt, besteht keine Möglichkeit mehr, noch „korrigierend“ eingreifen zu können. Bei der Kapselung einer Variablen über Property-Prozeduren ist das jedoch sehr leicht möglich. Darüber hinaus lässt sich ggf. sogar ein „Schreibschutz“ einrichten.

Für unser Beispiel möchten wir plausibilisieren, ob die Variable bereits initialisiert wurde, und falls ja, ob der Wert der Variable auch gültig ist. Dies stellt sich beispielhaft wie folgt dar:

Beispiel:

Option Explicit
 
Dim sMeinDateiPfad As String
 
Sub Main()
 
    MeinDateiPfad = "C:\MeineDatei.txt"
    Schreibe_in_die_Datei
 
End Sub
 
Sub Schreibe_in_die_Datei()
 
    Dim i As Integer
    i = FreeFile
    Open MeinDateiPfad For Input As #i
    '...
    Close #i
 
End Sub
 
Private Property Get MeinDateiPfad() As String
 
    MeinDateiPfad = sMeinDateiPfad
 
End Property
 
Private Property Let MeinDateiPfad(ByVal vNewValue As String)
 
   'Bevor wir jetzt die Variable mit dem übergebenen Wert
   'beschreiben, prüfen wir nach, ob die Datei überhaupt vorhanden
   'ist. Falls nicht, setzen wir einen anderen Pfad.
    If Dir(vNewValue) = "" Then
        vNewValue = "C:\MeineDatei2.txt"
    End If
    sMeinDateiPfad = vNewValue
 
End Property

In der hier gezeigten Let-Prozedur wird der ursprünglich vorgesehene Dateipfad verändert.

Diese Plausibilisierung ließe sich natürlich auch in der Get-Anweisung vor Rückgabe des Variablenwertes durchführen.

Wann, wo und wie mithilfe dieser Property-Prozeduren Variablenwerte plausibilisiert und ggf. verändert werden ist davon abhängig, welche „Fachlichkeit“ und welche Prüfungen durchzuführen sind.

Grundsätzlich wird der eigene Code durch Nutzung von Property-Prozeduren bei der Bearbeitung von globalen Variablen deutlich sicherer und flexibler.