TL;DR —
CallByName(object, "MemberName", callType, args)liest eine Eigenschaft, schreibt eine Eigenschaft oder ruft eine Methode auf einem Objekt auf und nutzt dazu den Namen des Mitglieds als Zeichenfolge. DercallType—VbGet,VbLet,VbSetoderVbMethod— sagt VBA, welche der vier Sachen Sie meinen, und die falsche zu wählen ist die häufigste Ursache für Fehler 438. Er erreicht nurPublic-Mitglieder. Nutzen Sie ihn, wenn der Eigenschafts- oder Methodenname erst zur Laufzeit feststeht — ein datengesteuertes Formular, eine Einstellungstabelle — und nicht, wenn Sie das Mitglied bereits kennen undobj.Memberdirekt schreiben können.
Sub SetByName()
Dim ctl As Object
Set ctl = Me.Controls("txtName")
' Eine Eigenschaft schreiben, deren Name eine Zeichenfolge ist:
CallByName ctl, "Value", VbLet, "Ada Lovelace"
' Eine Eigenschaft lesen, deren Name eine Zeichenfolge ist:
MsgBox CallByName(ctl, "Value", VbGet)
End Sub
Normalerweise erreichen Sie ein Mitglied eines Objekts, indem Sie es tippen: range.Value, sheet.Name,
form.Hide. Das klappt, weil Sie das Mitglied kennen, während Sie den Code schreiben. CallByName ist
für den Fall, in dem Sie das nicht tun — der Eigenschafts- oder Methodenname kommt als Text an, aus einer
Tabelle, einem Konfigurationsblatt oder einer Schleife. Es ist das zweite von drei Werkzeugen, die sich
eine Idee teilen. Application.Run macht aus einer Zeichenfolge ein
laufendes Makro; CallByName macht aus einer Zeichenfolge einen Mitgliedsaufruf auf einem Objekt;
und Evaluate macht aus einer Zeichenfolge einen berechneten Excel-Ausdruck.
Alle drei tauschen den Compiler gegen Flexibilität zur Laufzeit: Weil der Mitgliedsname Text ist, ist ein
Tippfehler keine rote Wellenlinie mehr — er ist ein Laufzeitfehler. Es gilt also dieselbe Regel: Füttern
Sie CallByName niemals mit einem Mitgliedsnamen, den Sie nicht selbst gebaut oder validiert haben.
Was Sie lernen
- Wo
CallByNamenebenApplication.RunundEvaluatesteht - Die vier Aufruftypen —
VbGet,VbLet,VbSet,VbMethod— und was jeder bedeutet - Warum der falsche Aufruftyp den Fehler 438 auslöst und wie Sie die Meldung lesen
- Argumente an eine Methode oder eine indizierte Eigenschaft übergeben
- Die Nur-Public-Regel, an der manche Aufrufe still scheitern
- Das Muster, für das es die Funktion gibt: eine Tabelle aus Namen und Werten auf ein Objekt anwenden
Das mentale Modell: Reflexion, gerichtet auf die Mitglieder eines Objekts
Application.Run schlägt ein Makro über den Namen nach. CallByName
macht denselben Trick eine Ebene tiefer: Es schlägt ein Mitglied eines bestimmten Objekts über den
Namen nach. Sie übergeben ihm das Objekt, den Mitgliedsnamen als Zeichenfolge und noch etwas, das die
direkte Syntax vor Ihnen verbirgt — welche Art von Zugriff Sie wollen. obj.Value = 5,
x = obj.Value und obj.Refresh sehen im normalen Code unterschiedlich aus, aber für CallByName sind
sie derselbe Aufruf mit einem anderen callType.
x = obj.Caption ' direkt: lesen
CallByName obj, "Caption", VbGet ' dasselbe Lesen, Mitgliedsname als Zeichenfolge
Dieses zusätzliche callType-Argument ist der ganze Grund, warum sich CallByName ungewohnt anfühlt.
Sobald Sie es als „welche der vier Arten des Mitgliedszugriffs" begreifen, verliert die Funktion ihr
Geheimnis.
Die vier Aufruftypen
VBA unterscheidet vier Dinge, die Sie mit einem Mitglied tun können, und Sie müssen CallByName sagen,
welches:
CallByName obj, "Value", VbGet ' eine Eigenschaft lesen -> gibt den Wert zurueck
CallByName obj, "Value", VbLet, "New text" ' eine Wert-Eigenschaft schreiben
CallByName obj, "Range", VbSet, someRange ' eine OBJEKT-Eigenschaft schreiben (braucht Set)
CallByName obj, "Refresh", VbMethod ' eine Methode ausfuehren
Die Trennung zwischen VbLet und VbSet spiegelt VBAs eigenes Let gegenüber Set wider: Nehmen Sie
VbLet für einen einfachen Wert (eine Zahl, eine Zeichenfolge, einen Boolean) und VbSet für einen
Objektverweis (wenn Sie einer Eigenschaft einen Range oder ein anderes Objekt zuweisen). VbGet liest;
VbMethod ruft auf. Fast jeder CallByName-Bug besteht darin, den falschen dieser vier zu wählen.
Die Falle: Der falsche Aufruftyp löst den Fehler 438 aus
Das ist die Zeile, die Sie sich merken sollten. Wenn das Mitglied nicht existiert oder Sie die falsche Art von Zugriff verlangen, kann VBA Sie zur Kompilierzeit nicht warnen — der Name ist eine Zeichenfolge —, also bekommen Sie Laufzeitfehler 438, „Object doesn't support this property or method":
' Wrong: Caption is a property, not a method
CallByName lbl, "Caption", VbMethod ' -> error 438
' Right: read it with VbGet
Dim text As String
text = CallByName(lbl, "Caption", VbGet)
Die Meldung ist etwas irreführend: Oft unterstützt das Objekt das Mitglied durchaus — Sie haben nur auf
die falsche Weise danach gefragt (ein VbMethod auf einer Eigenschaft oder ein VbGet auf einer
Methode, die VbMethod braucht). Wenn Sie von CallByName ein 438 sehen, prüfen Sie den Aufruftyp,
bevor Sie am Mitgliedsnamen zweifeln. Und weil der Name aus Daten stammt, umschließen Sie zur Laufzeit
gespeiste Aufrufe mit einer On Error-Behandlung, damit ein unerwarteter Name
ein behandelter Ausgang ist und kein Absturz.
Argumente an eine Methode oder indizierte Eigenschaft übergeben
Argumente stehen nach dem Aufruftyp, in Reihenfolge:
' A method with arguments:
CallByName ws, "Protect", VbMethod, "password123"
' An indexed property (Cells(2, 3)) via CallByName:
Dim v As Variant
v = CallByName(ws, "Cells", VbGet, 2, 3) ' same as ws.Cells(2, 3)
Argumente sind positionsbezogen, genau wie bei Application.Run. Nimmt
eine Methode mehrere, führen Sie sie in der Reihenfolge der Signatur auf. So erreichen Sie auch indizierte
Eigenschaften wie Cells(row, col), wenn der Eigenschaftsname selbst dynamisch ist.
Die Nur-Public-Regel
CallByName erreicht nur Public-Mitglieder. Eine Private-Eigenschaft oder -Methode in einem
Klassenmodul ist für ihn unsichtbar, und — weil der Name eine Zeichenfolge ist — bekommen Sie dasselbe
Laufzeit-438 wie bei einem Tippfehler, ohne einen Hinweis darauf, dass das eigentliche Problem die
Sichtbarkeit ist. Scheitert ein Aufruf an einem Mitglied, von dem Sie sicher sind, dass es existiert,
vergewissern Sie sich, dass es in der Klasse des Objekts als Public
deklariert ist. Das ist ein häufiger Haken, wenn Sie eigene Klassenobjekte über den Namen ansteuern statt
eingebauter Excel-Objekte.
Das Muster, für das es die Funktion gibt: eine Tabelle aus Namen und Werten
CallByName verdient sich seinen Platz, wenn Sie viele Mitglieder anfassen müssen und ihre Namen in
Daten stehen. Der Lehrbuchfall: eine Tabelle aus Eigenschaftsnamen und Werten auf ein Steuerelement, eine
Form oder ein Diagramm anwenden, ohne pro Eigenschaft eine Zuweisungszeile zu schreiben.
' Settings could come from a worksheet: column A = property, column B = value
Dim props As Variant, vals As Variant, i As Long
props = Array("Caption", "Width", "Visible")
vals = Array("Total", 120, True)
For i = LBound(props) To UBound(props)
CallByName btn, props(i), VbLet, vals(i) ' one loop instead of three assignments
Next i
Drei Eigenschaften sind Spielerei; dreißig sind ein echtes Formular, und genau da ersetzt die Schleife
eine Wand aus btn.Caption = ... : btn.Width = ...-Zeilen. Die Abwägung ist dieselbe wie beim Rest
dieser Familie: Sind die Mitgliedsnamen Konstanten, die Sie einmal tippen, nehmen Sie die direkte Syntax
— btn.Caption = "Total" ist klarer, und der Compiler prüft es. Nur wenn die Namen wirklich Daten sind,
macht CallByName den Verlust der Sicherheit zur Kompilierzeit wett.
Wie ExcelMaster hilft
Die Fehler hier sind still: ein VbMethod, wo ein VbGet hingehört hätte, ein Private-Mitglied, das
Sie nicht erreichen, ein Name aus einem Einstellungsblatt, der nicht mehr zum Objekt passt. Jeder taucht
als derselbe, schwer einzuordnende Fehler 438 auf.
ExcelMaster lässt Sie die Absicht
beschreiben — „setze diese Eigenschaften an diesem Steuerelement aus einer Tabelle und warne mich, wenn
ein Name nicht passt" — und schreibt die CallByName-Schleife mit den richtigen Aufruftypen und einer
bereits eingebauten Fehlerabsicherung. Sie behalten die Arbeitsmappe und den Code und ersparen sich die
Jagd nach dem 438.
Häufig gestellte Fragen
Was macht CallByName in VBA?
Es liest eine Eigenschaft, setzt eine Eigenschaft oder ruft eine Methode auf einem Objekt auf und
verwendet dazu den Namen des Mitglieds als Zeichenfolge statt getippten Code. Die Syntax lautet
CallByName(object, "MemberName", callType, args), wobei callType VbGet, VbLet, VbSet oder
VbMethod ist. Nutzen Sie es, wenn der Mitgliedsname erst zur Laufzeit feststeht; wenn Sie ihn beim
Schreiben des Codes kennen, ist object.Member klarer.
Was ist der Unterschied zwischen VbGet, VbLet, VbSet und VbMethod?
VbGet liest eine Eigenschaft und gibt ihren Wert zurück. VbLet schreibt eine einfache Wert-Eigenschaft
(Zahl, Zeichenfolge, Boolean). VbSet schreibt eine Objekteigenschaft und spiegelt VBAs Set.
VbMethod ruft eine Methode auf. Die falsche zu wählen ist die übliche Ursache für den Fehler 438, weil
das Objekt das Mitglied zwar unterstützt, aber nicht auf die Weise, nach der Sie gefragt haben.
Warum löst CallByName den Fehler 438 aus?
Weil auf das benannte Mitglied nicht auf die Weise zugegriffen werden kann, nach der Sie gefragt haben:
Der Name ist vertippt, das Mitglied ist Private (CallByName erreicht nur Public-Mitglieder), oder der
Aufruftyp ist falsch — zum Beispiel VbMethod auf einer Eigenschaft. Da der Name eine Zeichenfolge ist,
kann VBA das erst erkennen, wenn die Zeile läuft. Prüfen Sie den Aufruftyp und die Sichtbarkeit des
Mitglieds.
Kann CallByName eine private Methode aufrufen?
Nein. CallByName erreicht nur Public-Mitglieder. Eine Private-Eigenschaft oder -Methode in einem
Klassenmodul löst den Fehler 438 aus, denselben Fehler wie bei einem vertippten Namen, was die Diagnose
verwirrend macht. Machen Sie das Mitglied Public, wenn Sie es über den Namen erreichen müssen.
Wann sollte ich CallByName statt object.Member verwenden?
Nur, wenn der Mitgliedsname dynamisch ist — er kommt aus einer Tabelle, einem Konfigurationsblatt oder
einer Schleife über Eigenschaftsnamen. Wenn Sie das Mitglied beim Schreiben des Codes kennen, nehmen Sie
object.Member: Das ist klarer, und der Compiler fängt Tippfehler ab. Um ein eigenständiges Makro über
den Namen auszuführen, verwenden Sie stattdessen Application.Run.
Getestet in
Getestet in: Excel 365 (Windows 11), VBA 7.1 — zuletzt geprüft am 27.09.2026.
Verwandte Anleitungen: VBA Application.Run · VBA Evaluate · VBA Class Module · VBA With · VBA On Error · VBA CreateObject · VBA Dictionary
