TL;DR — Jeder
Variantträgt eine Typkennung.VarTypeliefert sie als Zahl (vbDoubleist 5,vbStringist 8),TypeNameals Wort ("Double","String","Range"). In Excel setzt die Zelle die Kennung des Zellwerts, nicht Ihr Code: Eine ganze Zahl kommt alsDoublean, eine als Währung formatierte Zahl alsCurrency, gerundet auf vier Nachkommastellen, eine als Datum formatierte alsDate, ein Fehler alsErrorund ein mehrzelliger Bereich als Array. Fragen Sie die Kennung an den Rändern Ihres Codes ab, wo Werte aus Zellen, aus der Markierung des Benutzers oder aus einemVariant-Parameter kommen, und deklarieren Sie überall sonst echte Typen.
Debug.Print TypeName(Range("A1").Value) ' Double, String, Date, Boolean, Error, Empty...
Debug.Print VarType(Range("A1").Value) ' 5, 8, 7, 11, 10, 0...
Debug.Print TypeName(Selection) ' Range, oder ChartArea, Rectangle, Picture...
Dies ist der zweite Artikel einer Reihe darüber, einen Wert zu fragen, was er ist: IsEmpty
prüft auf eine einzige Kennung, hier lesen VarType und TypeName jede Kennung, und IsNull
prüft auf die Kennung, die „gemischt oder unbekannt“ bedeutet. Die Idee der Reihe: Ein VBA-Wert trägt eine
Typkennung getrennt von seinem Inhalt, und diese Funktionen lesen die Kennung, nicht das, wonach der Wert
aussieht.
Was Sie lernen
- Das mentale Modell: Die Zelle setzt die Kennung, nicht Ihr Code
- VarType-Konstanten und TypeName-Namen
- Warum eine ganze Zahl ein Double ist und ein Währungsformat Ihre Daten rundet
- VarType schaut durch Objekte hindurch, TypeName benennt sie
- Die Array-Falle bei einer gegenüber mehreren Zellen
- Prüfen, was der Benutzer markiert hat
- Wo Sie nachfragen und wo Sie stattdessen deklarieren
Das mentale Modell: Die Zelle setzt die Kennung, nicht Ihr Code
Wenn Sie Dim total As Double schreiben, bestimmen Sie den Typ. Wenn Sie Range("A1").Value lesen, tun Sie das
nicht: Excel reicht Ihnen einen Variant, und die Zelle entscheidet, was darin steckt. Dieselbe Codezeile
bekommt in einer Zeile eine Zahl, in der nächsten Text, in der dritten einen Fehler und in der vierten gar
nichts.
Mit VarType und TypeName können Sie sich diese Entscheidung ansehen, bevor Sie darauf reagieren. Sie wandeln
nichts um und schlagen nie fehl: Sie melden nur die Kennung.
VarType-Konstanten und TypeName-Namen
Die Kennungen, denen Sie in Excel begegnen, mit beiden Namen:
| Zelle oder Wert | VarType |
Konstante | TypeName |
|---|---|---|---|
| unberührte Zelle | 0 | vbEmpty |
"Empty" |
| gemischt oder unbekannt | 1 | vbNull |
"Null" |
| jede Zahl, auch 42 | 5 | vbDouble |
"Double" |
| als Währung formatierte Zahl | 6 | vbCurrency |
"Currency" |
| als Datum formatierte Zahl | 7 | vbDate |
"Date" |
| Text | 8 | vbString |
"String" |
#N/A, #DIV/0! und andere Fehler |
10 | vbError |
"Error" |
| WAHR oder FALSCH | 11 | vbBoolean |
"Boolean" |
| Wert eines mehrzelligen Bereichs | 8204 | vbArray + vbVariant |
"Variant()" |
Eine Long-Variable ergibt 3 (vbLong), ein Integer 2, und eine Objektvariable ergibt bei TypeName
"Range", "Worksheet", "Workbook" oder "Nothing". TypeName liefert immer den englischen Namen, in jeder
Office-Sprache, auch im deutschen Excel; der Vergleich mit einem String ist also sicher.
Der natürliche Weg, die Kennung zu nutzen, ist ein Select Case, das jede Art von Zelle behandelt:
Sub DescribeCell(ByVal c As Range)
Dim v As Variant
v = c.Value
Select Case VarType(v)
Case vbEmpty: Debug.Print c.Address, "empty"
Case vbString: Debug.Print c.Address, "text: " & v
Case vbDouble, vbCurrency: Debug.Print c.Address, "number: " & v
Case vbDate: Debug.Print c.Address, "date: " & Format$(v, "yyyy-mm-dd")
Case vbBoolean: Debug.Print c.Address, "logical: " & v
Case vbError: Debug.Print c.Address, "error: " & c.Text
End Select
End Sub
Warum eine ganze Zahl ein Double ist und ein Währungsformat Ihre Daten rundet
Zwei Überraschungen haben dieselbe Ursache: Excel speichert jede Zahl als Double, und .Value kleidet sie je
nach Zellformat ein.
Eine ganze Zahl ist ein Double. Eine Zelle mit 42 liefert vbDouble, nicht vbLong. Code, der
If VarType(c.Value) = vbLong prüft, trifft nie auf eine Zelle zu. Um zu fragen, ob es eine ganze Zahl ist,
prüfen Sie zuerst die Kennung und dann den Wert, in zwei Schritten, denn VBAs And wertet beide Seiten aus, und
Int scheitert an Text: If VarType(v) = vbDouble Then isWhole = (v = Int(v)).
Das Format ändert die Kennung. Ist eine Zelle als Währung formatiert, liefert .Value einen Currency; ist
sie als Datum formatiert, einen Date. Ein Kollege, der eine Spalte umformatiert, ändert, was Ihr Code bekommt,
ohne einen einzigen Wert anzufassen. Currency hält außerdem nur vier Nachkommastellen; eine als Währung
formatierte Zelle mit dem Wechselkurs 1,234567 wird also als 1,2346 gelesen.
.Value2 kleidet nichts ein: Es liefert für Zahlen, Datumswerte und Währungen gleichermaßen einen Double, mit
voller Genauigkeit. Für Rechencode lesen Sie .Value2:
Debug.Print TypeName(Range("B2").Value) ' Currency (B2 als Waehrung formatiert)
Debug.Print TypeName(Range("B2").Value2) ' Double
Die Value2-Anleitung behandelt die Datumsseite desselben Unterschieds.
VarType schaut durch Objekte hindurch, TypeName benennt sie
Übergeben Sie einen Range selbst statt seines Werts, sind sich die beiden Funktionen nicht einig:
Debug.Print TypeName(Range("A1")) ' Range
Debug.Print VarType(Range("A1")) ' 5, wenn A1 eine Zahl enthaelt, nicht vbObject
VarType schaut durch ein Objekt mit Standardeigenschaft hindurch und meldet den Typ dieser Eigenschaft. Die
Standardeigenschaft eines Range ist sein Wert, VarType(Range("A1")) beschreibt also den Zellinhalt; nur ein
Objekt ohne Standardeigenschaft liefert vbObject (9). TypeName meldet das Objekt selbst.
Die Regel ist also einfach: Verwenden Sie TypeName (oder TypeOf), um zu fragen, was ein Objekt ist, und
VarType, um zu fragen, was ein Wert ist.
Die Array-Falle bei einer gegenüber mehreren Zellen
Einen Bereich in einen Variant einzulesen ist der schnelle Weg, Daten zu verarbeiten, und er verbirgt eine
Falle:
Dim data As Variant
data = Range("A2:A" & lastRow).Value
Debug.Print data(1, 1) ' Laufzeitfehler 13, wenn lastRow = 2
Umfasst der Bereich mehr als eine Zelle, ist data ein zweidimensionales Array. Ist lastRow gleich 2 und der
Bereich nur eine Zelle, ist data einfach der Wert dieser Zelle, und der Indexzugriff scheitert mit Type
mismatch (Laufzeitfehler 13 „Typen unverträglich“). Berichte laufen monatelang und stürzen dann an dem Tag ab,
an dem es nur eine Zeile gibt.
Prüfen Sie mit IsArray und verpacken Sie den Einzelwert selbst:
If Not IsArray(data) Then
Dim one(1 To 1, 1 To 1) As Variant
one(1, 1) = data
data = one
End If
IsArray(v) ist derselbe Test wie (VarType(v) And vbArray) <> 0. Die Array-Anleitung
behandelt das Einlesen von Bereichen in Arrays.
Prüfen, was der Benutzer markiert hat
Die häufigste echte Verwendung von TypeName ist ein Schutz am Anfang eines Makros, das mit der Markierung
arbeitet. Der Benutzer hat vielleicht ein Diagramm, eine Form oder ein Bild angeklickt statt Zellen:
Sub FormatSelectedCells()
If TypeName(Selection) <> "Range" Then
MsgBox "Select some cells first."
Exit Sub
End If
Selection.NumberFormat = "#,##0.00"
End Sub
Ohne den Schutz löst Selection.NumberFormat bei markiertem Diagramm den Fehler 438 aus (Object doesn't
support this property or method, im deutschen Excel „Objekt unterstützt diese Eigenschaft oder Methode
nicht“). If Not TypeOf Selection Is Range Then erledigt dieselbe Prüfung, und der Compiler erkennt einen
Tippfehler in Range, während er einen im String "Range" nicht erkennen kann. Verwenden Sie TypeOf in der
Logik und TypeName, wenn Sie den Namen anzeigen oder protokollieren wollen. Die
Selection-Anleitung behandelt den Rest.
Die Abwägung: an den Rändern fragen, überall sonst deklarieren
VarType und TypeName sind Grenzkontrollen. Setzen Sie sie dort ein, wo Werte von außen in Ihren Code kommen:
der Wert einer Zelle, die Markierung des Benutzers, ein Variant-Parameter, ein Element aus einer Collection,
ein Ergebnis von Application.Match. In Ihrem eigenen Code deklarieren Sie Long, String, Double und
Range und überlassen die Prüfung dem Compiler.
Finden Sie VarType-Prüfungen quer durch die Mitte eines Makros verteilt, besteht die eigentliche Lösung darin,
jeden Wert einmal zu lesen, seine Kennung einmal an der Grenze zu prüfen und ihn dort in eine deklarierte
Variable umzuwandeln. Ein einziges Select Case VarType am Eingang ist klarer und schneller als ein Dutzend
If TypeName-Prüfungen weiter unten.
Wie ExcelMaster hilft
Typ-Überraschungen kommen aus den Daten, nicht aus dem Code: eine als Währung umformatierte Spalte, ein
Nachschlagen, das #N/A liefert, ein Filter, der eine einzige Zeile übrig lässt.
ExcelMaster liest die tatsächlichen Zellen, Formate und Fehler in Ihrer Arbeitsmappe, bevor es Code schreibt, damit das Makro mit den Typen umgehen kann, die Ihr Blatt wirklich enthält — einschließlich des Falls mit nur einer Zeile und der Fehlerzeilen.
Häufig gestellte Fragen
Was ist der Unterschied zwischen VarType und TypeName in VBA?
VarType liefert den Typ als Zahl, etwa 5 für Double oder 8 für String. TypeName liefert ihn als Wort, etwa
"Double" oder "Range". Bei Objekten benennt TypeName das Objekt, während VarType den Typ seiner
Standardeigenschaft meldet.
Wie prüfe ich in VBA den Datentyp einer Zelle?
Verwenden Sie TypeName(Range("A1").Value) oder VarType(Range("A1").Value). Eine Zahl liefert Double, Text
String, eine als Datum formatierte Zahl Date, eine als Währung formatierte Zahl Currency, ein Fehler Error und
eine unberührte Zelle Empty.
Warum liefert VarType bei einer ganzen Zahl Double?
Excel speichert alle Zahlen als Double, eine Zelle mit 42 liefert also vbDouble. Um auf eine ganze Zahl zu
prüfen, testen Sie v = Int(v), nachdem Sie sichergestellt haben, dass der Wert numerisch ist.
Wie prüfe ich in VBA, ob die Markierung ein Bereich ist?
Verwenden Sie If TypeName(Selection) = "Range" Then oder If TypeOf Selection Is Range Then. Ist ein Diagramm
oder eine Form markiert, liefert TypeName stattdessen deren Objektnamen.
Was bedeutet VarType 8204?
8204 ist vbArray + vbVariant (8192 + 12): ein Array aus Variants. Das bekommen Sie vom Wert eines mehrzelligen
Bereichs.
Getestet in
Getestet in: Excel 365 (Windows 11), VBA 7.1 — zuletzt geprüft am 04.10.2026.
Verwandte Anleitungen: VBA IsEmpty · VBA IsNull · VBA Data Types · VBA Value2 · VBA Array · VBA Selection · VBA Select Case · VBA IsNumeric
