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

VBA Class Module in Excel — ein eigenes Objekt bauen (Bauplan vs. Instanz und die As-New-Falle)

|

VBA Class Module in Excel — ein eigenes Objekt bauen (Bauplan vs. Instanz und die As-New-Falle)

TL;DR — Ein Class module ist ein Bauplan für Ihren eigenen Objekttyp. Sie schreiben ihn einmal und erzeugen dann mit New beliebig viele unabhängige Instanzen. Zwei Dinge bringen jeden zu Fall: Der Name des Class module ist der Typname (es gibt kein Class-Schlüsselwort im Inneren), und Objekte sind Referenztypen, sodass Set b = a aus a und b zwei Namen für dieselbe Instanz macht. Bevorzugen Sie das explizite Set x = New clsThing gegenüber Dim x As New clsThing, das eine Falle der verzögerten Instanziierung verbirgt.

' --- In einem Class module namens  clsEmployee  (im Eigenschaftenfenster umbenennen) ---
Private mName As String
Private mSalary As Currency

Public Property Get Name() As String:   Name = mName:      End Property
Public Property Let Name(v As String):  mName = v:         End Property
Public Property Get Salary() As Currency: Salary = mSalary: End Property
Public Property Let Salary(v As Currency): mSalary = v:     End Property

Public Function AnnualCost() As Currency   ' Verhalten lebt bei den Daten
    AnnualCost = mSalary * 1.3             ' Gehalt + 30 % Gemeinkosten
End Function

' --- In einem normalen Modul ---
Sub Demo()
    Dim e As clsEmployee
    Set e = New clsEmployee        ' eine Instanz erzeugen
    e.Name = "Sarah"
    e.Salary = 65000
    MsgBox e.Name & " costs " & e.AnnualCost   ' 84500
End Sub

Ein Type bündelt Felder. Ein Class module geht einen Schritt weiter: Es bündelt Felder und den Code, der auf sie wirkt, und gibt Ihnen ein echtes Objekt, das Sie erzeugen, dessen Referenzen Sie kopieren und das Sie in einer Collection speichern können. Näher als das kommt VBA der objektorientierten Programmierung nicht — und gut eingesetzt verwandelt es einen Wildwuchs loser Variablen und Hilfs-Subs in eine Handvoll in sich geschlossener Objekte.

Was Sie lernen

  • Das mentale Modell — ein Bauplan, aus dem Sie Instanzen stanzen
  • Warum es kein Class-Schlüsselwort gibt (der Modulname ist der Typ)
  • Instanzen erzeugen — Set ... = New und die As New-Falle
  • Die Regel, die überrascht — Objekte teilen, sie kopieren nicht
  • Auf- und Abbau — Class_Initialize und der fehlende Konstruktor
  • Wann eine Klasse einen Type oder eine Collection schlägt

Das mentale Modell: ein Bauplan, nicht das Gebäude

Ein Class module ist ein Bauplan; jedes New baut daraus eine Instanz. Der Bauplan clsEmployee beschreibt, was jedes Mitarbeiter-Objekt hat (einen Namen, ein Gehalt) und tut (AnnualCost). Er ist selbst kein Mitarbeiter — er ist der Plan. Set e = New clsEmployee konstruiert einen tatsächlichen Mitarbeiter mit eigenen Daten; tun Sie das dreimal, und Sie haben drei unabhängige Objekte, jedes mit eigenem Namen und Gehalt, alle aus demselben Plan gebaut.

Halten Sie an dieser Trennung fest. Fast jede Verwirrung rund um Class module — „Warum steht kein Name in der Klasse?“, „Warum hat das Bearbeiten eines Objekts ein anderes verändert?“ — löst sich auf, sobald Sie den Bauplan (die Klasse) von einer Instanz (einem New-Objekt) trennen.

Warum es kein Class-Schlüsselwort gibt

Wer aus anderen Sprachen kommt, öffnet ein Class module und sucht nach einer Zeile wie Class clsEmployee. Die gibt es nicht, und sie hinzutippen ist ein Compilerfehler. In VBA ist der Name des Class module selbst der Typname. Sie benennen den Objekttyp um, indem Sie das Modul im Eigenschaftenfenster (F4) umbenennen, nicht mit einem Schlüsselwort im Code.

Der Ablauf ist also: Fügen Sie ein Class module ein, drücken Sie F4, setzen Sie (Name) auf clsEmployee (ein cls-Präfix ist die übliche Konvention) und beginnen Sie, seine Member direkt zu deklarieren. Die Datei ist die Klasse; ihr Name ist der Typ, den Sie hinter As schreiben.

Instanzen erzeugen: Set = New und die As-New-Falle

Es gibt zwei Wege, ein Objekt zu erzeugen, und sie sind nicht gleichwertig:

' Explizit (empfohlen)
Dim e As clsEmployee
Set e = New clsEmployee     ' genau hier erzeugt, in dieser Zeile

' Auto-Instanziierung (wirkt aufgeräumter, verbirgt zwei Fallen)
Dim e As New clsEmployee    ' NOCH NICHT erzeugt — erst bei der ersten Verwendung erzeugt

Die As New-Form ist verführerisch, weil sie eine Zeile ist, aber sie verbirgt zwei echte Probleme:

  • Sie können nie If e Is Nothing prüfen. Mit As New instanziiert VBA das Objekt in dem Moment, in dem Sie e anfassen, um es zu prüfen — also ist Is Nothing praktisch immer False. Sie verlieren die Möglichkeit zu fragen „Wurde das je erzeugt?“
  • Es aufersteht von selbst. Setzen Sie eine As New-Variable auf Nothing und referenzieren Sie sie danach erneut, dann erzeugt VBA stillschweigend eine neue Instanz — ein Zombie-Objekt, das wieder auftaucht, wenn Sie es längst zerstört glaubten.

Regel: Bevorzugen Sie Dim e As clsEmployee + Set e = New clsEmployee. Das erzeugt das Objekt an einer vorhersehbaren Zeile und hält Is Nothing aussagekräftig, sodass Sie sich gegen nicht initialisierte Objekte absichern können. Und vergessen Sie nie das Set: e = New clsEmployee ohne es zu schreiben löst Fehler 91, „Objektvariable oder With-Blockvariable nicht festgelegt“ aus — dieselbe Wert-gegen-Objekt-Regel, die besagt, dass Objekte mit Set zugewiesen werden, nicht mit =.

Die Regel, die überrascht: Objekte teilen, sie kopieren nicht

Das ist das Spiegelbild des Type-Artikels und die tiefste Quelle von Class-module-Bugs. Ein Objekt ist ein Referenztyp. Set b = a kopiert das Objekt nicht — es kopiert die Referenz, sodass a und b nun auf dieselbe Instanz zeigen:

Dim a As clsEmployee, b As clsEmployee
Set a = New clsEmployee
a.Salary = 50000
Set b = a               ' beide Namen -> EINE Instanz
b.Salary = 70000        ' bearbeitet das geteilte Objekt
Debug.Print a.Salary    ' 70000  — a „hat sich von selbst geändert“

Wenn Sie wirklich zwei unabhängige Mitarbeiter wollten, ist Set b = a ein Bug. VBA hat keine automatische Kopie für Objekte; Sie schreiben eine Clone-Methode, die eine frische Instanz mit denselben Feldwerten zurückgibt. Und wenn Sie eigentlich von Anfang an Kopieren-bei-Zuweisung wollten, ist das Ihr Signal, dass ein Type — ein Werttyp — das bessere Modell war. Zu wissen, welche Semantik Sie brauchen, teilen oder kopieren, ist der ganze Grund, beide zu verstehen.

Auf- und Abbau: Class_Initialize und der fehlende Konstruktor

Eine Klasse kann automatisch Code ausführen, wenn eine Instanz geboren wird oder stirbt:

Private Sub Class_Initialize()     ' läuft bei  Set e = New clsEmployee
    mSalary = 0                    ' hier Standardwerte setzen
End Sub

Private Sub Class_Terminate()      ' läuft, wenn die letzte Referenz verschwindet
    ' Dateien schließen, Handles freigeben usw.
End Sub

Der Haken: Class_Initialize nimmt keine Argumente entgegen. VBA hat keinen parametrisierten Konstruktor — Sie können nicht New clsEmployee("Sarah", 65000) schreiben. Sie erzeugen das Objekt zuerst und setzen dann seine Eigenschaften. Weil dieser zweistufige Tanz mühsam und leicht zu vergessen ist, ist die Standardlösung eine kleine Factory-Funktion in einem normalen Modul:

Function NewEmployee(nm As String, sal As Currency) As clsEmployee
    Dim e As clsEmployee
    Set e = New clsEmployee
    e.Name = nm
    e.Salary = sal
    Set NewEmployee = e
End Function
' Set e = NewEmployee("Sarah", 65000)   ' eine lesbare Zeile

Meine Faustregel: Jede Klasse, die Sie mehr als ein- oder zweimal erzeugen, verdient eine Factory-Funktion. Sie gibt Ihnen den parametrisierten Konstruktor, den VBA weggelassen hat, und sie hält die Erzeugung an einer Stelle statt über verstreute Set- und Eigenschaftszeilen.

Wann eine Klasse einen Type oder eine Collection schlägt

Greifen Sie zu einem Class module, wenn mindestens eines davon zutrifft:

  • Daten und Verhalten gehören zusammen — der Datensatz sollte Dinge über sich selbst prüfen, formatieren oder berechnen, statt diese Logik über Hilfs-Subs zu verstreuen.
  • Sie brauchen viele unabhängige, sich selbst verwaltende Objekte — Bestellungen, Rechnungen, Mitarbeiter — idealerweise gehalten in einer Collection, die Objekte akzeptiert, aber keinen Type.
  • Sie wollen Interna verbergen — eine saubere Oberfläche über Eigenschaften freigeben und die dahinterliegenden Felder Private halten.

Trifft keines davon zu und Sie wollen nur, dass Felder mit günstigen Kopien zusammen reisen, ist ein Type leichter und ehrlicher. Bauen Sie keine Klasse für einen Sack aus drei Werten — aber in dem Moment, in dem dieser Sack etwas tun muss, ist eine Klasse genau richtig.

Wie ExcelMaster hilft

In Class module leben die „kompiliert, verhält sich aber seltsam“-Bugs: der As New-Zombie, die Bearbeitung über eine geteilte Referenz, die ein Objekt „von selbst“ ändert, das vergessene Set, das Fehler 91 wirft. Jeder ist unsichtbar, bis er zubeißt, und jeder stammt aus einer Regel, die leicht zu formulieren und unter Termindruck leicht zu vergessen ist.

ExcelMaster lässt Sie das Objekt beschreiben, das Sie wollen — „ein Employee mit einem Namen, einem Gehalt und einer Methode, die die Jahreskosten zurückgibt und von dem ich eine Liste führen kann“ — und es schreibt die Klasse mit explizitem Set ... = New, einer Factory-Funktion, Private-Feldern, die über Eigenschaften freigegeben werden, und einer Collection, die sie hält. Sie bekommen idiomatisches, fallenfreies objektorientiertes VBA, ohne sich an jede Art erinnern zu müssen, wie New und Set Sie überraschen können.

Häufig gestellte Fragen

Was ist ein Class module in VBA?

Ein Class module ist der Ort, an dem Sie Ihren eigenen Objekttyp definieren — einen Bauplan, der Daten (Felder) und Verhalten (Methoden und Eigenschaften) bündelt. Einmal definiert, erzeugen Sie mit New unabhängige Instanzen davon. So unterstützt VBA eigene Objekte, einen Schritt jenseits eines Type, der nur Daten hält.

Wie erzeuge ich eine Instanz einer Klasse in VBA?

Deklarieren Sie eine Variable des Klassentyps und weisen Sie mit Set und New eine neue Instanz zu: Dim e As clsEmployee, dann Set e = New clsEmployee. Das Schlüsselwort Set ist bei Objekten Pflicht; es wegzulassen (e = New clsEmployee) löst Fehler 91 aus. Setzen Sie nach der Erzeugung seine Eigenschaften: e.Name = "Sarah".

Was ist der Unterschied zwischen Dim As New und Set New in VBA?

Dim e As clsEmployee + Set e = New clsEmployee erzeugt das Objekt an genau dieser Zeile und hält If e Is Nothing aussagekräftig. Dim e As New clsEmployee verzögert die Erzeugung bis zur ersten Verwendung, wodurch Is Nothing immer False ist und das Objekt stillschweigend neu erzeugt wird, wenn Sie es auf Nothing setzen und danach wieder anfassen. Bevorzugen Sie die explizite Set ... = New-Form.

Unterstützt eine VBA-Klasse einen Konstruktor mit Parametern?

Nein. Das Ereignis Class_Initialize läuft automatisch, wenn eine Instanz erzeugt wird, nimmt aber keine Argumente entgegen, sodass Sie nicht New clsEmployee("Sarah", 65000) schreiben können. Die Standardlösung ist eine Factory-Funktion in einem normalen Modul, die das Objekt erzeugt, seine Eigenschaften setzt und es zurückgibt — was Ihnen einen einzeiligen, parametrisierten Weg gibt, das Objekt zu bauen.

Wann sollte ich ein Class module statt eines Type oder einer Collection verwenden?

Nehmen Sie eine Klasse, wenn der Datensatz Verhalten (Methoden) braucht, wenn Sie viele unabhängige Objekte wollen, die Sie in einer Collection speichern können, oder wenn Sie interne Felder hinter Eigenschaften verbergen wollen. Wenn Sie nur brauchen, dass Felder mit günstigen, unabhängigen Kopien zusammen reisen, ist ein Type leichter und klarer.

Getestet in

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

Verwandte Anleitungen: VBA Type · VBA Property · VBA Dim · VBA Collection · VBA Dictionary