Access Bedienungsanleitung: Globale Variablen und ihre Alternativen

Aus DBWiki
Wechseln zu: Navigation, Suche

In einer Access-Anwendung ergibt sich immer wieder die Notwendigkeit, Werte zentral speichern zu müssen, um sie von beliebiger Stelle aus jederzeit abrufen zu können.

Möglichkeit 1: Globale Variablen

Globale Variablen werden in einem globalen Modul hinterlegt, und als Public deklariert.

Beispiel:
Speichern einer Jahreszahl in einer globalen Variablen.


  • Die globale Variable wird in einem globalen Modul deklariert:
Public p_lngJahr as Long


  • Die globale Variable wird über eine Schaltfläche1 in einem beliebigen Formular gefüllt:
Private Sub MeineSchaltfläche1_Click() 
 p_lngJahr = 2016 
End Sub


  • Der Wert der globalen Variablen wird über eine Schaltfläche2 in einem beliebigen Formular ausgelesen:
Private Sub MeineSchaltfläche2_Click()
 MsgBox p_lngJahr
End Sub


Wiki hinweis.png

Nachteile:

• Der Name der globalen Variablen kann versehentlich zusätzlich in einem Formularmodul als private Variable gleichen Namens deklariert werden. Das sorgt für Chaos in der Datenbank, da einmal die private und das andere Mal die globale Variable angesprochen wird.
Man kann das einigermaßen in den Griff bekommen, indem die Namen von globalen Variablen eindeutig von privaten Variablen unterscheidbar sind, z.B. durch das Voranstellen eines zusätzlichen Zeichens z.B. "p_" oder "g_".

• Globale Variablen verlieren ihren Wert, wenn in der Anwendung ein nicht aufgefangener Laufzeitfehler auftritt. Das bedeutet in der Praxis, daß sie nur geeignet sind,
   • um Werte kurz zwischenzuspeichern
   • wenn ein fehlender Wert jederzeit leicht wieder ersetzt werden kann.


Möglichkeit 2: Ein unsichtbares Formular

Ein Formular mit einer zugrundeliegenden Tabelle wird unsichtbar (hidden) geöffnet. Werte können jederzeit über das Formular in die Tabelle geschrieben oder über das Formular aus der Tabelle ausgelesen werden.

Beispiel:
Speichern einer Jahreszahl im unsichtbaren Formular/Tabelle
Das unsichtbare Formular bekommt in diesem Beispiel den Namen Administrator, und das zugehörige Tabellenfeld den Namen Geschäftsjahr.


  • Das Formular wird unsichtbar geöffnet:
DoCmd.OpenForm "Administrator", , , , , acHidden


  • Das Tabellenfeld wird über eine Schaltfläche1 in einem beliebigen Formular gefüllt:
Private Sub MeineSchaltfläche1_Click()
 Forms!Administrator!Geschäftsjahr = 2016
End Sub


  • Der Wert des Tabellenfeldes wird über eine Schaltfläche2 in einem beliebigen Formular ausgelesen:
Private Sub MeineSchaltfläche2_Click()
 MsgBox Forms!Administrator!Geschäftsjahr
End Sub


Wiki hinweis.png

Hinweise:

Vorteil: Die Werte bleiben in der Tabelle auch nach dem Schließen der Datenbank dauerhaft gespeichert.
Kleiner Nachteil: Um eine neue Speichermöglichkeit hinzuzufügen oder zu löschen, muss in der dem Formular zugrundeliegenden Tabelle ein neues Feld angelegt oder gelöscht werden.


Möglichkeit 3: Temporäre Variablen (TempVars)

Temporäre Variablen (ab Access 2007) haben den Datentyp Variant.


  • TempVar füllen oder Wert ändern:
    Nicht nur die Variante TempVars.Add legt eine neue temporäre Variable an, wenn diese noch nicht vorhanden ist. Auch die einfache Zuweisung erzeugt gegebenenfalls eine neue temporäre Variable.
'entweder
TempVars.Add "t_lngJahr", 2016
'oder
TempVars("t_lngJahr") = 2016
'oder
TempVars!t_lngJahr = 2016
Der Name der TempVar kann auch als Variable übergeben werden.
Dim strName As String
strName = "t_lngJahr"
 
'entweder
TempVars.Add strName, 2016
'oder
TempVars(strName) = 2016


  • Wert der TempVar auslesen:
'entweder
MsgBox TempVars.Item("t_lngJahr")
'oder
MsgBox TempVars("t_lngJahr")
'oder
MsgBox TempVars!t_lngJahr


  • TempVar löschen:
TempVars.Remove "t_lngJahr"
TempVars.Remove strName


  • Alle TempVars löschen:
TempVars.RemoveAll


  • Alle TempVars können in einer For-Each-Schleife durchlaufen werden.
Dim objTempVar As TempVar
For Each objTempVar In TempVars
  Debug.Print "Name: " & objTempVar.Name, "Wert: " & objTempVar.value
Next objTempVar
  • Alle TempVars können auch in einer For-Schleife durchlaufen werden.
Dim i As Integer
For i = 0 To TempVars.Count - 1
  Debug.Print "Name: " & TempVars(i).Name, "Wert: " & TempVars(i).value
Next i


Wiki hinweis.png

Hinweise:
• Temporäre Variablen (TempVars) werden im Gegensatz zu herkömmlichen globalen Variablen im Falle eines nicht aufgefangenen Laufzeitfehlers nicht geleert. Sie behalten ihren Wert, bis die Datenbank geschlossen wird, oder bis sie per Code geleert werden.
• TempVars können auch in Makros genutzt werden.
• TempVars können auch in Abfragen genutzt werden, z.B.

... WHERE Year(Bestelldatum) = TempVar!t_lngjahr


Möglichkeit 4: Properties

Beispiel:
Speichern einer Jahreszahl in einer Property (Eigenschaft).


  • Schritt 1: Ein Klassenmodul wird erstellt (VBA-Codebereich - Einfügen - Klassenmodul).
    Das Modul bekommt von Access standardmäßig den Namen Klasse1 zugewiesen. Es sollte aber der Übersichtlichkeit halber einen sprechenden Namen erhalten, z.B. GlobVars, GlobaleVariablen, PubVars, ClassVars o.ä..


  • Schritt 2: In einem beliebigen "normalen" Globalen Modul wird das Klassenobjekt als Public deklariert.
    Das Klassenmodul heißt hier GlobVars. Die Objektvariable heißt hier glob.
Public glob As GlobVars


  • Schritt 3: Im Klassenmodul GlobVars wird eine sogenannte Membervariable als Private deklariert. Die Membervariable dient quasi als "Handlanger" für das Einlesen und Auslesen eines Wertes.
Private m_lngjahr As Long 'Long-Membervariable
Private m_frm As Access.Form  'Objekt-Membervariable


  • Schritt 4: Im Klassenmodul GlobVars werden die Property-Prozeduren erstellt.
Property Let übernimmt das Füllen, und Property Get das Auslesen des Wertes aus der Property.
Public Property Let lngJahr(ByVal Wert As Long)
  m_lngJahr = Wert
End Property
 
Public Property Get lngJahr() As Long
  lngJahr = m_lngJahr
End Property

Für Objekte übernimmt Property Set das Füllen, und Property Get das Auslesen des Wertes aus der Property.

Public Property Set frm(ByVal Wert As Access.Form)
  Set m_frm = Wert
End Property
 
Public Property Get frm() As Form
  Set frm = m_frm
End Property

Alternativ kann in die Property-Prozedur eine Gültigkeitsprüfung sowohl beim Füllen, als auch beim Auslesen eingebaut werden.
Beispiel:

Public Property Let lngJahr(ByVal Wert As Long)
 
 If Wert < 2000 Or Wert > 2100 Then
   Err.Raise vbObjectError, "Geschäftsjahr", Wert & " ist kein gültiges Jahr"
 End If
 
 m_lngjahr = Wert
 
End Property


  • Schritt 5: Das Klassenobjekt wird gesetzt.
    In dem Codeteil, der zuerst gestartet wird, z.B. das Form_Open- oder das Form_Load-Ereignis eines Formulars, wird das Klassenobjekt gesetzt. Das Klassenobjekt kann auch über eine Schaltfläche gesetzt werden.
Private Sub Form_Open(Cancel As Integer)
 Set glob = New GlobVars
End Sub


  • Schritt 6:
    Die Property wird z.B. über eine Schaltfläche1 im Formular gefüllt:
Private Sub MeineSchaltfläche1_Click()
 glob.lngJahr = 2016
 Set glob.frm = Me
End Sub
Der Wert der Property wird z.B. über eine Schaltfläche2 im Formular ausgelesen:
Private Sub MeineSchaltfläche2_Click()
 MsgBox glob.lngJahr
 MsgBox glob.frm.Name
End Sub


Praktisches Anwendungs-Beispiel

Werte automatisiert aus einer Konfigurations-Tabelle auslesen

  • Man kann eine Property in einem Globalen Modul verwenden, um Werte aus einer Tabelle, in der feste Anwendungseinstellungen gespeichert sind, auszulesen. Zum Auslesen der Werte kann alternativ zur unten verwendeten DLookup-Funktion auch eine eigene, spezielle Funktion erstellt werden.
  • Die Property wird in der Anwendung wie eine globale (allerdings nur lesende) Variable verwendet. Im Gegensatz zur Variablen holt sie sich ihren Wert automatisch selbst aus der Tabelle, aber nur dann, wenn die Property noch keinen Wert hat, oder ihr Wert verloren gegangen ist. Damit kann der Wert nur aus der Tabelle ausgelesen, aber nicht in der Tabelle verändert werden, und bleibt somit schreibgeschützt.
  • Der Wert aus der Tabelle wird mittels der Property im Speicher vorgehalten, damit man nicht so oft auf die Tabelle zugreifen muss.
Private m_lngjahr As Long
 
Public Property Get lngJahr() As Long
 
  'wenn noch kein Wert zugewiesen, oder der Wert verlorenen gegangen ist
  If lngJahr = 0 Then
    'Property-Let-Vorgang: aktuellen Wert aus der Tabelle "tblKonfiguration" holen, 
    'und der Membervariablen zuweisen
    m_lngjahr = DLookup("Geschäftsjahr", "tblKonfiguration")
  End If
 
  'Wert der Membervariablen ausgeben
  lngJahr = m_lngjahr
 
End Property
 
'Aufruf
 MsgBox lngJahr


Wiki hinweis.png

Hinweise:

  • Die Prüfung, ob eine Property einen gültigen Wert enthält, findet - im Gegensatz zu Globalen Variablen - nur an einer Stelle im Code statt: In der Property-Prozedur.
  • Würde man eine globale Variable verwenden, müsste man sich an jeder Stelle des Codes, an der die Variable verwendet wird, darum kümmern, ob diese initialisiert (mit passendem Wert befüllt) wurde. Bei größeren Projekten verliert man dadurch schnell die Übersicht, und handelt sich vermeidbare Fehler ein.
  • Mit einer Property-Prozedur kann man Werte prüfen, bevor sie übermittelt werden, sei es bei der Ausgabe (Get) als auch bei der Annahme (Let).
  • Property-Prozeduren können statt in einem Klassenmodul auch in einem Globalen Modul eingesetzt werden. Dadurch entfallen das Erstellen der Objektvariablen und das Setzen des Klassenobjekts.
    Nachteil: Es kann keine Public Variable mit gleichem Namen existieren, und bei Verwendung einer gleichnamigen Private Variablen in einem Formularmodul würde die Variable statt der Property angesprochen.
  • Eine Property in einem Klassenmodul dagegen kann den gleichen Namen wie eine Public oder Private Variable haben, weil sie - im Gegensatz zur Variablen, z.B. lngJahr - immer über ihr Klassenobjekt angesprochen wird, z.B. glob.lngJahr
  • Auch Properties verlieren ihren Wert, wenn ein nicht aufgefangener Laufzeitfehler auftritt.


Web-Links

TempVars:

Properties: