Kurzfassung — Schreiben Sie innerhalb einer Prozedur
StaticstattDim, und die Variable behält ihren Wert, wenn die Prozedur endet:Static clicks As Longzählt jeden Aufruf, nicht nur den aktuellen. Sie ist ein privates Gedächtnis: Niemand außerhalb der Prozedur sieht sie, aber sie lebt so lange wie eine globale Variable, nämlich bis das VBA-Projekt zurückgesetzt wird. Das ist ihre Stärke und ihre Falle. Eine Static-Variable vergisst nie von selbst, also merkt sie sich auch ein Flag, das hängen geblieben ist, weil ein Fehler die Zeile übersprungen hat, die es zurücksetzen sollte, und einen Cache aus Daten, die sich inzwischen geändert haben. Nehmen Sie Static, wenn eine Prozedur das Gedächtnis allein besitzt; sobald eine andere Prozedur es lesen oder zurücksetzen muss, verlegen Sie es in ein modulweitesPrivate.
Sub CountClicks()
Static clicks As Long ' bleibt zwischen den Aufrufen erhalten
clicks = clicks + 1
Application.StatusBar = "Clicked " & clicks & " times"
End Sub
Dies ist der zweite Teil einer dreiteiligen Reihe darüber, wo ein Wert lebt. Eine globale Variable ist für das ganze Projekt sichtbar und lebt, bis das Projekt zurückgesetzt wird. Eine Static-Variable behält diese Lebensdauer, ist aber nur für eine einzige Prozedur sichtbar. Ein optionaler Parameter hält genau einen Aufruf lang. Die Regel über alle drei hinweg: Nehmen Sie den engsten Gültigkeitsbereich, der die Aufgabe erfüllt.
Was Sie lernen
- Das Denkmodell: Static ist lokaler Gültigkeitsbereich mit Modul-Lebensdauer
- Static vs. Dim vs. ein modulweites Private im direkten Vergleich
- Vier Aufgaben, die Static gut erledigt: Zähler, Umschalter, Wiedereintrittssperren, Caches
- Die zwei Arten, wie sich eine Static-Variable zu viel merkt: hängende Flags und veraltete Caches
- Warum sich alle Zellen, die eine Arbeitsblattfunktion aufrufen, eine Static-Variable teilen
- Static Sub, und wann Sie eine Static-Variable aus ihrer Prozedur herausziehen
Das Denkmodell: lokaler Gültigkeitsbereich, Modul-Lebensdauer
Ein Dim innerhalb einer Prozedur ist ein Notizzettel: Er entsteht, wenn die Prozedur startet, und wird
weggeworfen, wenn sie endet; der nächste Aufruf beginnt also bei null. Ein Static innerhalb einer Prozedur
ist eine Schublade, zu der nur diese Prozedur einen Schlüssel hat. Die Prozedur kann etwas darin ablegen,
enden und es beim nächsten Aufruf dort wiederfinden.
| Deklaration | Wer sie sieht | Wie lange sie ihren Wert behält |
|---|---|---|
Dim n As Long innerhalb einer Prozedur |
diese Prozedur | bis die Prozedur endet |
Static n As Long innerhalb einer Prozedur |
diese Prozedur | bis das Projekt zurückgesetzt wird |
Private n As Long am Anfang eines Moduls |
jede Prozedur des Moduls | bis das Projekt zurückgesetzt wird |
Public n As Long am Anfang eines Standardmoduls |
das ganze Projekt | bis das Projekt zurückgesetzt wird |
Die zweite Zeile ist die einzige, die einen engen Gültigkeitsbereich mit einer langen Lebensdauer verbindet.
„Bis das Projekt zurückgesetzt wird“ bedeutet hier dasselbe wie bei einer globalen Variablen: End, die
Zurücksetzen-Schaltfläche, ein unbehandelter Fehler, den der Benutzer beendet, manche Codeänderungen oder das
Schließen der Arbeitsmappe — alles behandelt in der Anleitung zu globalen Variablen.
Eine Static-Variable deklarieren, und der Wert beim ersten Aufruf
Static ist nur innerhalb einer Prozedur erlaubt, anstelle von Dim:
Function NextInvoiceNo() As Long
Static lastNo As Long ' 0 beim allerersten Aufruf
lastNo = lastNo + 1
NextInvoiceNo = lastNo
End Function
VBA kennt keine Initialisierung in der Deklaration, Static lastNo As Long = 1000 ist also ein Syntaxfehler.
Beim ersten Aufruf enthält eine Static-Variable den leeren Wert ihres Typs — 0, "", Empty oder
Nothing —, und den echten Startwert setzen Sie selbst. Kann 0 ein echter Wert sein, verfolgen Sie den
ersten Aufruf mit einer zweiten Static-Variablen:
Function NextInvoiceNo() As Long
Static lastNo As Long, started As Boolean
If Not started Then
lastNo = ThisWorkbook.Worksheets("Settings").Range("B3").Value
started = True
End If
lastNo = lastNo + 1
NextInvoiceNo = lastNo
End Function
Beachten Sie, was diese Fassung eingesteht: Die Static-Variable ist eine schnelle Kopie, die echte Nummer lebt in der Arbeitsmappe. Ein Zähler, der das Schließen der Datei überstehen muss, muss dorthin zurückgeschrieben werden, denn keine Variable überlebt das Projekt.
Vier Aufgaben, die Static gut erledigt
Ein Umschalter. Eine Schaltfläche, die etwas ein- und ausschaltet, muss ihren letzten Zustand kennen:
Sub ToggleGridlines()
Static isOff As Boolean
isOff = Not isOff
ActiveWindow.DisplayGridlines = Not isOff
End Sub
Ein Zähler oder eine laufende Summe, die zu einer einzigen Routine gehört, wie die Rechnungsnummer oben.
Eine Wiedereintrittssperre für eine Ereignisprozedur, die das Blatt ändert, das sie überwacht. Wer
innerhalb von Worksheet_Change eine Zelle schreibt, löst Worksheet_Change erneut aus; ein Static-Flag
stoppt die Schleife:
Private Sub Worksheet_Change(ByVal Target As Range)
Static busy As Boolean
If busy Then Exit Sub
busy = True
On Error GoTo Done
Target.Offset(0, 1).Value = Now ' wuerde dieses Ereignis erneut ausloesen
Done:
busy = False
End Sub
Ein Cache für eine Nachschlagetabelle, deren Aufbau langsam ist und die nur eine Prozedur braucht:
Function RegionOf(ByVal code As String) As String
Static map As Object
If map Is Nothing Then
Dim r As Range
Set map = CreateObject("Scripting.Dictionary")
For Each r In ThisWorkbook.Worksheets("Regions").Range("A2:A500")
map(r.Value) = r.Offset(0, 1).Value
Next r
End If
If map.Exists(code) Then RegionOf = map(code)
End Function
Der Test If map Is Nothing erfüllt eine doppelte Aufgabe: Er baut den Cache beim ersten Aufruf auf und baut
ihn neu auf, nachdem ein Zurücksetzen des Projekts ihn geleert hat. Das ist das selbstheilende Muster aus der
Anleitung zu globalen Variablen, nur dass der Cache privat in der einen
Funktion bleibt, die ihn verwendet.
Die Regel, die zubeißt: Eine Static-Variable vergisst nie von selbst
Jeder Static-Bug ist derselbe Bug: Der Wert hat die Situation überlebt, für die er galt.
Das hängende Flag. Nehmen Sie die Wiedereintrittssperre oben und löschen Sie die Zeile
On Error GoTo Done. Jetzt beendet jeder Fehler nach busy = True — eine geschützte Zelle oder ein
Typkonflikt — die Prozedur, bevor busy = False läuft. Das Flag bleibt True, und von da an steigt die erste
Zeile jedes Mal aus: Die Ereignisprozedur ist stillschweigend tot, bis das Projekt zurückgesetzt wird. Der
Benutzer sieht ein Blatt, das sich nicht mehr aktualisiert, ohne jede Fehlermeldung. Ein Sperr-Flag muss auf
jedem Ausgangsweg zurückgesetzt werden, und genau deshalb springt die Fehlerbehandlung zu der Zeile, die es
zurücksetzt. Die EnableEvents-Anleitung behandelt die andere übliche Sperre, mit
derselben Regel.
Der veraltete Cache. RegionOf baut seine Tabelle einmal auf. Fügt jemand danach eine Region auf dem
Blatt hinzu, antwortet die Funktion weiter aus der alten Tabelle, den ganzen Tag, weil ihr nichts sagt, dass
sich die Daten geändert haben. Und nichts außerhalb der Funktion kann es ihr sagen, denn die Static-Variable
ist von außen unsichtbar. Das ist die eigentliche Grenze von Static: Sie können sie nicht aus einer anderen
Prozedur zurücksetzen.
Die UDF-Überraschung: Alle Zellen teilen sich eine Static-Variable
Eine Static-Variable gehört zur Prozedur, nicht zu der Stelle, von der aus sie aufgerufen wurde. Bei einer Arbeitsblattfunktion heißt das: Alle Zellen, die sie aufrufen, teilen sich eine einzige Variable:
Function CallCount() As Long
Static n As Long
n = n + 1
CallCount = n
End Function
' =CallCount() in A1, A2 und A3 ergibt nicht 1, 1, 1 -
' sondern drei verschiedene Zahlen, in Berechnungsreihenfolge
Excel bestimmt die Berechnungsreihenfolge und kann jede Zelle jederzeit neu berechnen; eine UDF, deren
Ergebnis von einer Static-Variablen abhängt, liefert also Ergebnisse, die sich von selbst ändern. Die
Function-Anleitung erklärt, warum eine Arbeitsblattfunktion nur von ihren Argumenten
abhängen sollte. Ein Static-Cache in einer UDF, wie die Tabelle in RegionOf, ist in Ordnung, denn er
ändert, wie schnell die Antwort kommt, nicht, wie sie lautet. Ein Static-Zähler oder eine laufende Summe in
einer UDF ist ein Bug.
Static Sub, und Static in einer UserForm
Steht Static vor der Prozedur, wird jede lokale Variable darin statisch:
Static Sub Tally()
Dim total As Double ' ebenfalls statisch, wegen Static Sub
total = total + 1
End Sub
Das gibt es, aber meiden Sie es. Wer den Code liest, sieht Dim und erwartet eine frische Variable, und das
eine Schlüsselwort oben, das etwas anderes sagt, übersieht man leicht. Kennzeichnen Sie stattdessen die
einzelnen Variablen, die ein Gedächtnis brauchen.
Static-Variablen in den Prozeduren einer UserForm leben nur so lange, wie das Formular geladen bleibt. Nach
Unload beginnt das nächste Show mit frischen Werten — dieselbe Lebensdauer wie die der anderen Variablen
des Formulars, siehe UserForm-Anleitung.
Die Abwägung: Static, bis eine zweite Prozedur es braucht
Static ist der engste Weg, einer Prozedur ein Gedächtnis zu geben, und eng ist gut: Nichts anderes kann den
Wert versehentlich ändern, und die Deklaration steht direkt neben dem Code, der sie verwendet. Meine Regel:
Nehmen Sie Static, wenn genau eine Prozedur das Gedächtnis liest und schreibt und nichts anderes es je leeren
muss. Sobald eine zweite Prozedur es sehen muss oder Sie eine „Aktualisieren“-Schaltfläche brauchen, die
einen Cache leert, verlegen Sie die Variable als Private an den Anfang des Moduls und ergänzen eine kleine
Prozedur, die sie zurücksetzt:
Private mMap As Object
Sub ResetRegionCache()
Set mMap = Nothing ' die naechste Abfrage baut ihn neu auf
End Sub
So bleibt der Gültigkeitsbereich so eng, wie es der neue Bedarf erlaubt, und Sie vermeiden den Sprung direkt
zu einer globalen Public-Variablen.
Wie ExcelMaster hilft
Static-Bugs wirken wie Geister: eine Ereignisprozedur, die ohne sichtbaren Grund nicht mehr auslöst, eine Nachschlagefunktion, die die gerade eingefügte Zeile ignoriert, eine UDF, deren Zahlen sich bei jeder Neuberechnung des Blatts verschieben.
ExcelMaster lässt Sie beschreiben, was sich das Makro merken soll — etwa „nummeriere jede neue Rechnung ab der zuletzt verwendeten Nummer“. Es wählt den richtigen Ort für dieses Gedächtnis — eine Static-Variable, eine modulweite Variable mit Zurücksetzen-Prozedur oder eine Zelle in der Arbeitsmappe — und ergänzt die Fehlerbehandlung, die verhindert, dass ein Sperr-Flag hängen bleibt.
Häufig gestellte Fragen
Was bedeutet Static in VBA?
Static deklariert innerhalb einer Prozedur eine Variable, die ihren Wert behält, nachdem die Prozedur
geendet hat. Der nächste Aufruf sieht den Wert, den der letzte hinterlassen hat. Nur diese Prozedur sieht die
Variable, und der Wert geht verloren, wenn das VBA-Projekt zurückgesetzt oder die Arbeitsmappe geschlossen
wird.
Was ist der Unterschied zwischen Static und Dim in VBA?
Eine Dim-Variable innerhalb einer Prozedur beginnt bei jedem Aufruf leer und verschwindet, wenn die Prozedur
endet. Eine Static-Variable beginnt nur beim ersten Aufruf leer und behält ihren Wert zwischen den Aufrufen.
Beide sind nur innerhalb ihrer Prozedur sichtbar.
Wie behalte ich den Wert einer Variablen zwischen zwei Makroläufen?
Deklarieren Sie sie mit Static innerhalb der Prozedur, wenn nur diese Prozedur sie braucht, oder als
Private am Anfang des Moduls, wenn mehrere Prozeduren sie brauchen. Beide behalten den Wert, bis das Projekt
zurückgesetzt wird. Soll er auch nach dem Schließen der Arbeitsmappe erhalten bleiben, speichern Sie ihn in
einer Zelle oder einem definierten Namen.
Kann ich einer Static-Variablen einen Startwert geben?
Nicht in der Deklaration: VBA kennt keine Initialisierung, Static n As Long = 5 ist also ein Syntaxfehler.
Die Variable beginnt als 0, "", Empty oder Nothing. Setzen Sie den Startwert beim ersten Aufruf und
merken Sie sich mit einer zweiten Static-Variablen vom Typ Boolean, ob der erste Aufruf schon stattgefunden
hat.
Wie setze ich eine Static-Variable zurück?
Nur die Prozedur, die sie deklariert, kann sie ändern; geben Sie dieser Prozedur also einen Weg, sie
zurückzusetzen, oder verlegen Sie die Variable als Private auf Modulebene und ergänzen Sie eine kleine
Prozedur zum Zurücksetzen. Ein Zurücksetzen des gesamten VBA-Projekts leert sie ebenfalls, zusammen mit allen
anderen modulweiten und öffentlichen Variablen.
Getestet in
Getestet in: Excel 365 (Windows 11), VBA 7.1 — zuletzt geprüft am 01.10.2026.
Verwandte Anleitungen: VBA Global Variable · VBA Optional Parameter · VBA Dim · VBA Function · VBA Worksheet Change · VBA EnableEvents · VBA Dictionary · VBA UserForm
