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

VBA CallByName in Excel — Eine Eigenschaft lesen oder setzen oder eine Methode über den Namen aufrufen

|

VBA CallByName in Excel — Eine Eigenschaft lesen oder setzen oder eine Methode über den Namen aufrufen

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. Der callType — VbGet, VbLet, VbSet oder VbMethod — 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 nur Public-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 und obj.Member direkt 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 CallByName neben Application.Run und Evaluate steht
  • 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