TL;DR — Un class module est un plan pour votre propre type d'objet. Vous l'écrivez une fois, puis vous créez autant d'instances indépendantes que vous voulez avec
New. Deux choses piègent tout le monde : le nom du class module est le nom du type (il n'y a pas de mot-cléClassà l'intérieur), et les objets sont des types référence, si bien queSet b = afait deaetbdeux noms pour la même instance. Préférez leSet x = New clsThingexplicite auDim x As New clsThing, qui cache un piège d'instanciation paresseuse.
' --- Dans un class module nommé clsEmployee (renommez-le dans la fenêtre Propriétés) ---
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 ' le comportement vit avec les données
AnnualCost = mSalary * 1.3 ' salaire + 30 % de charges
End Function
' --- Dans un module normal ---
Sub Demo()
Dim e As clsEmployee
Set e = New clsEmployee ' crée une instance
e.Name = "Sarah"
e.Salary = 65000
MsgBox e.Name & " costs " & e.AnnualCost ' 84500
End Sub
Un Type regroupe des champs. Un class module va un cran
plus loin : il regroupe les champs et le code qui agit dessus, et vous donne un
véritable objet que vous pouvez créer, dont vous pouvez copier les références, et
que vous pouvez stocker dans une Collection. C'est ce
que VBA offre de plus proche de la programmation orientée objet — et, bien utilisé,
cela transforme un fouillis de variables éparses et de Sub utilitaires en une
poignée d'objets autonomes.
Ce que vous allez apprendre
- Le modèle mental — un plan à partir duquel vous fabriquez des instances
- Pourquoi il n'y a pas de mot-clé
Class(le nom du module est le type) - Créer des instances —
Set ... = New, et le piègeAs New - La règle qui surprend — les objets partagent, ils ne copient pas
- Initialisation et libération —
Class_Initialize, et le constructeur manquant - Quand une classe l'emporte sur un
Typeou uneCollection
Le modèle mental : un plan, pas le bâtiment
Un class module est un plan ; chaque New en construit une instance. Le
plan clsEmployee décrit ce que tout objet employé possède (un nom, un salaire)
et fait (AnnualCost). Ce n'est pas lui-même un employé — c'est le plan.
Set e = New clsEmployee construit un employé bien réel avec ses propres données ;
faites-le trois fois et vous avez trois objets indépendants, chacun avec son nom et
son salaire, tous bâtis d'après le même plan.
Gardez cette distinction en tête. Presque toutes les confusions autour des class
modules — « pourquoi n'y a-t-il pas de nom dans la classe ? », « pourquoi modifier
un objet en a-t-il changé un autre ? » — se dissipent dès qu'on sépare le plan
(la classe) d'une instance (un objet créé par New).
Pourquoi il n'y a pas de mot-clé Class
Venant d'autres langages, on ouvre un class module en cherchant une ligne du genre
Class clsEmployee. Il n'y en a pas, et la taper est une erreur de compilation. En
VBA, le nom du class module est le nom du type. Vous renommez le type d'objet
en renommant le module dans la fenêtre Propriétés (F4), pas avec un mot-clé dans le
code.
Le déroulé est donc : insérez un class module, appuyez sur F4, réglez (Name)
sur clsEmployee (le préfixe cls est la convention courante), et commencez à
déclarer ses membres directement. Le fichier est la classe ; son nom est le type
que vous écrivez après As.
Créer des instances : Set = New, et le piège As New
Il y a deux façons de créer un objet, et elles ne sont pas équivalentes :
' Explicite (recommandé)
Dim e As clsEmployee
Set e = New clsEmployee ' créé exactement ici, sur cette ligne
' Auto-instanciation (plus net en apparence, cache deux pièges)
Dim e As New clsEmployee ' PAS encore créé — créé à la première utilisation
La forme As New est séduisante parce qu'elle tient sur une ligne, mais elle cache
deux vrais problèmes :
- Vous ne pouvez jamais tester
If e Is Nothing. AvecAs New, à l'instant où vous touchezepour le vérifier, VBA l'instancie — doncIs Nothingest en pratique toujoursFalse. Vous perdez la possibilité de demander « cet objet a-t-il seulement été créé ? ». - Il ressuscite tout seul. Affectez
Nothingà une variableAs New, puis référencez-la de nouveau, et VBA crée en silence une nouvelle instance — un objet zombie qui réapparaît alors que vous le croyiez détruit.
Règle : préférez Dim e As clsEmployee + Set e = New clsEmployee. Cela crée
l'objet à une ligne prévisible, et cela garde Is Nothing porteur de sens, pour
vous prémunir contre les objets non initialisés. Et n'oubliez jamais le Set :
écrire e = New clsEmployee sans lui déclenche l'erreur 91, « Variable objet ou
variable de bloc With non définie » — la même règle
valeur-contre-objet qui veut que les objets s'affectent avec
Set, pas avec =.
La règle qui surprend : les objets partagent, ils ne copient pas
C'est l'image inversée de l'article sur le Type, et c'est la
source la plus profonde des bugs de class module. Un objet est un type
référence. Set b = a ne copie pas l'objet — il copie la référence, si bien
que a et b pointent désormais vers la même instance :
Dim a As clsEmployee, b As clsEmployee
Set a = New clsEmployee
a.Salary = 50000
Set b = a ' les deux noms -> UNE seule instance
b.Salary = 70000 ' modifie l'objet partagé
Debug.Print a.Salary ' 70000 — a « a changé tout seul »
Si vous vouliez en réalité deux employés indépendants, Set b = a est un bug. VBA
n'a aucune copie automatique pour les objets ; vous écrivez une méthode Clone
qui renvoie une nouvelle instance avec les mêmes valeurs de champs. Et si ce que
vous vouliez vraiment dès le départ, c'était la copie à l'affectation, c'est le
signal qu'un Type — un type valeur — était le meilleur
modèle. Savoir de quelle sémantique vous avez besoin, partager ou copier, est
toute la raison de comprendre les deux.
Initialisation et libération : Class_Initialize et le constructeur manquant
Une classe peut exécuter du code automatiquement à la naissance ou à la mort d'une instance :
Private Sub Class_Initialize() ' s'exécute au Set e = New clsEmployee
mSalary = 0 ' placez les valeurs par défaut ici
End Sub
Private Sub Class_Terminate() ' s'exécute quand la dernière référence disparaît
' fermez les fichiers, libérez les handles, etc.
End Sub
Le hic : Class_Initialize ne prend aucun argument. VBA n'a pas de
constructeur paramétré — vous ne pouvez pas écrire
New clsEmployee("Sarah", 65000). Vous créez d'abord l'objet, puis vous réglez ses
propriétés. Comme ce pas de deux est fastidieux et facile à oublier, le
contournement standard est une petite fonction fabrique dans un module normal :
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) ' une seule ligne lisible
Ma règle générale : toute classe que vous créez plus d'une ou deux fois mérite
une fonction fabrique. Elle vous donne le constructeur paramétré que VBA a laissé de
côté, et elle garde la création en un seul endroit au lieu de lignes Set +
propriétés éparpillées.
Quand une classe l'emporte sur un Type ou une Collection
Sortez un class module dès qu'au moins l'un de ces points est vrai :
- Données et comportement vont de pair — l'enregistrement devrait valider,
mettre en forme ou calculer des choses sur lui-même, plutôt que de voir cette
logique éparpillée dans des
Subutilitaires. - Vous avez besoin de nombreux objets indépendants et autonomes — des
commandes, des factures, des employés — idéalement rangés dans une
Collection, qui accepte les objets mais pas unType. - Vous voulez masquer les détails internes — exposer une surface propre via des
propriétés et garder les champs de stockage
Private.
Si aucun de ces points ne tient et que vous voulez seulement faire voyager des
champs ensemble avec des copies bon marché, un Type est plus léger et plus
honnête. Ne construisez pas une classe pour un sac de trois valeurs — mais dès
l'instant où ce sac doit faire quelque chose, une classe est exactement ce qu'il
faut.
Comment ExcelMaster aide
Les class modules sont le repaire des bugs « ça compile mais ça se comporte
bizarrement » : le zombie As New, la modification par référence partagée qui
change un objet « tout seul », le Set oublié qui déclenche l'erreur 91. Chacun
reste invisible jusqu'à ce qu'il morde, et chacun découle d'une règle facile à
énoncer et facile à oublier sous la pression d'une échéance.
ExcelMaster
vous laisse décrire l'objet voulu — « un Employee avec un nom, un salaire et une
méthode qui renvoie le coût annuel, dont je peux garder une liste » — et il écrit la
classe avec un Set ... = New explicite, une fonction fabrique, des champs de
stockage Private exposés via des propriétés, et une Collection pour les
contenir. Vous obtenez du VBA orienté objet idiomatique et sans pièges, sans avoir à
vous souvenir de toutes les façons dont New et Set peuvent vous surprendre.
Questions fréquentes
Qu'est-ce qu'un class module en VBA ?
Un class module est l'endroit où vous définissez votre propre type d'objet — un plan
qui regroupe des données (des champs) et du comportement (des méthodes et des
propriétés). Une fois défini, vous en créez des instances
indépendantes avec New. C'est ainsi que VBA prend en charge les objets
personnalisés, un cran au-delà d'un Type, qui ne contient que
des données.
Comment créer une instance de classe en VBA ?
Déclarez une variable du type de la classe et affectez-lui une nouvelle instance
avec Set et New : Dim e As clsEmployee, puis Set e = New clsEmployee. Le
mot-clé Set est obligatoire pour les objets ; l'omettre (e = New clsEmployee)
déclenche l'erreur 91. Après la création, réglez ses propriétés :
e.Name = "Sarah".
Quelle est la différence entre Dim As New et Set New en VBA ?
Dim e As clsEmployee + Set e = New clsEmployee crée l'objet à cette ligne
précise et garde If e Is Nothing porteur de sens. Dim e As New clsEmployee
diffère la création jusqu'à la première utilisation, ce qui rend Is Nothing
toujours False et recrée l'objet en silence si vous l'affectez à Nothing puis le
touchez à nouveau. Préférez la forme explicite Set ... = New.
Une classe VBA prend-elle en charge un constructeur avec paramètres ?
Non. L'événement Class_Initialize s'exécute automatiquement à la création d'une
instance, mais il ne prend aucun argument ; vous ne pouvez donc pas écrire
New clsEmployee("Sarah", 65000). Le contournement standard est une fonction
fabrique, dans un module normal, qui crée l'objet, règle ses propriétés et le
renvoie — ce qui vous donne une façon paramétrée et tenant sur une ligne de
construire l'objet.
Quand utiliser un class module plutôt qu'un Type ou une Collection ?
Utilisez une classe quand l'enregistrement a besoin de comportement (des méthodes),
quand vous voulez de nombreux objets indépendants que vous pouvez stocker dans une
Collection, ou quand vous voulez masquer des champs
internes derrière des propriétés. Si vous avez seulement
besoin de faire voyager des champs ensemble avec des copies indépendantes bon
marché, un Type est plus léger et plus clair.
Testé dans
Testé dans : Excel 365 (Windows 11), VBA 7.1 — dernière vérification le 04/08/2026.
Guides associés : VBA Type · VBA Property · VBA Dim · VBA Collection · VBA Dictionary
