TL;DR —
Application.Run "MacroName", arg1, arg2führt ein Makro aus, das Sie über eine Zeichenfolge benennen, sodass der Code erst zur Laufzeit entscheidet, welches Makro läuft, und nicht beim Schreiben. Nutzen Sie es als Anweisung (ohne Klammern) oder fangen Sie den Rückgabewert einerFunctionmitx = Application.Run("MyFunc", 5)ab. Der Haken: Der Name ist Text, ein Tippfehler ist also ein Laufzeitfehler 1004, keine rote Wellenlinie zur Kompilierzeit. Greifen Sie dazu, wenn der Makroname erst zur Laufzeit feststeht — eine Dispatch-Tabelle, ein Name in einer Zelle, ein Plug-in. Wenn Sie das Makro bereits kennen, rufen Sie es einfach direkt auf.
Sub RunByName()
' Makronamen zur Laufzeit bestimmen, dann ausfuehren
Dim macroName As String
macroName = Range("Config!B2").Value ' z. B. "BuildMonthlyReport"
Application.Run macroName, Date, "Finance" ' Argumente positionsbezogen uebergeben
End Sub
Meistens rufen Sie ein Makro auf die naheliegende Weise auf: Sie tippen seinen Namen, BuildReport, und
es läuft. Das klappt nur, weil Sie den Namen kennen, während Sie den Code schreiben. Application.Run
ist für den anderen Fall — wenn der Name in einer Zelle, einem Einstellungsblatt oder einer Variablen
steckt und Sie ihn erst kennen, wenn das Makro bereits läuft. Dies ist das erste von drei Werkzeugen,
die sich eine Idee teilen, und die sollten Sie sich vorab klarmachen:
Application.Run, CallByName und Evaluate
machen allesamt aus einer Zeichenfolge eine zur Laufzeit ausgeführte Aktion. Run führt ein über eine
Zeichenfolge benanntes Makro aus, CallByName ruft ein über eine Zeichenfolge benanntes Objektmitglied
auf, und Evaluate berechnet einen als Text vorliegenden Excel-Ausdruck. Die Stärke ist die Indirektion;
der Preis ist, dass Sie den Compiler aufgeben, sodass aus einem Tippfehler ein Laufzeitfehler wird statt
einer Wellenlinie. Die Regel, die für alle drei gilt: Übergeben Sie ihnen niemals eine Zeichenfolge, die
Sie nicht selbst gebaut oder geprüft haben.
Was Sie lernen
- Das mentale Modell, das
Application.Run,CallByNameundEvaluateverbindet - Die Anweisungsform gegenüber dem Abfangen des Rückgabewerts einer
Function - Das positionsbezogene Übergeben von Argumenten — bis zu 30, und warum Objekte als Werte ankommen
- Ein Makro aufrufen, das in einer anderen geöffneten Arbeitsmappe liegt
- Warum ein vertippter Name zur Laufzeit scheitert, nicht zur Kompilierzeit, und wie Sie das absichern
- Die eine Situation, die
Application.Runwirklich rechtfertigt: eine Dispatch-Tabelle
Das mentale Modell: eine Telefonzentrale, die das Makro über den Namen nachschlägt
Stellen Sie sich eine Telefonvermittlung vor. Ein direkter Aufruf, BuildReport, ist eine Standleitung,
die fest mit einem einzigen Büro verdrahtet ist — schnell, aber für immer festgelegt. Application.Run
ist die Vermittlung: Sie sagen einen Namen laut, und man verbindet Sie mit dem, worauf dieser Name
gerade jetzt zeigt. Der Name kann von überall herkommen — aus einer Zelle, einem Konfigurationsblatt,
einer Schleife über eine Liste —, weil die Verbindung zur Laufzeit hergestellt und nicht beim Schreiben
des Codes fest verlötet wird.
BuildReport ' direkter Aufruf: Name beim Schreiben festgelegt
Application.Run "BuildReport" ' indirekter Aufruf: Name zur Laufzeit aufgeloest
Diese beiden Zeilen tun heute dasselbe. Der Unterschied zeigt sich erst, wenn der Name keine Konstante
ist. In dem Moment, in dem Sie Application.Run someVariable schreiben, haben Sie sich Indirektion
erkauft — und die Verantwortung dafür übernommen, dass someVariable einen echten Makronamen enthält.
Um diesen Handel geht es auf der ganzen Seite.
Die Syntax: Anweisungsform oder das Abfangen eines Rückgabewerts
Wie MsgBox hat Application.Run zwei Gestalten, und die Klammern entscheiden,
welche Sie bekommen. Als Anweisung lassen Sie die Klammern weg:
Application.Run "FormatSheet", ActiveSheet.Name ' einen Sub ausfuehren, Ergebnis ignorieren
Um abzufangen, was eine Function zurückgibt, setzen Sie den gesamten Aufruf in Klammern und weisen
ihn zu:
Dim total As Double
total = Application.Run("SumColumn", "B") ' den Rueckgabewert der Function abfangen
Die Regel ist dieselbe, über die alle bei MsgBox stolpern: Klammern bedeuten das ist ein Ausdruck,
dessen Wert ich haben will. Nutzen Sie die Anweisungsform für einen Sub; nutzen
Sie die Funktionsform für eine Function, deren Ergebnis Sie brauchen.
Argumente übergeben — positionsbezogen, bis zu 30, als Werte
Sie übergeben Argumente nach dem Namen, getrennt durch Kommas. Zwei harte Grenzen sollten Sie sich merken:
Application.Run "PostEntry", 2026, "March", 4820.5 ' Argumente gehen nach POSITION, nicht nach Name
Erstens sind Argumente rein positionsbezogen — Sie können hier keine named:=-Argumente verwenden,
die Reihenfolge in Ihrem Aufruf muss also exakt der Reihenfolge in der Signatur des Zielmakros
entsprechen. Zweitens gibt es eine Obergrenze von 30 Argumenten, was in der Praxis heißt: Wenn Sie
sich ihr nähern, übergeben Sie ein Array oder ein Dictionary statt einer
langen Argumentliste.
Eine stille Überraschung: Objekte werden als Werte übergeben, nicht als lebende Verweise. Wenn Sie
einen Range übergeben, erhält das Ziel dessen .Value, nicht den Bereich selbst. Wenn ein Makro auf
einem echten Objekt arbeiten muss, schreiben Sie den Namen in die Zeichenfolge und lassen das Ziel das
Objekt selbst auflösen, statt zu versuchen, das Objekt über Application.Run zu reichen.
Ein Makro in einer anderen geöffneten Arbeitsmappe aufrufen
Hier verdient sich Application.Run den regelmäßigen Einsatz: der Aufruf eines Makros, das in einer
anderen Arbeitsmappe liegt — einem gemeinsam genutzten Add-in, einer Werkzeug-Arbeitsmappe, einer
Berichtsvorlage. Qualifizieren Sie den Namen mit der Arbeitsmappe:
Application.Run "'Monthly Tools.xlsm'!Module1.RefreshData"
Drei Details entscheiden, ob das funktioniert. Die Arbeitsmappe muss geöffnet sein —
Application.Run öffnet sie nicht für Sie. Setzen Sie den Namen der Arbeitsmappe in einfache
Anführungszeichen, wenn er Leerzeichen enthält ('Monthly Tools.xlsm'). Und das Zielmakro muss
Public sein (die Voreinstellung für einen Sub in einem Standardmodul); ein Private-Makro ist
von außerhalb seines eigenen Moduls unsichtbar. Machen Sie eines der drei falsch, landen Sie bei genau
dem Fehler, um den es im nächsten Abschnitt geht.
Die Falle: Der Name ist eine Zeichenfolge, ein Tippfehler ist also ein Laufzeitfehler
Hier ist der Preis der Indirektion — und die wichtigste Zeile auf dieser Seite. Wenn Sie ein Makro
direkt aufrufen und sich vertippen, stoppt Sie der VBA-Compiler, bevor irgendetwas läuft. Wenn Sie die
Zeichenfolge in Application.Run vertippen, hat der Compiler nichts zu prüfen — es ist bloß Text —,
sodass der Fehler erst auftaucht, wenn diese Zeile ausgeführt wird, als Laufzeitfehler 1004, „Cannot
run the macro":
Sub SafeRun(macroName As String)
On Error GoTo NotFound
Application.Run macroName
Exit Sub
NotFound:
MsgBox "Macro not found or failed: " & macroName, vbExclamation
End Sub
Weil der Compiler Ihnen nicht helfen kann, müssen Sie es tun. Immer wenn der Makroname von außerhalb
Ihres Codes stammt — aus einer Zelle, einer Datei, einer Benutzereingabe —, umschließen Sie den Aufruf
mit einer On Error-Behandlung und behandeln „Makro nicht gefunden" als
normalen Ausgang, nicht als Absturz. Ein zeichenfolgengesteuerter Aufruf ohne Fehlerabsicherung ist ein
Bug, der nur auf den ersten Tippfehler in einem Konfigurationsblatt wartet.
Wann sich Application.Run wirklich lohnt: eine Dispatch-Tabelle
Wenn Sie das Makro schon beim Schreiben kennen, rufen Sie es direkt auf — Application.Run "BuildReport"
liest sich langsamer und bricht leichter als BuildReport. Die Methode zahlt sich erst aus, wenn der
Name wirklich dynamisch ist. Das sauberste Beispiel ist eine Dispatch-Tabelle: Bilden Sie eine Menge
von Namen auf eine Menge von Aktionen ab und führen Sie dann diejenige aus, die die Situation verlangt.
Sub RunAction(actionName As String)
' Ein ganzes Select Case schrumpft auf eine Zeile:
' Tag der Schaltflaeche, eine Zelle oder eine Konfigurationszeile entscheidet, welches Makro laeuft.
Application.Run "Actions." & actionName ' "Actions.Export", "Actions.Refresh", ...
End Sub
Diese eine Zeile ersetzt ein wachsendes Select Case, das Sie sonst bei
jeder neuen Aktion anpassen müssten. Es ist das Muster hinter Plug-in-Architekturen, hinter
Menüband-Schaltflächen, die ihren Handler-Namen in einem Tag tragen, und hinter Makros, deren Verhalten
von einem Einstellungsblatt gesteuert wird. Der Test, ob Sie Application.Run verwenden sollten, ist
einfach: Ist der Name eine Konstante? Wenn ja, rufen Sie direkt auf. Wenn nein, ist dies das Werkzeug.
Application.Run, direkter Aufruf oder CallByName
Drei Wege, Code aufzurufen, drei Aufgaben. Ein direkter Aufruf ist für ein Makro, dessen Namen Sie
beim Schreiben kennen — bevorzugen Sie ihn immer, wenn Sie können. Application.Run ist für ein
Makro, dessen Name eine erst zur Laufzeit festgelegte Zeichenfolge ist, auch für eines in einer anderen
Arbeitsmappe. CallByName ist dieselbe Idee, gerichtet auf eine
Eigenschaft oder Methode eines Objekts statt auf ein eigenständiges Makro. Wenn Sie merken, dass Sie
eine Zeichenfolge bauen, um an ein Mitglied eines bestimmten Objekts zu gelangen (ein Steuerelement, eine
Form, eine Klasse), ist das die Aufgabe von CallByName, nicht von Run.
Wie ExcelMaster hilft
Der Fehler auf dieser Seite ist von Natur aus still: ein Name, der heute richtig ist und in dem Moment
falsch wird, in dem jemand ein Konfigurationsblatt bearbeitet, und der dann tief in einem Lauf als Fehler
1004 auftaucht. Jeden zeichenfolgengesteuerten Aufruf absichern, Arbeitsmappennamen in Anführungszeichen
setzen, prüfen, ob ein Ziel Public ist — leicht ist eines davon übersehen.
ExcelMaster lässt Sie das
Ziel in klaren Worten beschreiben — „führe das in dieser Zelle benannte Makro aus und sag mir deutlich,
wenn es nicht existiert" — und schreibt den Application.Run-Code, bei dem die Fehlerabsicherung, der
Arbeitsmappen-Qualifizierer und die Rückgabebehandlung bereits an Ort und Stelle sind. Sie behalten die
Arbeitsmappe und den Code und ersparen sich den 1004.
Häufig gestellte Fragen
Wie führe ich in VBA ein Makro über seinen Namen als Zeichenfolge aus?
Verwenden Sie Application.Run "MacroName". Als Anweisung lassen Sie die Klammern weg; um das Ergebnis
einer Function abzufangen, schreiben Sie x = Application.Run("MyFunc", arg). Weil der Name eine
Zeichenfolge ist, kann der Compiler ihn nicht prüfen, umschließen Sie den Aufruf also mit einer
On Error-Behandlung — ein Tippfehler zeigt sich als Laufzeitfehler 1004 statt
als Kompilierfehler.
Wie übergebe ich mit Application.Run Argumente an ein Makro?
Führen Sie sie nach dem Namen auf, getrennt durch Kommas: Application.Run "PostEntry", 2026, "March".
Argumente sind rein positionsbezogen — Sie können keine named:=-Syntax verwenden — und es gibt eine
Grenze von 30. Objekte werden als Werte übergeben (ein Range kommt als sein .Value an), für alles
Größere übergeben Sie also ein Array oder ein Dictionary.
Wie führe ich ein Makro in einer anderen Arbeitsmappe aus?
Qualifizieren Sie den Namen mit der Arbeitsmappe: Application.Run "'Tools.xlsm'!Module1.RefreshData".
Die andere Arbeitsmappe muss bereits geöffnet sein, verwenden Sie einfache Anführungszeichen um ihren
Namen, wenn er Leerzeichen enthält, und das Zielmakro muss Public sein. Application.Run öffnet die
Arbeitsmappe nicht für Sie.
Warum gibt Application.Run den Fehler 1004 aus, das Makro lässt sich nicht ausführen?
Fast immer lässt sich die Namenszeichenfolge nicht zu einem ausführbaren Makro auflösen: Sie ist
vertippt, die Arbeitsmappe, die es enthält, ist nicht geöffnet, oder das Makro ist Private. Weil der
Name Text ist, lässt sich das erst zur Laufzeit erkennen. Prüfen Sie die Schreibweise, stellen Sie
sicher, dass die Arbeitsmappe geöffnet ist, und vergewissern Sie sich, dass das Ziel Public ist.
Wann sollte ich Application.Run verwenden, statt das Makro einfach aufzurufen?
Nur, wenn der Name erst zur Laufzeit feststeht — er kommt aus einer Zelle, einem Konfigurationsblatt,
einer Variablen oder einer Schleife, oder das Makro liegt in einer anderen Arbeitsmappe. Wenn Sie den
Makronamen beim Schreiben des Codes kennen, rufen Sie ihn direkt auf: BuildReport ist klarer, und der
Compiler fängt Tippfehler ab. Um ein Mitglied eines Objekts über den Namen aufzurufen, verwenden Sie
stattdessen CallByName.
Getestet in
Getestet in: Excel 365 (Windows 11), VBA 7.1 — zuletzt geprüft am 27.09.2026.
Verwandte Anleitungen: VBA CallByName · VBA Evaluate · VBA Sub · VBA Function · VBA On Error · VBA Select Case · VBA Dictionary
