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

VBA Type dans Excel — regrouper des champs liés dans une seule variable (types définis par l'utilisateur ou class module)

|

VBA Type dans Excel — regrouper des champs liés dans une seule variable (types définis par l'utilisateur ou class module)

TL;DR — Un Type (un type défini par l'utilisateur, ou UDT) vous laisse nommer une forme une fois et transporter tous ses champs dans une seule variable. Au lieu de jongler avec trois tableaux qui doivent rester alignés par index, vous obtenez un seul tableau d'enregistrements. Un Type est un type valeur : affecter b = a copie chaque champ, si bien que les deux variables sont indépendantes — l'inverse d'une instance de classe, qui, elle, est partagée. Déclarez-le en haut d'un module standard, et ne sortez un class module que lorsque l'enregistrement doit faire quelque chose.

' Tout en haut d'un module standard, avant tout Sub ou Function :
Type Employee
    Name   As String
    Age    As Long
    Salary As Currency
End Type

Sub Demo()
    Dim e As Employee          ' une seule variable contient les trois champs
    e.Name = "Sarah"
    e.Age = 34
    e.Salary = 65000

    Dim copy As Employee
    copy = e                   ' COPIE PAR VALEUR — chaque champ est dupliqué
    copy.Salary = 99000        ' modifier la copie NE touche PAS e
    MsgBox e.Salary            ' toujours 65000
End Sub

La plupart des macros VBA qui « suivent plusieurs informations sur un même élément » finissent en tableaux parallèles — names(), ages(), salaries() — qui doivent tous rester dans le même ordre. Triez-en un en oubliant les autres, et le nom de la ligne 5 se retrouve rattaché au salaire de la ligne 12, sans la moindre erreur pour vous prévenir. Un Type règle le problème à la racine : les champs ne peuvent plus se désolidariser, puisqu'ils vivent dans une seule variable.

Ce que vous allez apprendre

  • Le modèle mental — une ligne de tableau vue comme une seule variable
  • Où un Type doit être déclaré (et pourquoi à l'intérieur d'un Sub ça échoue)
  • La règle qui surprend — un Type copie, il ne partage pas
  • Le vrai gain — un seul tableau d'enregistrements au lieu de tableaux parallèles
  • La limite dure — un Type ne peut porter aucun comportement ni entrer dans une Collection
  • Type ou class module — comment choisir

Le modèle mental : une ligne de tableau vue comme une seule variable

Voyez un Type comme une ligne de tableau promue au rang de variable. Dans une feuille de calcul, la ligne d'un employé aligne côte à côte un nom, un âge et un salaire ; un Type vous donne le même regroupement dans le code. Vous définissez les colonnes une fois (Type Employee ... End Type), et chaque Dim e As Employee est une nouvelle ligne dotée de ces mêmes cases.

C'est toute l'idée : cessez de faire circuler des valeurs éparses qui vont pourtant ensemble, et faites plutôt circuler une seule chose étiquetée. Une fonction qui a besoin d'un employé prend un unique argument Employee, pas trois paramètres que vous devez maintenir dans le bon ordre.

Où un Type doit être déclaré

Une déclaration Type se place au niveau module — tout en haut d'un module standard, au-dessus de toute procédure. Mettez-la à l'intérieur d'un Sub et le projet refuse de compiler. C'est ce qui piège ceux qui traitent Type comme Dim : Dim est une instruction que vous exécutez à l'intérieur d'une procédure, tandis que Type est une déclaration qui définit une forme pour tout le module, voire tout le projet.

Deux règles de placement à mémoriser :

  • Public Type (la valeur par défaut au niveau module) rend le type utilisable dans tout le projet. Utilisez Private Type pour le cantonner à un seul module.
  • Vous ne pouvez pas déclarer un Public Type dans un class module — VBA le refuse avec « Impossible de définir un type défini par l'utilisateur public dans un module objet privé ». Gardez vos Type partagés dans un module normal (Module1, ou un module Types dédié), pas dans une classe ni dans le code d'une feuille.

La règle qui surprend : un Type copie, il ne partage pas

C'est la chose la plus importante à comprendre au sujet d'un Type, car c'est précisément là qu'il diffère d'un objet. Un Type est un type valeur. Quand vous écrivez copy = e, VBA duplique chaque champ dans une variable toute neuve et indépendante :

Dim a As Employee, b As Employee
a.Salary = 50000
b = a                 ' copie complète de tous les champs
b.Salary = 70000      ' ne modifie que b
Debug.Print a.Salary  ' 50000  — a n'est pas touché

Comparez avec une instance de classe, où Set b = a fait de a et b deux noms pour le même objet : modifier l'un modifie l'autre. Si vous vous êtes déjà fait piéger par un objet qui change « tout seul » après l'avoir affecté quelque part, la copie à l'affectation d'un Type est l'antidote — et souvent exactement ce que vous voulez.

Le seul endroit où la copie n'a pas lieu, c'est le passage à une procédure. Un argument Type est ByRef par défaut, si bien qu'un Sub peut modifier votre original :

Sub GiveRaise(emp As Employee)      ' ByRef par défaut
    emp.Salary = emp.Salary * 1.1   ' modifie l'enregistrement de l'appelant
End Sub

Passez-le en ByVal si vous voulez que la procédure appelée travaille sur une copie privée — la même règle ByRef contre ByVal qui régit les variables ordinaires.

Le vrai gain : un seul tableau d'enregistrements

C'est ici qu'un Type justifie sa place. Au lieu de N tableaux parallèles que vous devez aligner à la main, vous déclarez un seul tableau d'enregistrements :

Dim staff(1 To 100) As Employee
staff(1).Name = "Sarah"
staff(1).Salary = 65000
staff(2).Name = "Tom"
staff(2).Salary = 58000

' Triez, filtrez ou réordonnez staff() et chaque champ suit —
' un nom ne peut plus jamais se désynchroniser de son salaire.

Le mode de défaillance ainsi éliminé est silencieux et vicieux : avec names(), ages() et salaries() en tableaux distincts, toute opération qui en réordonne un — un tri, une insertion, une suppression — désynchronise les autres, à moins de penser à l'appliquer à tous à l'identique. Avec un tableau d'Employee, il n'y a plus rien à synchroniser, car les champs ne se sont jamais quittés.

La limite dure : aucun comportement, et pas de Collection

Un Type est délibérément bête — il porte des données, et rien d'autre. Cela lui vaut deux limites dures qui vous disent quand vous l'avez dépassé :

  • Il ne peut pas avoir de méthodes. Dès l'instant où votre enregistrement doit faire quelque chose — valider son propre âge, se mettre en forme sous forme de chaîne, recalculer un total —, un Type ne peut rien pour vous. Le comportement relève d'un class module.
  • Il ne peut pas entrer dans une Collection ni un Dictionary. Ces conteneurs stockent des valeurs Variant, et un type défini par l'utilisateur ne peut pas être converti en Variant. Essayez coll.Add e avec un Type et VBA refuse. Si vous avez besoin d'un conteneur d'enregistrements extensible et indexé par clé, cela suffit à justifier le passage à une classe, dont les instances sont des objets qu'une Collection accepte.

Type ou class module : comment choisir

Type (UDT) Class module
Contient Des données seulement Des données et du comportement
Catégorie Type valeur Type référence (objet)
b = a Copie tous les champs Set b = a partage une seule instance
Déclaré dans Un module standard, au-dessus des procédures Son propre class module
Stockable dans une Collection ? Non Oui
Créé avec Dim e As Employee Set e = New clsEmployee
Idéal quand Les champs doivent juste voyager ensemble L'enregistrement a besoin de méthodes ou doit vivre dans une collection

Ma règle générale : si les champs doivent seulement rester ensemble et que vous voulez des copies indépendantes bon marché, un Type est le bon outil — sortir une classe ici, c'est de la sur-ingénierie. Passez à une classe dès que l'enregistrement a besoin d'un comportement, ou dès qu'il vous faut en garder beaucoup dans une Collection. Tout l'entre-deux relève du jugement, et « commencez par le Type, promouvez-le plus tard » est une valeur par défaut tout à fait saine.

Comment ExcelMaster aide

Choisir entre des tableaux parallèles, un Type et une véritable classe — puis se souvenir qu'un Type copie là où un objet partage — est exactement le genre de choix de modélisation qu'on rate subtilement. Les bugs qui en découlent (un tableau désynchronisé, un objet qui a muté « tout seul ») compilent sans broncher et ne se révèlent que plus tard.

ExcelMaster vous laisse plutôt décrire les données. Dites « je dois suivre le nom, l'âge et le salaire d'une liste d'employés et les trier par salaire », et il modélise les enregistrements à votre place — un tableau d'un Type, avec le tri appliqué pour que rien ne se désynchronise — et explique, dans le code, quand il aurait plutôt choisi une classe. Vous obtenez la bonne structure sans avoir à garder en tête toutes les règles du valeur-contre-référence.

Questions fréquentes

Qu'est-ce qu'un Type en VBA ?

Un Type (type défini par l'utilisateur, ou UDT) est une structure de données personnalisée qui regroupe plusieurs champs liés sous un même nom — par exemple un Employee avec Name, Age et Salary. Vous le déclarez une fois avec Type ... End Type en haut d'un module standard, puis vous l'utilisez comme n'importe quel autre type : Dim e As Employee. Il laisse des valeurs liées voyager ensemble dans une seule variable au lieu de variables séparées et faciles à désynchroniser.

Quelle est la différence entre un Type et un class module en VBA ?

Un Type ne contient que des données et c'est un type valeur — en affecter un à un autre copie chaque champ, donc les deux sont indépendants. Un class module contient données et comportement (des méthodes) et c'est un type référenceSet b = a fait pointer les deux noms vers la même instance. Utilisez un Type pour un enregistrement passif ; utilisez une classe quand l'enregistrement a besoin de méthodes ou doit être stocké dans une Collection.

Où déclarer un Type en VBA ?

Au niveau module, au-dessus de toute procédure, dans un module standard. Déclarer un Type à l'intérieur d'un Sub ou d'une Function est une erreur de compilation. Utilisez Public Type (la valeur par défaut) pour le partager dans tout le projet, ou Private Type pour le limiter à un seul module. Vous ne pouvez pas déclarer un Public Type dans un class module.

Peut-on stocker un Type VBA dans une Collection ou un Dictionary ?

Non. Une Collection et un Dictionary stockent des valeurs Variant, et un type défini par l'utilisateur ne peut pas être converti en Variant ; coll.Add someType échoue donc. Si vous avez besoin d'un conteneur d'enregistrements extensible ou indexé par clé, utilisez plutôt un class module — ses instances sont des objets qu'une Collection accepte — ou gardez les enregistrements dans un tableau du Type.

Affecter une variable Type à une autre copie-t-il ou partage-t-il les données ?

Il copie. Comme un Type est un type valeur, b = a duplique chaque champ dans une variable indépendante ; modifier b ensuite n'affecte pas a. C'est l'inverse des objets (les instances de classe), où Set b = a partage une seule instance. La seule exception est le passage d'un Type à une procédure, qui est ByRef par défaut et peut donc modifier l'enregistrement de l'appelant.

Testé dans

Testé dans : Excel 365 (Windows 11), VBA 7.1 — dernière vérification le 04/08/2026.

Guides associés : VBA Class Module · VBA Property · VBA Data Types · VBA Array · VBA ByRef contre ByVal