TL;DR — Ein
Type(ein benutzerdefinierter Typ, kurz UDT) lässt Sie eine Form einmal benennen und alle ihre Felder in einer einzigen Variablen mitführen. Statt drei Arrays zu jonglieren, die indexgleich bleiben müssen, erhalten Sie ein Array aus Datensätzen. EinTypeist ein Werttyp:b = akopiert jedes Feld, sodass die beiden Variablen unabhängig sind — das Gegenteil einer Class-Instanz, die geteilt wird. Deklarieren Sie ihn ganz oben in einem Standardmodul und greifen Sie erst dann zu einem Class module, wenn der Datensatz auch etwas tun muss.
' Ganz oben in einem Standardmodul, vor jedem Sub oder Function:
Type Employee
Name As String
Age As Long
Salary As Currency
End Type
Sub Demo()
Dim e As Employee ' eine Variable hält alle drei Felder
e.Name = "Sarah"
e.Age = 34
e.Salary = 65000
Dim copy As Employee
copy = e ' WERTKOPIE — jedes Feld dupliziert
copy.Salary = 99000 ' das Ändern der Kopie berührt e NICHT
MsgBox e.Salary ' immer noch 65000
End Sub
Der meiste VBA-Code, der „mehrere Dinge über ein einzelnes Element verfolgt“, endet als
parallele Arrays — names(), ages(), salaries() —, die alle in derselben Reihenfolge
bleiben müssen. Sortieren Sie eines und vergessen die anderen, und der Name aus Zeile 5
gehört plötzlich zum Gehalt aus Zeile 12 — ohne jeden Fehler, der Sie warnt. Ein Type
behebt das an der Wurzel: Die Felder können nicht mehr auseinanderdriften, weil sie in
einer einzigen Variablen leben.
Was Sie lernen
- Das mentale Modell — eine Zeile als eine einzige Variable
- Wo ein Type deklariert werden muss (und warum es innerhalb einer Sub scheitert)
- Die Regel, die überrascht — ein Type kopiert, er teilt nicht
- Der eigentliche Gewinn — ein Array aus Datensätzen statt paralleler Arrays
- Die harte Grenze — ein Type kann kein Verhalten halten und nicht in eine Collection
- Type vs. Class module — wie Sie wählen
Das mentale Modell: eine Zeile als eine einzige Variable
Denken Sie an einen Type als eine Zeile einer Tabelle, zur Variablen befördert. Eine
Arbeitsblattzeile für einen Mitarbeiter hat einen Namen, ein Alter und ein Gehalt direkt
nebeneinander; ein Type gibt Ihnen dieselbe Gruppierung im Code. Sie definieren die
Spalten einmal (Type Employee ... End Type), und jedes Dim e As Employee ist eine
frische Zeile mit genau denselben Fächern.
Das ist die ganze Idee: Hören Sie auf, lose Werte zu übergeben, die zusammengehören, und
übergeben Sie stattdessen ein einziges beschriftetes Ding. Eine Funktion, die einen
Mitarbeiter braucht, nimmt ein einzelnes Employee-Argument entgegen, nicht drei
Parameter, die Sie in der richtigen Reihenfolge halten müssen.
Wo ein Type deklariert werden muss
Eine Type-Deklaration steht auf Modulebene — ganz oben in einem Standardmodul,
oberhalb jeder Prozedur. Schreiben Sie sie in eine Sub, kompiliert das Projekt nicht.
Das bringt jene zu Fall, die Type wie Dim behandeln: Dim ist eine Anweisung, die Sie
innerhalb einer Prozedur ausführen, aber Type ist eine Deklaration, die eine Form für
das ganze Modul oder Projekt festlegt.
Zwei Platzierungsregeln, die man sich merken sollte:
Public Type(die Vorgabe auf Modulebene) macht den Typ im ganzen Projekt nutzbar. Nutzen SiePrivate Type, um ihn auf ein Modul zu beschränken.- Sie können kein
Public Typeinnerhalb eines Class module deklarieren — VBA lehnt das mit „Ein öffentlicher benutzerdefinierter Typ kann nicht in einem privaten Objektmodul definiert werden“ ab. Halten Sie Ihre gemeinsam genutzten Types in einem normalen Modul (Module1oder einem eigenenTypes-Modul), nicht in einer Klasse oder im Code eines Blatts.
Die Regel, die überrascht: ein Type kopiert, er teilt nicht
Das ist das mit Abstand Wichtigste, das Sie über einen Type verstehen müssen, denn es
ist genau der Punkt, an dem er sich von einem Objekt unterscheidet. Ein Type ist ein
Werttyp. Wenn Sie copy = e schreiben, dupliziert VBA jedes Feld in eine
brandneue, unabhängige Variable:
Dim a As Employee, b As Employee
a.Salary = 50000
b = a ' vollständige Kopie aller Felder
b.Salary = 70000 ' ändert nur b
Debug.Print a.Salary ' 50000 — a bleibt unberührt
Vergleichen Sie das mit einer Class-Instanz, wo Set b = a
aus a und b zwei Namen für dasselbe Objekt macht, sodass das Bearbeiten des einen
das andere mitbearbeitet. Wenn Sie je davon gebeutelt wurden, dass sich ein Objekt „von
selbst“ änderte, nachdem Sie es irgendwo zugewiesen hatten, ist das
Kopier-bei-Zuweisung-Verhalten des Type das Gegenmittel — und oft genau das, was Sie
wollen.
Die eine Stelle, an der die Kopie nicht passiert, ist die Übergabe an eine Prozedur.
Ein Type-Argument ist standardmäßig ByRef, also kann eine Sub Ihr Original
verändern:
Sub GiveRaise(emp As Employee) ' standardmäßig ByRef
emp.Salary = emp.Salary * 1.1 ' verändert den Datensatz des Aufrufers
End Sub
Übergeben Sie ihn ByVal, wenn der Aufgerufene mit einer privaten Kopie arbeiten soll —
dieselbe ByRef-vs.-ByVal-Regel, die auch für gewöhnliche
Variablen gilt.
Der eigentliche Gewinn: ein Array aus Datensätzen
Hier verdient sich ein Type seinen Platz. Statt N paralleler Arrays, die Sie von Hand
ausgerichtet halten müssen, deklarieren Sie ein einziges Array aus Datensätzen:
Dim staff(1 To 100) As Employee
staff(1).Name = "Sarah"
staff(1).Salary = 65000
staff(2).Name = "Tom"
staff(2).Salary = 58000
' Sortieren, filtern oder umordnen von staff() — jedes Feld bewegt sich mit,
' ein Name kann sich nie wieder von seinem Salary abkoppeln.
Der Fehlermodus, den das beseitigt, ist stumm und bösartig: Mit names(), ages() und
salaries() als getrennte Arrays wird jede Operation, die eines
umordnet — ein Sortieren, ein Einfügen, ein Löschen — den Rest aus dem Takt bringen,
sofern Sie nicht daran denken, sie identisch auf alle anzuwenden. Mit einem Array aus
Employee gibt es nichts synchron zu halten, weil die Felder einander nie verlassen
haben.
Die harte Grenze: kein Verhalten und keine Collection
Ein Type ist bewusst dumm — er hält Daten und sonst nichts. Das verschafft ihm zwei
harte Grenzen, die Ihnen sagen, wann Sie ihm entwachsen sind:
- Er kann keine Methoden haben. In dem Moment, in dem Ihr Datensatz etwas tun muss —
sein eigenes Alter prüfen, sich als Zeichenfolge formatieren, eine Summe neu berechnen —,
kann ein
Typenicht helfen. Verhalten gehört in ein Class module. - Er kann nicht in eine
Collectionoder einDictionary. Diese Speicher haltenVariant-Werte, und ein UDT lässt sich nicht in einenVariantzwängen. Versuchen Siecoll.Add emit einemType, und VBA verweigert es. Wenn Sie einen wachsbaren, schlüsselbasierten Speicher für Datensätze brauchen, ist allein das ein Grund, zu einer Klasse zu wechseln, deren Instanzen echte Objekte sind, die eineCollectionakzeptiert.
Type vs. Class module: wie Sie wählen
Type (UDT) |
Class module | |
|---|---|---|
| Hält | Nur Daten | Daten und Verhalten |
| Kategorie | Werttyp | Referenztyp (Objekt) |
b = a |
Kopiert alle Felder | Set b = a teilt eine Instanz |
| Deklariert in | Standardmodul, oberhalb der Prozeduren | eigenem Class module |
In Collection speicherbar? |
Nein | Ja |
| Erzeugen mit | Dim e As Employee |
Set e = New clsEmployee |
| Am besten, wenn | Felder nur zusammen reisen müssen | der Datensatz Methoden braucht oder in einer Collection leben muss |
Meine Faustregel: Wenn die Felder nur zusammenbleiben müssen und Sie günstige,
unabhängige Kopien wollen, ist ein Type das richtige Werkzeug — hier zu einer Klasse zu
greifen, ist Over-Engineering. Wechseln Sie in dem Moment zu einer Klasse, in dem der
Datensatz Verhalten braucht, oder in dem Sie viele davon in einer Collection halten
müssen. Alles dazwischen ist eine Ermessensfrage, und „Fang mit dem Type an, befördere
ihn später“ ist eine gute Standardwahl.
Wie ExcelMaster hilft
Die Entscheidung zwischen parallelen Arrays, einem Type und einer vollen Klasse — und
dann daran zu denken, dass ein Type kopiert, während ein Objekt teilt — ist genau die
Art Modellierungsentscheidung, die man leicht auf subtile Weise falsch trifft. Die Bugs,
die sie verursacht (ein aus dem Takt geratenes Array, ein Objekt, das sich „von selbst“
veränderte), kompilieren sauber und tauchen erst später auf.
ExcelMaster lässt Sie
stattdessen die Daten beschreiben. Sagen Sie „Ich muss Name, Alter und Gehalt für eine
Liste von Mitarbeitern verfolgen und sie nach Gehalt sortieren“, und es modelliert die
Datensätze für Sie — ein Array aus einem Type, mit angewandter Sortierung, sodass nichts
aus dem Takt gerät — und erklärt im Code, wann es stattdessen eine Klasse gewählt hätte.
Sie bekommen die richtige Struktur, ohne alle Wert-gegen-Referenz-Regeln im Kopf behalten
zu müssen.
Häufig gestellte Fragen
Was ist ein Type in VBA?
Ein Type (benutzerdefinierter Typ, kurz UDT) ist eine eigene Datenstruktur, die mehrere
zusammengehörige Felder unter einem Namen gruppiert — etwa einen Employee mit Name,
Age und Salary. Sie deklarieren ihn einmal mit Type ... End Type ganz oben in einem
Standardmodul und verwenden ihn dann wie jeden anderen Typ: Dim e As Employee. So reisen
zusammengehörige Werte als eine einzige Variable statt als getrennte, leicht aus dem Takt
geratende Variablen.
Was ist der Unterschied zwischen einem Type und einem Class module in VBA?
Ein Type hält nur Daten und ist ein Werttyp — die Zuweisung des einen an den
anderen kopiert jedes Feld, sodass beide unabhängig sind. Ein
Class module hält Daten und Verhalten (Methoden) und ist
ein Referenztyp — Set b = a lässt beide Namen auf dieselbe Instanz zeigen. Nehmen
Sie einen Type für einen passiven Datensatz; nehmen Sie eine Klasse, wenn der Datensatz
Methoden braucht oder in einer Collection gespeichert werden muss.
Wo deklariere ich einen Type in VBA?
Auf Modulebene, oberhalb jeder Prozedur, in einem Standardmodul. Einen Type
innerhalb einer Sub oder Function zu deklarieren, ist ein Compilerfehler. Nutzen Sie
Public Type (die Vorgabe), um ihn im ganzen Projekt zu teilen, oder Private Type, um
ihn auf ein Modul zu begrenzen. Sie können kein Public Type innerhalb eines Class module
deklarieren.
Kann ich einen VBA Type in einer Collection oder einem Dictionary speichern?
Nein. Eine Collection und ein Dictionary speichern Variant-Werte, und ein
benutzerdefinierter Typ lässt sich nicht in einen Variant umwandeln, also schlägt
coll.Add someType fehl. Wenn Sie einen wachsbaren oder schlüsselbasierten Speicher für
Datensätze brauchen, nehmen Sie stattdessen ein Class module —
dessen Instanzen sind Objekte, die eine Collection akzeptiert — oder halten Sie die
Datensätze in einem Array des Type.
Kopiert oder teilt die Zuweisung einer Type-Variablen an eine andere die Daten?
Sie kopiert. Weil ein Type ein Werttyp ist, dupliziert b = a jedes Feld in eine
unabhängige Variable; das spätere Ändern von b wirkt sich nicht auf a aus. Das ist das
Gegenteil von Objekten (Class-Instanzen), bei denen Set b = a eine einzige Instanz
teilt. Die einzige Ausnahme ist die Übergabe eines Type an eine Prozedur, die
standardmäßig ByRef ist und daher den Datensatz des Aufrufers verändern kann.
Getestet in
Getestet in: Excel 365 (Windows 11), VBA 7.1 — zuletzt geprüft am 04.08.2026.
Verwandte Anleitungen: VBA Class Module · VBA Property · VBA Datentypen · VBA Array · VBA ByRef vs. ByVal
