TL;DR — Chaque
Variantporte une étiquette de type.VarTypela renvoie sous forme de nombre (vbDoublevaut 5,vbStringvaut 8), etTypeNamesous forme de mot ("Double","String","Range"). Dans Excel, l'étiquette de la valeur d'une cellule est fixée par la cellule, pas par votre code : un nombre entier arrive enDouble, un nombre au format monétaire enCurrencyarrondi à quatre décimales, un nombre au format date enDate, une erreur enError, et une plage de plusieurs cellules en tableau. Interrogez l'étiquette aux frontières de votre code, là où les valeurs viennent des cellules, de la sélection de l'utilisateur ou d'un paramètreVariant, et déclarez de vrais types partout ailleurs.
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, ou ChartArea, Rectangle, Picture...
Voici le deuxième article d'une série consacrée à la question demander à une valeur ce qu'elle est :
IsEmpty teste une seule étiquette, VarType et TypeName lisent ici n'importe
laquelle, et IsNull teste l'étiquette qui signifie « mixte ou inconnu ». L'idée de la
série : une valeur VBA porte une étiquette de type distincte de son contenu, et ces fonctions lisent
l'étiquette, pas l'apparence de la valeur.
Ce que vous allez apprendre
- Le modèle mental : c'est la cellule qui fixe l'étiquette, pas votre code
- Les constantes VarType et les chaînes TypeName
- Pourquoi un nombre entier est un Double, et pourquoi un format monétaire arrondit vos données
- VarType regarde à travers les objets ; TypeName les nomme
- Le piège du tableau : une cellule ou plusieurs
- Vérifier ce que l'utilisateur a sélectionné
- Où interroger le type, et où le déclarer plutôt
Le modèle mental : c'est la cellule qui fixe l'étiquette, pas votre code
Quand vous écrivez Dim total As Double, c'est vous qui décidez du type. Quand vous lisez
Range("A1").Value, ce n'est plus vous : Excel vous remet un Variant, et c'est la cellule qui décide de ce
qu'il contient. La même ligne de code reçoit un nombre sur une ligne, du texte sur la suivante, une erreur sur
la troisième et rien du tout sur la quatrième.
VarType et TypeName vous permettent d'examiner cette décision avant d'agir. Ils ne convertissent rien et
n'échouent jamais : ils se contentent de rapporter l'étiquette.
Constantes VarType et chaînes TypeName
Les étiquettes que l'on rencontre en travaillant dans Excel, sous leurs deux noms :
| Cellule ou valeur | VarType |
constante | TypeName |
|---|---|---|---|
| cellule intacte | 0 | vbEmpty |
"Empty" |
| mixte ou inconnu | 1 | vbNull |
"Null" |
| tout nombre, y compris 42 | 5 | vbDouble |
"Double" |
| nombre au format monétaire | 6 | vbCurrency |
"Currency" |
| nombre au format date | 7 | vbDate |
"Date" |
| texte | 8 | vbString |
"String" |
#N/A, #DIV/0! et autres erreurs |
10 | vbError |
"Error" |
| VRAI ou FAUX | 11 | vbBoolean |
"Boolean" |
| la valeur d'une plage de plusieurs cellules | 8204 | vbArray + vbVariant |
"Variant()" |
Une variable Long donne 3 (vbLong), un Integer 2, et une variable objet donne "Range",
"Worksheet", "Workbook" ou "Nothing" avec TypeName. TypeName renvoie toujours le nom anglais, quelle
que soit la langue d'Office : on peut donc le comparer sans risque à une chaîne.
La façon naturelle d'exploiter l'étiquette est un Select Case qui traite chaque sorte de cellule :
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
Pourquoi un nombre entier est un Double, et pourquoi un format monétaire arrondit vos données
Deux surprises découlent du même fait : Excel stocke chaque nombre comme un Double, et .Value l'habille selon
le format de la cellule.
Un nombre entier est un Double. Une cellule contenant 42 renvoie vbDouble, pas vbLong. Un code qui
teste If VarType(c.Value) = vbLong ne correspond jamais à une cellule. Pour savoir si c'est un nombre entier,
vérifiez d'abord l'étiquette puis la valeur, en deux temps, car le And de VBA évalue les deux côtés et Int
échoue sur du texte : If VarType(v) = vbDouble Then isWhole = (v = Int(v)).
Le format change l'étiquette. Si une cellule est au format monétaire, .Value renvoie un Currency ; si
elle est au format date, il renvoie un Date. Un collègue qui reformate une colonne change ce que reçoit votre
code, sans toucher à une seule valeur. Currency ne conserve en outre que quatre décimales : une cellule au
format monétaire contenant un taux de change de 1,234567 est lue comme 1,2346.
.Value2 ne fait pas cet habillage : il renvoie un Double pour les nombres, les dates et les montants
monétaires, en pleine précision. Pour du code de calcul, lisez .Value2 :
Debug.Print TypeName(Range("B2").Value) ' Currency (B2 au format monetaire)
Debug.Print TypeName(Range("B2").Value2) ' Double
Le guide Value2 traite le versant date de cette même différence.
VarType regarde à travers les objets ; TypeName les nomme
Passez un Range lui-même, et non sa valeur, et les deux fonctions ne sont plus d'accord :
Debug.Print TypeName(Range("A1")) ' Range
Debug.Print VarType(Range("A1")) ' 5 si A1 contient un nombre, pas vbObject
VarType regarde à travers un objet qui possède une propriété par défaut et rapporte le type de cette
propriété. La propriété par défaut d'un Range est sa valeur : VarType(Range("A1")) décrit donc le contenu
de la cellule, et seul un objet sans propriété par défaut renvoie vbObject (9). TypeName, lui, rapporte
l'objet lui-même.
La règle est donc simple : utilisez TypeName (ou TypeOf) pour demander ce qu'est un objet, et VarType
pour demander ce qu'est une valeur.
Le piège du tableau : une cellule ou plusieurs
Lire une plage dans un Variant est la manière rapide de traiter des données, et elle cache un piège :
Dim data As Variant
data = Range("A2:A" & lastRow).Value
Debug.Print data(1, 1) ' Run-time error 13 si lastRow = 2
Quand la plage fait plus d'une cellule, data est un tableau à deux dimensions. Quand lastRow vaut 2 et que
la plage se réduit à une seule cellule, data n'est que la valeur de cette cellule, et l'indexer échoue avec
Type mismatch (« Incompatibilité de type »). Les états fonctionnent pendant des mois, puis plantent le jour où
il n'y a qu'une seule ligne.
Vérifiez avec IsArray et emballez vous-même la valeur unique :
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) est le même test que (VarType(v) And vbArray) <> 0. Le guide des tableaux
explique comment lire des plages dans des tableaux.
Vérifier ce que l'utilisateur a sélectionné
L'usage réel le plus courant de TypeName est une garde en tête d'une macro qui travaille sur la sélection.
L'utilisateur a pu cliquer sur un graphique, une forme ou une image au lieu de cellules :
Sub FormatSelectedCells()
If TypeName(Selection) <> "Range" Then
MsgBox "Select some cells first."
Exit Sub
End If
Selection.NumberFormat = "#,##0.00"
End Sub
Sans cette garde, Selection.NumberFormat déclenche l'erreur 438 (Object doesn't support this property or
method, « Propriété ou méthode non gérée par cet objet » dans un Excel français) quand un graphique est
sélectionné. If Not TypeOf Selection Is Range Then fait la même vérification, et le compilateur repère une
faute de frappe dans Range, ce qu'il ne peut pas faire dans la chaîne "Range". Utilisez TypeOf dans la
logique et TypeName quand vous voulez afficher ou journaliser le nom. Le
guide Selection couvre le reste.
Le parti pris : interroger aux frontières, déclarer partout ailleurs
VarType et TypeName sont des postes-frontières. Utilisez-les là où les valeurs entrent dans votre code
depuis l'extérieur : la valeur d'une cellule, la sélection de l'utilisateur, un paramètre Variant, un
élément d'une Collection, un résultat d'Application.Match. À l'intérieur de votre propre code, déclarez des
Long, String, Double et Range, et laissez le compilateur faire les vérifications.
Si vous trouvez des tests VarType disséminés au milieu d'une macro, la vraie correction consiste à lire
chaque valeur une seule fois, à vérifier son étiquette une seule fois à la frontière, et à la convertir là
dans une variable déclarée. Un seul Select Case VarType à l'entrée est plus clair et plus rapide qu'une
douzaine de tests If TypeName plus loin.
Comment ExcelMaster aide
Les surprises de type viennent des données, pas du code : une colonne reformatée en monétaire, une recherche
qui renvoie #N/A, un filtre qui ne laisse qu'une seule ligne.
ExcelMaster lit les vraies cellules, les formats et les erreurs de votre classeur avant d'écrire du code : la macro gère ainsi les types que votre feuille contient réellement, y compris le cas d'une seule ligne et les lignes en erreur.
Questions fréquentes
Quelle est la différence entre VarType et TypeName en VBA ?
VarType renvoie le type sous forme de nombre, par exemple 5 pour Double ou 8 pour String. TypeName le
renvoie sous forme de mot, par exemple "Double" ou "Range". Pour les objets, TypeName nomme l'objet,
tandis que VarType rapporte le type de sa propriété par défaut.
Comment vérifier le type de données d'une cellule en VBA ?
Utilisez TypeName(Range("A1").Value) ou VarType(Range("A1").Value). Un nombre renvoie Double, du texte
String, un nombre au format date Date, un nombre au format monétaire Currency, une erreur Error, et une
cellule intacte Empty.
Pourquoi VarType renvoie-t-il Double pour un nombre entier ?
Excel stocke tous les nombres en Double : une cellule contenant 42 renvoie donc vbDouble. Pour vérifier
qu'il s'agit d'un nombre entier, testez v = Int(v) après avoir confirmé que la valeur est numérique.
Comment vérifier si la sélection est une plage en VBA ?
Utilisez If TypeName(Selection) = "Range" Then ou If TypeOf Selection Is Range Then. Si un graphique ou
une forme est sélectionné, TypeName renvoie plutôt le nom de cet objet.
Que signifie VarType 8204 ?
8204 correspond à vbArray + vbVariant (8192 + 12) : un tableau de Variants. C'est ce que vous obtenez avec
la valeur d'une plage de plusieurs cellules.
Testé dans
Testé dans : Excel 365 (Windows 11), VBA 7.1 — vérifié le 04/10/2026.
Guides connexes : VBA IsEmpty · VBA IsNull · VBA Data Types · VBA Value2 · VBA Array · VBA Selection · VBA Select Case · VBA IsNumeric
