Kurzfassung — Schreiben Sie
Public gTaxRate As Doublean den Anfang eines Standardmoduls, über jede Prozedur, und jede Prozedur der Arbeitsmappe kann den Wert lesen und ändern. Das ist die leichte Hälfte. Die schwere Hälfte: Eine globale Variable behält ihren Wert nur, solange das VBA-Projekt geladen bleibt, und das Projekt wird öfter zurückgesetzt, als man denkt — durch eineEnd-Anweisung, die Zurücksetzen-Schaltfläche, einen unbehandelten Fehler, den der Benutzer beendet, eine Änderung im VBA-Editor, das Schließen der Arbeitsmappe. Nach dem Zurücksetzen steht jede globale Variable wieder auf0,""oderNothing, ohne jede Warnung. Lesen Sie eine globale Variable also nie, ohne sie gerade geprüft zu haben: Greifen Sie über eine Funktion darauf zu, die sie neu aufbaut, wenn sie leer ist, und speichern Sie alles, was die Sitzung überdauern muss, in der Arbeitsmappe selbst.
' Module1 - ganz oben, ueber jedem Sub und jeder Function
Option Explicit
Public gTaxRate As Double ' sichtbar fuer jedes Modul in diesem Projekt
Sub SetUp()
gTaxRate = 0.19
End Sub
Sub UseIt()
Debug.Print gTaxRate ' 0.19 - bis das Projekt zurueckgesetzt wird, dann 0
End Sub
Dies ist der erste Teil einer dreiteiligen Reihe darüber, wo ein Wert lebt. Jede Variable hat einen Gültigkeitsbereich — wer sie sieht — und eine Lebensdauer — wie lange sie sich etwas merkt. Eine globale Variable hat von beidem das Maximum: das ganze Projekt, bis das Projekt zurückgesetzt wird. Eine Static-Variable behält die lange Lebensdauer, schrumpft den Gültigkeitsbereich aber auf eine einzige Prozedur. Ein optionaler Parameter schrumpft beides auf einen einzigen Aufruf, und der Aufrufer reicht den Wert herein. Meine Regel für die ganze Reihe: Nehmen Sie die engste Variante, die funktioniert.
Was Sie lernen
- Das Denkmodell: Gültigkeitsbereich heißt, wer einen Wert sieht, Lebensdauer, wie lange er hält
- Wie Sie eine globale Variable deklarieren, und Public vs. Global vs. Dim am Modulanfang
- Was eine globale Variable zurücksetzt und warum der Wert ohne Fehlermeldung verschwindet
- Die selbstheilende Zugriffsfunktion, die ein Zurücksetzen harmlos macht
- Das lokale
Dim, das Ihre globale Variable stillschweigend verdeckt, und der Fehler wegen mehrdeutiger Namen - Public-Variablen in Tabellen-, ThisWorkbook- und UserForm-Modulen
- Wie ein Wert das Schließen der Arbeitsmappe überdauert
Das Denkmodell: Gültigkeitsbereich und Lebensdauer sind zwei verschiedene Fragen
Der Ort, an dem Sie eine Variable deklarieren, beantwortet zwei Fragen auf einmal. Der Gültigkeitsbereich legt fest, wer sie sieht. Die Lebensdauer legt fest, wie lange sie ihren Wert behält. VBA kennt drei Ebenen:
| Deklariert | Schlüsselwort | Gültigkeitsbereich | Lebensdauer |
|---|---|---|---|
Innerhalb eines Sub oder einer Function |
Dim |
nur diese Prozedur | bis die Prozedur endet |
| Am Anfang eines Moduls | Dim oder Private |
jede Prozedur dieses Moduls | bis das Projekt zurückgesetzt wird |
| Am Anfang eines Standardmoduls | Public (oder Global) |
jede Prozedur des Projekts | bis das Projekt zurückgesetzt wird |
Die erste Zeile behandelt die Dim-Anleitung. In diesem Artikel geht es um die letzte, und die entscheidende Tatsache steht in der letzten Spalte: Variablen auf Modulebene und öffentliche Variablen leben nicht, bis Sie Excel schließen, und sie sterben auch nicht, wenn die Prozedur endet, die sie gesetzt hat. Sie leben genau so lange wie der Zustand des Projekts, und dieser Zustand ist zerbrechlicher, als er aussieht.
Eine globale Variable deklarieren: Public, Global und wohin die Zeile gehört
Eine globale Variable muss im Deklarationsabschnitt eines Standardmoduls stehen: nach Option Explicit,
vor der ersten Prozedur. Schreiben Sie dieselbe Zeile in ein Sub, lehnt VBA sie ab, denn Public ist
innerhalb einer Prozedur nicht erlaubt.
Option Explicit
Public gUserName As String ' projektweit
Global gRunCount As Long ' dasselbe, aelteres Schluesselwort
Private mCache As Object ' nur modulweit
Dim mLastRow As Long ' ebenfalls nur modulweit
Sub Demo()
' Public x As Long waere hier ein Kompilierfehler
End Sub
Global ist die ältere Schreibweise von Public. Es funktioniert nur in Standardmodulen und bringt nichts
Zusätzliches, nehmen Sie also Public. Auf Modulebene bedeuten Dim und Private dasselbe; bevorzugen Sie
Private, weil es sagt, was Sie meinen. Ein Präfix wie g für globale und m für modulweite Variablen
kostet nichts und verhindert den Bug aus einem der folgenden Abschnitte.
Ändert sich der Wert nie, ist er gar keine Variable. Nehmen Sie Public Const VAT_RATE As Double = 0.19; wie
die Const-Anleitung zeigt, kann eine Konstante weder abdriften noch zurückgesetzt
werden.
Die Regel, die zubeißt: Eine globale Variable lebt nur so lange wie das Projekt
Hier ist der Fehler, den jeder einmal erlebt. Ein Makro setzt gTaxRate beim ersten Klick, eine zweite
Schaltfläche verwendet den Wert, und das funktioniert den ganzen Vormittag. Nach der Mittagspause rechnet die
zweite Schaltfläche mit 0. Kein Fehler wurde ausgelöst. Dazwischen wurde das Projekt zurückgesetzt, und ein
Zurücksetzen stellt jede modulweite und öffentliche Variable auf ihren leeren Wert zurück:
- Irgendwo läuft eine
End-Anweisung, die, wie die End-Anleitung zeigt, den gesamten Zustand auf einen Schlag löscht. - Sie klicken im VBA-Editor auf Zurücksetzen (die quadratische Schaltfläche) oder wählen Ausführen > Zurücksetzen.
- Ein unbehandelter Laufzeitfehler erscheint, und der Benutzer klickt im Dialog auf Beenden.
- Sie ändern Code im VBA-Editor: Eine geänderte Deklaration oder ein neues Modul kann eine Neukompilierung erzwingen, die das Projekt zurücksetzt. Im Haltemodus fragt Excel vorher nach; sonst passiert es einfach.
- Die Arbeitsmappe, die den Code enthält, wird geschlossen.
Was sie nicht zurücksetzt: Die Prozedur, die den Wert gesetzt hat, endet normal, ein Fehler wird von
Ihrer eigenen On-Error-Behandlung abgefangen, oder Exit Sub. Diese Asymmetrie ist
der Grund, warum der Bug zufällig wirkt. Er taucht an dem Tag auf, an dem jemand in einen unbehandelten Fehler
läuft, oder auf Ihrem eigenen Rechner direkt nachdem Sie den Code geändert haben.
Die Lösung: über eine selbstheilende Zugriffsfunktion zugreifen
Versuchen Sie nicht, das Zurücksetzen zu verhindern; das können Sie nicht. Machen Sie es stattdessen harmlos.
Halten Sie die Variable Private und stellen Sie eine Funktion bereit, die sie neu aufbaut, sobald sie leer
ist:
Option Explicit
Private mRates As Object ' Scripting.Dictionary, bei Bedarf aufgebaut
Public Function Rates() As Object
If mRates Is Nothing Then
Dim r As Range
Set mRates = CreateObject("Scripting.Dictionary")
For Each r In ThisWorkbook.Worksheets("Rates").Range("A2:A50")
If Len(r.Value) > 0 Then mRates(r.Value) = r.Offset(0, 1).Value
Next r
End If
Set Rates = mRates
End Function
Sub PriceOrder()
Debug.Print Rates()("EUR") ' funktioniert nach jedem Zuruecksetzen - die Funktion laedt neu
End Sub
Jeder Aufrufer fragt Rates(), statt mRates direkt zu lesen. Hat ein Zurücksetzen die Variable geleert,
zahlt der erste Aufrufer danach den Preis für das Neuladen, und niemand bekommt eine falsche Antwort zu sehen.
Dasselbe Muster funktioniert für einen einfachen Wert: Prüfen Sie, ob er 0 oder "" ist, und laden Sie ihn
aus seiner Quelle neu. Das Cache-Objekt selbst behandelt die Dictionary-Anleitung.
Die stille Falle: ein lokales Dim mit demselben Namen
Der zweite klassische Bug kommt ganz ohne Zurücksetzen aus:
' Module1
Public gTotal As Double
Sub AddSales()
Dim gTotal As Double ' eine NEUE lokale Variable, die die globale verdeckt
gTotal = gTotal + 100 ' aendert nur die lokale Kopie
End Sub
Sub ShowTotal()
MsgBox gTotal ' immer noch 0
End Sub
Ein Dim auf Prozedurebene mit demselben Namen wie eine globale Variable verdeckt diese: Innerhalb von
AddSales bezeichnet der Name gTotal die lokale Variable. VBA akzeptiert das ohne Murren, und
Option Explicit kann nicht helfen, weil beide Variablen deklariert sind. Die
Lösung ist die Namensgewohnheit: Globale Variablen beginnen mit g, und Sie deklarieren innerhalb einer
Prozedur nie einen g-Namen per Dim.
Die umgekehrte Kollision löst dagegen einen Fehler aus. Deklarieren Module1 und Module2 beide
Public Total, bekommt ein drittes Modul, das Total schreibt, beim Kompilieren Ambiguous name detected
(„Mehrdeutiger Name“). Qualifizieren Sie den Namen als Module1.Total, oder besser: Geben Sie jeder globalen
Variablen genau einen Besitzer.
Public in einem Tabellen-, ThisWorkbook- oder UserForm-Modul
Public am Anfang eines Tabellenmoduls, von ThisWorkbook oder einer UserForm erzeugt keine globale
Variable. Es erzeugt eine Eigenschaft dieses Objekts, also müssen andere Module das Objekt nennen, um
darauf zuzugreifen:
' Im Codemodul von Sheet1
Public Threshold As Double
' In Module1
Sub Check()
Sheet1.Threshold = 500 ' qualifiziert - das funktioniert
' Threshold = 500 ' Variable not defined (mit Option Explicit)
End Sub
Diese Module sind Objektmodule, deshalb sind dort einige Dinge als Public-Mitglieder nicht erlaubt: Arrays,
Konstanten, Zeichenketten fester Länge und benutzerdefinierte Typen lösen alle einen Kompilierfehler aus. Eine
UserForm bringt zusätzlich eine eigene Lebensdauer mit: UserForm1.SomeValue ist in dem Moment verloren, in
dem das Formular entladen wird, wie die UserForm-Anleitung mit Unload Me vs.
Me.Hide zeigt. Für eine echte projektweite Variable nehmen Sie ein Standardmodul.
Einen Wert über das Schließen der Arbeitsmappe hinaus behalten
Keine Variable überlebt das Schließen der Arbeitsmappe. Muss ein Wert nächste Woche noch da sein — das Datum des letzten Laufs, eine Benutzerauswahl, ein Zähler —, schreiben Sie ihn in die Datei:
Sub RememberLastRun()
ThisWorkbook.Worksheets("Settings").Range("B2").Value = Now
End Sub
Function LastRun() As Date
LastRun = ThisWorkbook.Worksheets("Settings").Range("B2").Value
End Function
Ein Einstellungsblatt, das sehr versteckt ist wie in der Hide-Sheet-Anleitung, hält ihn aus dem Weg. Ein ausgeblendeter benannter Bereich funktioniert ebenso. So oder so ist die Datei das Gedächtnis und die Variable nur eine schnelle Kopie davon — dieselbe Idee wie bei der Zugriffsfunktion oben.
Die Abwägung: globale Variablen für Einstellungen und Caches, Argumente für Daten
Globale Variablen sind nicht böse; sie sind nur geteilt, und geteilter Zustand ist schwer zu durchschauen. Jede Prozedur kann eine globale Variable ändern, und wenn sie den falschen Wert enthält, müssen Sie das ganze Projekt danach durchsuchen, wer ihn geschrieben hat. Meine Regel: Nehmen Sie eine globale Variable für Dinge, die das ganze Projekt liest und fast nichts schreibt, etwa einmal geladene Einstellungen und Caches hinter einer Zugriffsfunktion. Muss eine Prozedur Daten an eine andere weitergeben, übergeben Sie sie als Argument, mit bewusst gewähltem ByVal oder ByRef. Muss sich nur eine einzige Prozedur zwischen zwei Aufrufen etwas merken, gibt ihr eine Static-Variable dieses Gedächtnis, ohne es zu teilen.
Wie ExcelMaster hilft
Bugs mit globalen Variablen sehen selten wie Bugs mit globalen Variablen aus. Sie sehen aus wie eine Schaltfläche, die heute Morgen funktioniert hat und jetzt mit null rechnet, oder wie eine Summe, die sich nie ändert, weil eine lokale Kopie die Aktualisierung abbekommen hat.
ExcelMaster lässt Sie
beschreiben, was die Makros tun sollen — etwa „lade die Kurse einmal und verwende sie in jedem
Preismakro“. Es legt den geteilten Zustand hinter eine Zugriffsfunktion, die ein Zurücksetzen übersteht, lässt
Daten über Argumente fließen und findet in bestehendem Code das lokale Dim, das eine globale Variable
verdeckt.
Häufig gestellte Fragen
Wie deklariere ich in VBA eine globale Variable?
Schreiben Sie Public, gefolgt von Name und Typ, etwa Public gTaxRate As Double, an den Anfang eines
Standardmoduls, vor das erste Sub oder die erste Function. Jede Prozedur des Projekts kann die Variable
dann lesen und ändern. Innerhalb einer Prozedur deklariert, ist sie ein Kompilierfehler.
Was ist der Unterschied zwischen Public und Global in VBA?
Keiner, der zählt. Global ist das ältere Schlüsselwort und funktioniert nur in Standardmodulen; Public
erledigt dieselbe Aufgabe und funktioniert außerdem in Klassen-, Tabellen- und UserForm-Modulen. Nehmen Sie
Public.
Warum verliert meine globale VBA-Variable ihren Wert?
Das VBA-Projekt wurde zurückgesetzt. Eine End-Anweisung, die Zurücksetzen-Schaltfläche im Editor, ein
unbehandelter Fehler, bei dem der Benutzer auf Beenden klickt, manche Codeänderungen und das Schließen der
Arbeitsmappe löschen alle modulweiten und öffentlichen Variablen. Greifen Sie über eine Funktion auf den Wert
zu, die ihn neu lädt, wenn er leer ist.
Wie behalte ich den Wert einer Variablen nach dem Schließen der Arbeitsmappe?
Speichern Sie ihn in der Arbeitsmappe, nicht in einer Variablen: in einer Zelle auf einem ausgeblendeten
Einstellungsblatt, in einem ausgeblendeten definierten Namen oder in einer Dokumenteigenschaft. Lesen Sie ihn
beim Öffnen der Arbeitsmappe zurück, zum Beispiel im Ereignis Workbook_Open.
Kann eine UserForm eine globale Variable verwenden?
Ja. Deklarieren Sie die Variable als Public in einem Standardmodul, dann kann der Code des Formulars sie
lesen und ändern. Eine Public-Variable, die im eigenen Modul der UserForm deklariert ist, gehört zum
Formular und geht verloren, wenn das Formular entladen wird.
Getestet in
Getestet in: Excel 365 (Windows 11), VBA 7.1 — zuletzt geprüft am 01.10.2026.
Verwandte Anleitungen: VBA Static Variable · VBA Optional Parameter · VBA Dim · VBA Const · VBA End · VBA ByRef vs ByVal · VBA Dictionary · VBA Option Explicit
