Getestet in: Excel 365 v2509 · Excel 2021 · Excel 2019 · zuletzt geprüft am 07.06.2026
Kurz gesagt — Ein Sub (Unterprogramm) ist ein benannter Block von Aktionen, der beim Aufruf abläuft und nichts zurückgibt. Das Makro, das du im Dialog Makros ausführst, ist ein Sub. Aufgerufen wird es über seinen Namen — mit oder ohne das Schlüsselwort Call:
Sub Begruessen() ' ein Sub: eine benannte Folge von Aktionen, ohne Rückgabe
MsgBox "Hallo!"
End Sub
Sub BerichtAusfuehren()
Begruessen ' aufrufen — kein Call, keine Klammern
Call Begruessen ' identisches Ergebnis, nur die ältere Call-Schreibweise
End Sub
Macht man den Aufruf falsch, landet man bei „Kompilierfehler: Erwartet: =" oder „Erwartet: Anweisungsende" — dem häufigsten Sub-Fehler überhaupt. Der Rest dieses Leitfadens dreht sich darum, warum.
Das Denkmodell: Ein Sub ist ein Verb, das du beim Namen rufst
Stell dir ein Sub als benannte Aktion vor — als Verb. BerichtFormatieren, RechnungenExportieren, AlteZeilenLoeschen. Du legst die Schritte einmal fest, gibst ihnen einen Namen, und ab dann rufst du diese Schritte von überall auf, indem du den Namen nennst.
Was die meisten Anleitungen verschweigen: Es gibt in VBA keinen eigenen Typ „Makro". Wenn du ein Makro aufzeichnest oder unter Entwicklertools → Makros eines auswählst, führst du in Wahrheit ein schlichtes Sub aus — genauer ein Public Sub ohne Argumente. „Makro" ist nur das freundliche Wort, das Excel den Anwendern zeigt; darunter steckt ein Sub. Sobald das klickt, fühlt sich das ganze VBA-Projekt nicht mehr wie Zauberei an, sondern wie eine Liste benannter Aktionen, die du zusammenstecken kannst.
Die eine Regel: Wie du das Sub aufrufst, entscheidet über die Klammern
Das ist die Regel, die fast jeden Anfängerfehler erklärt:
' Ohne Argumente — alle drei sind in Ordnung:
Begruessen
Call Begruessen
Call Begruessen()
' MIT Argumenten — nur diese beiden sind erlaubt:
LogSchreiben "bericht.txt", 3 ' ✅ blanker Aufruf: KEINE Klammern, Argumente per Komma
Call LogSchreiben("bericht.txt", 3) ' ✅ mit Call: Klammern PFLICHT
LogSchreiben("bericht.txt", 3) ' ❌ Kompilierfehler: Erwartet: =
Die letzte Zeile scheitert, weil VBA ohne Call das LogSchreiben( … ) als „werte LogSchreiben aus und nutze den Rückgabewert" liest — aber ein Sub hat keinen Rückgabewert, und "bericht.txt", 3 ist ohnehin kein einzelner Ausdruck. Klammern gehören zu Call, nicht zum blanken Aufruf. Es ist exakt dieselbe Logik wie bei der MsgBox-Klammer-Regel: Klammern erscheinen nur, wenn ein Wert verwendet wird.
In einem Satz: blanker Aufruf → keine Klammern; Call-Schlüsselwort → Klammern. Wähle einen Stil und bleib dabei. Modernes VBA lässt Call meist ganz weg.
Ein Makro ist ein Public Sub — Private versteckt es
Ob dein Sub im Makro-Dialog auftaucht, hängt an einem einzigen Wort davor:
Public Sub Monatsabschluss() ' erscheint in der Makroliste (Alt+F8) — das ist „ein Makro"
DatenVorbereiten ' ruft einen Helfer, den der Anwender nie sieht
ZusammenfassungBauen
End Sub
Private Sub DatenVorbereiten() ' aus der Makroliste verborgen — nur ein Helfer
' ...
End Sub
Public (Standard für ein einfaches Sub) bedeutet „jeder darf das aufrufen und es dem Anwender zeigen". Private bedeutet „nur Code in diesem Modul ruft das auf". Nutze Private für die kleinen Helfer-Subs, die je einen Schritt erledigen — das hält den Makro-Dialog sauber und signalisiert „kein Einstiegspunkt". Ein Sub mit Argumenten verschwindet ebenfalls automatisch aus der Liste, weil Excel nicht wissen kann, was es übergeben soll.
Daten hineinreichen: Argumente
Wiederverwendbar wird ein Sub in dem Moment, in dem es keine festen Werte mehr hartkodiert, sondern sie entgegennimmt:
Sub ZeileHervorheben(zielZeile As Long, farbIndex As Long)
Rows(zielZeile).Interior.ColorIndex = farbIndex
End Sub
Sub UeberfaelligeMarkieren()
ZeileHervorheben 5, 3 ' Zeile 5 rot
ZeileHervorheben 9, 6 ' Zeile 9 gelb
End Sub
Wie diese Argumente reisen — ob das aufgerufene Sub die übergebene Variable verändern kann — ist eine Falle, die eine eigene Seite verdient. Der Standard in VBA ist ByRef, das Original kann dir also unter den Händen verändert werden. Siehe ByRef vs ByVal für den Stolperstein hinter „Warum hat sich mein Zähler nach dem Aufruf geändert?".
Ereignisprozeduren sind Subs — und müssen es sein
Jedes Arbeitsblatt-/Arbeitsmappen-Ereignis, das du je geschrieben hast, ist ein Sub, und es hat keine Wahl:
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("A:A")) Is Nothing Then
MsgBox "Spalte A wurde bearbeitet."
End If
End Sub
Excel ruft diese auf, wenn etwas passiert (eine Zelle ändert sich, die Mappe öffnet), und liest keinen Rückgabewert zurück — sie können also nur Subs sein, niemals Functions. Diese Asymmetrie macht die Grenze Sub gegen Function am klarsten spürbar: Wenn der Aufrufer keine Antwort will, ist es ein Sub.
Die Meinung: ein Sub, eine Aufgabe
Der schnellste Weg zu unwartbarem VBA ist das 300-Zeilen-Sub Main(), das importiert, bereinigt, rechnet, formatiert und mailt — alles in einem Rutsch. Zerlege es in benannte Subs, die je eine Sache tun:
Public Sub PipelineAusfuehren()
DatenImportieren
DatenBereinigen
BerichtBauen
BerichtMailen
End Sub
Jetzt liest sich PipelineAusfuehren wie ein Inhaltsverzeichnis, jeder Schritt ist für sich prüfbar, und wenn die Mail bricht, reparierst du BerichtMailen, ohne an 250 Zeilen fremdem Code vorbeizuscrollen. Ein Sub-Name ist Dokumentation, die nicht veralten kann — sie läuft. Das ist die eine Gewohnheit, die VBA, das ein Jahr übersteht, von VBA trennt, das niemand mehr anzufassen wagt.
Häufige Sub-Fehler (und die Lösung)
| Symptom | Ursache | Lösung |
|---|---|---|
| „Erwartet: =" beim Aufruf | Klammern beim blanken Aufruf: MeinSub(a, b) |
Klammern weglassen (MeinSub a, b) oder Call davor: Call MeinSub(a, b) |
| Makro fehlt in Alt+F8 | Sub ist Private oder hat Argumente |
Public ohne Argumente machen oder aus einem argumentlosen Wrapper aufrufen |
| „Mehrdeutiger Name erkannt" | Zwei Subs gleichen Namens in einem Modul | Eines umbenennen — Namen müssen je Modul eindeutig sein |
| Sub läuft, aber „nichts passiert" | Ein Sub geschrieben, wo ein Rückgabewert nötig war | Eine Function nehmen, wenn der Aufrufer eine Antwort braucht |
| Argument unerwartet verändert | Standard ByRef ließ das Sub die Variable ändern |
Parameter als ByVal deklarieren — siehe ByRef vs ByVal |
| „Sub oder Function nicht definiert" | Tippfehler, oder das Sub liegt in anderem Modul/anderer Mappe | Schreibweise prüfen; ggf. mit Modul/Mappe qualifizieren |
Wenn das Makro selbst das Schwere ist — beschreib es einfach
Arbeit in saubere Subs zu zerlegen ist gutes Handwerk, bleibt aber Infrastruktur, die du schreiben und pflegen musst. Lautet die Logik „importiere diese drei Dateien, gleiche sie über die Bestell-ID ab, markiere Abweichungen, maile sie an die Buchhaltung", ist die eigentliche Arbeit nicht die Sub-Aufteilung — sondern der Code darin. ExcelMaster Agent lässt dich das in Klartext-Deutsch sagen und schreibt die ganze Pipeline für dich — kein Sub, kein Call, keine Wartung. Kostenlos testen →
Verwandte Anleitungen
- VBA Function in Excel — Rückgabewerte & eigene Arbeitsblattfunktionen
- VBA ByRef vs ByVal — Warum sich deine Variable nach einem Aufruf geändert hat
- VBA MsgBox in Excel — Ja/Nein, Buttons & die Klammer-Regel
- VBA For-Schleife in Excel — 8 Praxisbeispiele
FAQ
Was ist ein Sub in VBA?
Ein Sub (Unterprogramm) ist ein benannter Block von VBA-Code, der Aktionen ausführt und keinen Wert zurückgibt. Du definierst es mit Sub Name() … End Sub und startest es per Namensaufruf. Die Makros, die du über Excels Makro-Dialog ausführst, sind Subs.
Worin unterscheiden sich Sub und Makro?
Technisch gar nicht. „Makro" ist nur der anwendernahe Name für ein Public Sub ohne Argumente — die einzige Art, die in der Liste unter Entwicklertools → Makros (Alt+F8) erscheint. Jedes Makro ist ein Sub; nicht jedes Sub wird als Makro angezeigt.
Wie rufe ich ein Sub in VBA auf?
Auf zwei gleichwertige Arten: den Namen allein schreiben — MeinSub (bzw. MeinSub arg1, arg2 mit Argumenten, ohne Klammern) — oder das Schlüsselwort Call nutzen — Call MeinSub(arg1, arg2) (Klammern Pflicht). Setze beim blanken Aufruf mit mehreren Argumenten keine Klammern; das ist ein Kompilierfehler.
Warum gibt MeinSub(a, b) einen Kompilierfehler?
Ohne Call deutet VBA die Klammern als „nutze den Rückgabewert dieses Subs", doch ein Sub hat keinen, und a, b ist kein einzelner Ausdruck. Entferne die Klammern (MeinSub a, b) oder setze Call davor (Call MeinSub(a, b)).
Was ist der Unterschied zwischen Sub und Function in VBA?
Ein Sub erledigt Arbeit und gibt nichts zurück; eine Function erledigt Arbeit und gibt einen Wert an den Aufrufer zurück. Nimm eine Function, wenn der Aufrufer eine Antwort braucht (und wenn du sie als Arbeitsblattformel nutzen willst); ein Sub für alles andere.
Was bedeutet Private Sub in VBA?
Private Sub macht die Prozedur nur innerhalb desselben Moduls aufrufbar und verbirgt sie aus dem Makro-Dialog. Nutze es für Helfer, die der Anwender nicht direkt starten soll. Ereignisprozeduren wie Worksheet_Change sind genau deshalb Private Sub.
