🚀The world's best VBA AI has evolved. ExcelMaster is now an autonomous Agent.Read more →
Back to Blog

VBA Optional Parameter in Excel — Standardwerte, IsMissing, benannte Argumente und ParamArray

|

VBA Optional Parameter in Excel — Standardwerte, IsMissing, benannte Argumente und ParamArray

Kurzfassung — Mit Optional darf der Aufrufer ein Argument weglassen: Sub Export(ByVal path As String, Optional ByVal addDate As Boolean = True) lässt sich als Export "C:\Out" oder als Export "C:\Out", False aufrufen. Geben Sie jedem typisierten optionalen Parameter einen Standardwert, und Sie sind fertig. Die eine Regel, die Sie kennen müssen: Ein typisierter optionaler Parameter kann „nicht übergeben“ nicht von „den Standardwert übergeben“ unterscheiden, und IsMissing funktioniert nur bei einem Variant ohne Standardwert. Nehmen Sie einen Standardwert, wenn das Weglassen des Arguments dasselbe bedeutet wie die Übergabe dieses Werts; nehmen Sie einen Variant mit IsMissing nur dann, wenn das Weglassen etwas bedeutet, das kein Wert ausdrücken kann. Und wenn eine Prozedur eine neue Eingabe braucht, fügen Sie sie als Optional am Ende hinzu, mit dem bisherigen Verhalten als Standardwert — so funktioniert jeder bestehende Aufrufer weiter.

Sub ExportReport(ByVal folder As String, Optional ByVal addDate As Boolean = True)
    Dim fileName As String
    fileName = "Report"
    If addDate Then fileName = fileName & " " & Format(Date, "yyyy-mm-dd")
    Debug.Print folder & "\" & fileName & ".pdf"
End Sub

' ExportReport "C:\Out"             -> C:\Out\Report 2026-10-01.pdf
' ExportReport "C:\Out", False      -> C:\Out\Report.pdf

Damit schließt eine dreiteilige Reihe darüber, wo ein Wert lebt. Eine globale Variable teilt sich das ganze Projekt, bis es zurückgesetzt wird; eine Static-Variable ist das private Gedächtnis einer einzigen Prozedur. Ein optionaler Parameter ist das Engste von allem: Der Aufrufer reicht den Wert für einen einzigen Aufruf herein oder lässt den Standardwert einspringen. Er ist auch am leichtesten zu durchschauen, denn wer den Aufruf liest, sieht, woher der Wert kommt.

Was Sie lernen

  • Das Denkmodell: Ein optionaler Parameter ist ein Formularfeld mit vorgedrucktem Standardwert
  • Die Deklarationsregeln, und warum der Standardwert eine Konstante sein muss
  • Die eine Regel: Ein typisierter optionaler Parameter kann „weggelassen“ nicht von „Standardwert“ unterscheiden
  • IsMissing mit einem Variant, und wann das die richtige Wahl ist
  • Argumente überspringen, und warum benannte Argumente Parameternamen festschreiben
  • ParamArray für beliebig viele Werte, und die Falle beim Weiterreichen
  • Optional als sicherer Weg, eine Prozedur zu ändern, die alle schon aufrufen

Das Denkmodell: ein Formularfeld mit vorgedrucktem Standardwert

Ein Pflichtparameter ist ein leeres Feld, das der Aufrufer ausfüllen muss. Ein optionaler Parameter ist ein Feld, in dem schon ein Wert vorgedruckt ist: Der Aufrufer kann ihn überschreiben oder stehen lassen. Die Prozedur bekommt in jedem Fall einen Wert. Dieses Bild erklärt jede folgende Regel: Der vorgedruckte Wert muss feststehen, bevor jemand das Formular ausfüllt, er muss nach den Pflichtfeldern kommen, und sobald er gedruckt ist, kann die Prozedur nicht mehr unterscheiden, ob der Aufrufer ihn stehen gelassen oder denselben Wert darübergeschrieben hat.

Optionale Parameter deklarieren: die Regeln

Function Discount(ByVal amount As Double, _
                  Optional ByVal rate As Double = 0.1, _
                  Optional ByVal roundTo As Long = 2) As Double
    Discount = Round(amount * (1 - rate), roundTo)
End Function
  • Optional steht vor ByVal oder ByRef, der Standardwert nach dem Typ: = 0.1.
  • Jeder optionale Parameter steht nach allen Pflichtparametern. Sobald ein Parameter optional ist, müssen auch alle folgenden optional sein.
  • Der Standardwert muss ein konstanter Ausdruck sein: eine Zahl, eine Zeichenkette, True, eine von Ihnen deklarierte Konstante. Optional asOf As Date = Date ist ein Kompilierfehler („Constant expression required“), denn Date ist eine Funktion, die erst später läuft. Lassen Sie den Standardwert weg und setzen Sie ihn stattdessen am Anfang der Prozedur:
Sub Snapshot(Optional ByVal asOf As Date)
    If asOf = 0 Then asOf = Date     ' 0 heisst nicht angegeben - dann das heutige Datum
    Debug.Print Format(asOf, "yyyy-mm-dd")
End Sub

Ein Objektparameter ohne Standardwert kommt als Nothing an, was „nimm das aktive Blatt, sofern nichts anderes angegeben ist“ leicht macht: Optional ws As Worksheet, dann If ws Is Nothing Then Set ws = ActiveSheet.

In einer Arbeitsblattfunktion verhalten sich optionale Parameter genauso: =Discount(A2) verwendet beide Standardwerte, =Discount(A2, 0.2) überschreibt einen davon. Den Rest des UDF-Entwurfs behandelt die Function-Anleitung.

Die eine Regel: Ein typisierter optionaler Parameter kann „weggelassen“ nicht von „Standardwert“ unterscheiden

Sehen Sie sich Snapshot noch einmal an. Übergibt der Aufrufer nichts, ist asOf gleich 0. Übergibt der Aufrufer absichtlich 0, ist asOf ebenfalls 0. Die Prozedur kann beides nicht auseinanderhalten, und das gilt für jeden typisierten optionalen Parameter: Ein weggelassenes Long ist 0, ein weggelassener String ist "", ein weggelassenes Boolean ist False — oder eben der Standardwert, den Sie deklariert haben.

Meistens ist das genau, was Sie wollen. „Weglassen“ und „den Standardwert übergeben“ sollen dasselbe bedeuten, und ein Standardwert macht das Verhalten der Prozedur schon in der ersten Zeile offensichtlich. Das Problem entsteht, wenn das Weglassen durch den Aufrufer etwas bedeuten muss, das kein Wert des Typs ausdrücken kann. Ein typischer Fall ist ein Filter, der standardmäßig „kein Filter“ heißt, während 0 und "" echte Werte sind, nach denen jemand filtern möchte.

IsMissing: wenn das Weglassen etwas bedeuten muss

Für diesen Fall deklarieren Sie den Parameter als Variant ohne Standardwert und fragen IsMissing:

Function CountWhere(rng As Range, Optional ByVal match As Variant) As Long
    Dim c As Range, n As Long
    For Each c In rng
        If IsMissing(match) Then
            If Not IsEmpty(c.Value) Then n = n + 1   ' kein Filter: gefuellte Zellen zaehlen
        ElseIf c.Value = match Then
            n = n + 1                                ' Filter, auch auf 0 oder ""
        End If
    Next c
    CountWhere = n
End Function

IsMissing hat zwei Bedingungen, und wer eine davon verletzt, bekommt stillschweigend für immer False:

  • Der Parameter muss ein Variant sein. Bei einem Long oder einem String ist IsMissing immer False.
  • Der Parameter darf keinen Standardwert haben. Optional match As Variant = "" fehlt nie, weil der Standardwert ihn ausfüllt.

Meine Einschätzung: Greifen Sie nur dann zu IsMissing, wenn das Fehlen ein echter dritter Zustand ist. Verwenden Sie es nur, um am Anfang der Prozedur einen Standardwert einzusetzen, deklarieren Sie stattdessen den typisierten Standardwert; dann dokumentiert die Signatur das Verhalten, und der Compiler prüft den Typ.

Argumente überspringen, und benannte Argumente

Um ein optionales Argument in der Mitte zu überspringen, lassen Sie seinen Platz leer oder nennen das Argument, das Sie übergeben, beim Namen:

Debug.Print Discount(200, , 0)            ' Standard-Rabatt, auf 0 Stellen runden
Debug.Print Discount(200, roundTo:=0)     ' dasselbe, und lesbar
Debug.Print Discount(amount:=200, rate:=0.25)

Benannte Argumente verwenden := und den Namen des Parameters, in beliebiger Reihenfolge. Sobald eine Prozedur mehr als einen optionalen Parameter hat, sind sie die lesbare Wahl, denn , , 0 sagt nichts darüber, welcher Wert welcher ist. Eine Folge übersehen viele: Sobald irgendein Aufrufer roundTo:= verwendet, ist der Parametername Teil der Schnittstelle. roundTo in decimals umzubenennen, kompiliert in der Prozedur problemlos und bricht jeden Aufrufer, der den Namen verwendet hat — mit „Named argument not found“ (benanntes Argument nicht gefunden). Wählen Sie die Namen optionaler Parameter so sorgfältig wie Prozedurnamen.

ParamArray: beliebig viele Werte

Soll der Aufrufer so viele Werte übergeben können, wie er möchte, nehmen Sie ParamArray. Es muss der letzte Parameter sein, es muss ein Array vom Typ Variant sein, und es lässt sich in derselben Prozedur nicht mit Optional kombinieren:

Function SumAll(ParamArray values() As Variant) As Double
    Dim i As Long, total As Double
    For i = LBound(values) To UBound(values)
        total = total + values(i)
    Next i
    SumAll = total
End Function

' SumAll(1, 2, 3)  -> 6
' SumAll()         -> 0   (UBound ist -1, also laeuft die Schleife nie)

Die Falle ist das Weiterreichen. Will SumAll seine Werte an eine zweite ParamArray-Prozedur übergeben, verteilt Other values sie nicht: Other bekommt ein einziges Argument, nämlich das ganze Array. Schreiben Sie die Hilfsprozedur so, dass sie stattdessen einen gewöhnlichen Variant mit einem Array entgegennimmt, und durchlaufen Sie es dort. Die UBound-Anleitung behandelt die Grenzen, die leere Arrays sicher machen.

Die Abwägung: Mit Optional wächst eine Prozedur, ohne zu brechen

Das Nützlichste an Optional ist nicht die Bequemlichkeit. Es ist die Kompatibilität. Angenommen, ExportReport folder wird von zwölf Schaltflächen und drei anderen Makros aufgerufen, und jetzt soll ein Bericht das Datum weglassen. Die Signatur um einen neuen Pflichtparameter zu erweitern, bricht fünfzehn Aufrufer. Optional ByVal addDate As Boolean = True hinzuzufügen, bricht keinen einzigen, denn der Standardwert ist genau das, was sie bisher bekommen haben, und der eine neue Aufrufer übergibt False.

Meine Regeln:

  • Neue Eingaben kommen ans Ende, als Optional, mit dem bisherigen Verhalten als Standardwert.
  • Ziehen Sie einen typisierten Standardwert IsMissing vor, es sei denn, „nicht angegeben“ ist ein echter dritter Zustand.
  • Ab zwei oder drei optionalen Parametern sollten Aufrufer benannte Argumente verwenden, und es lohnt sich die Frage, ob die Prozedur zwei Aufgaben erledigt, die zwei Prozeduren sein sollten — ganz im Sinne der Sub-Anleitung.
  • Verwenden Sie nie eine globale Variable, um eine Einstellung an eine Prozedur zu übergeben, die sie als Optional entgegennehmen könnte. Das Argument ist im Aufruf sichtbar; die globale Variable nirgends.

Wie ExcelMaster hilft

Bugs mit optionalen Parametern verstecken sich in den Aufrufen: ein Filter, der nie greift, weil IsMissing auf einen String angewendet wurde, eine Umbenennung, die jeden Aufrufer mit benannten Argumenten bricht, eine Prozedur, die einen Pflichtparameter dazubekommen hat und damit die Schaltflächen bricht, die sie aufrufen.

ExcelMaster lässt Sie die Änderung beschreiben — etwa „lass diesen Export beim Monatsbericht das Datum weglassen“. Es fügt die Eingabe als Optional mit dem bisherigen Verhalten als Standardwert hinzu, sodass bestehende Aufrufer weiter funktionieren, und prüft jede Aufrufstelle im Projekt.

Häufig gestellte Fragen

Wie mache ich einen Parameter in VBA optional?

Schreiben Sie in der Deklaration Optional davor und geben Sie ihm einen Standardwert: Optional ByVal rate As Double = 0.1. Er muss nach allen Pflichtparametern stehen, und jeder Parameter danach muss ebenfalls optional sein. Aufrufer können ihn dann weglassen, und die Prozedur bekommt den Standardwert.

Warum gibt IsMissing immer False zurück?

IsMissing funktioniert nur, wenn der optionale Parameter ein Variant ohne Standardwert ist. Bei einem typisierten Parameter wie Long oder String oder bei einem Variant mit Standardwert setzt VBA einen Wert ein, wenn das Argument weggelassen wird — er fehlt also nie.

Kann ein optionaler Parameter standardmäßig das heutige Datum haben?

Nicht direkt, denn ein Standardwert muss eine Konstante sein, und Date ist eine Funktion. Deklarieren Sie Optional asOf As Date ohne Standardwert und schreiben Sie dann If asOf = 0 Then asOf = Date an den Anfang der Prozedur.

Wie überspringe ich ein optionales Argument in der Mitte?

Lassen Sie seine Position mit einem Komma leer, wie in Discount(200, , 0), oder verwenden Sie benannte Argumente, wie in Discount(200, roundTo:=0). Benannte Argumente sind klarer und lassen sich in beliebiger Reihenfolge angeben.

Was ist ParamArray in VBA?

Mit ParamArray nimmt eine Prozedur beliebig viele Argumente als ein einziges Array von Variants entgegen, etwa Function SumAll(ParamArray values() As Variant). Es muss der letzte Parameter sein und lässt sich nicht zusammen mit optionalen Parametern verwenden. Durchlaufen Sie es mit LBound und UBound; werden keine Argumente übergeben, ist UBound gleich -1.

Getestet in

Getestet in: Excel 365 (Windows 11), VBA 7.1 — zuletzt geprüft am 01.10.2026.

Verwandte Anleitungen: VBA Global Variable · VBA Static Variable · VBA Function · VBA Sub · VBA ByRef vs ByVal · VBA UBound · VBA Format · VBA Save as PDF