TL;DR — Un graphique ne stocke pas de données — il stocke une référence à un Range. Le
.Valuesde chaque série est une formule comme=Sheet1!$B$2:$B$13, si bien que le graphique n'est jamais plus juste que cette référence. Créez un graphique incorporé avecws.ChartObjects.Add(left, top, width, height), récupérez son.Chart, réglez.ChartType, et liez les données en un seul geste avec.SetSourceData Source:=Range(...). Les deux choses qui mordent : les graphiques incorporés vivent dansChartObjects(pasCharts, qui sont des feuilles de graphique), et réexécuter la macro empile des graphiques en double si vous ne supprimez pas les anciens d'abord.
Dim co As ChartObject, ch As Chart
Set co = Worksheets("Report").ChartObjects.Add( _
Left:=300, Top:=20, Width:=420, Height:=260)
Set ch = co.Chart ' le ChartObject est le cadre ; .Chart est le graphique
ch.ChartType = xlColumnClustered
ch.SetSourceData Source:=Worksheets("Data").Range("A1:B13") ' lie toute la plage d'un coup
ch.HasTitle = True
ch.ChartTitle.Text = "Monthly Sales"
Faire des graphiques en VBA paraît facile jusqu'à la deuxième exécution, où vous trouvez deux graphiques, ou jusqu'à la première, où les barres tracent la mauvaise colonne. Les deux viennent du même malentendu, et le correctif des deux est la même idée : un graphique ne contient pas vos données — il pointe dessus. Chaque série tient une référence à une plage, écrite sous forme de formule. Déplacez les données, insérez une ligne, reconstruisez la source à un autre endroit, et le graphique continue de pointer là où on le lui a dit, traçant fidèlement les mauvaises cellules. Une fois que vous tenez « un graphique est une vue liée à un Range », l'API cesse d'être capricieuse et les deux bugs classiques deviennent évidents.
Ce que vous allez apprendre
- Le modèle mental — un graphique tient une référence à un Range, pas une copie des données
- Les deux conteneurs : les
ChartObjectsincorporés contre les feuilles de graphique dansCharts - Créer un graphique et lier les données en un seul geste avec
SetSourceData - Ajouter et contrôler les séries à la main avec
SeriesCollection - Le piège du graphique en double à la réexécution, et comment effacer les anciens
- Lier la source à une Table pour que le graphique suive les données
Le modèle mental : un graphique pointe sur un Range
Quand vous portez une plage en graphique, Excel ne copie pas les nombres dans le graphique. Il stocke, pour chaque série, une formule qui référence la plage — de la même façon qu'une formule de cellule référence d'autres cellules. Vous pouvez la relire :
Debug.Print ch.SeriesCollection(1).Formula
' =SERIES("Sales",Data!$A$2:$A$13,Data!$B$2:$B$13,1)
Cette formule SERIES(...) est toute la vérité sur le graphique : un nom, une référence de valeurs X, une
référence de valeurs Y. Le graphique est une vue vivante sur ces références. Voilà pourquoi « mon graphique
affiche les mauvaises données » est si courant — le graphique n'est pas faux, sa référence pointe sur des
cellules qui ne contiennent plus ce que vous croyez. Et voilà pourquoi le correctif durable, à la fin de ce
guide, consiste à faire suivre les données à la référence au lieu de la figer sur $B$2:$B$13.
Les deux conteneurs : ChartObjects contre feuilles de graphique
Excel a deux domiciles pour les graphiques, et les confondre est la première chose qui fait trébucher une
macro de graphique. Un graphique incorporé flotte sur une feuille et vit dans la collection
ChartObjects de cette feuille ; une feuille de graphique est un onglet entier qui n'est rien d'autre
qu'un graphique, et vit dans la collection Charts du classeur :
' Incorpore : un ChartObject est le cadre/conteneur ; son .Chart est le graphique lui-meme
Dim co As ChartObject
Set co = Worksheets("Report").ChartObjects.Add(300, 20, 420, 260)
co.Chart.ChartType = xlLine ' reglez les proprietes sur .Chart, pas sur co
' Feuille de graphique : un onglet a part entiere
Dim ch As Chart
Set ch = ThisWorkbook.Charts.Add
La subtilité qui coûte une heure aux gens : avec un graphique incorporé, ChartObjects.Add vous donne le
cadre (un ChartObject), et le graphique que vous formatez réellement est co.Chart. Aller chercher
Charts(1) quand votre graphique est incorporé déclenche une erreur, car Charts ne contient que des
feuilles de graphique. La plupart des rapports vivent sur une feuille, vous utiliserez donc ChartObjects
bien plus souvent — souvenez-vous juste de la scission en deux couches cadre/graphique.
Créer un graphique et lier les données en un seul geste
Le schéma propre est : ajouter le cadre, récupérer .Chart, régler le type, et lier toute la source avec
SetSourceData en un seul appel :
Dim co As ChartObject, ch As Chart
Set co = Worksheets("Report").ChartObjects.Add(300, 20, 420, 260)
Set ch = co.Chart
ch.ChartType = xlColumnClustered
ch.SetSourceData Source:=Worksheets("Data").Range("A1:B13")
SetSourceData remet à Excel tout le bloc — en-têtes, catégories et valeurs — et le laisse déterminer les
séries, exactement comme sélectionner la plage et appuyer sur le bouton de graphique. C'est presque
toujours ce que vous voulez ; c'est moins de lignes et moins d'erreurs que construire les séries une à une.
Incluez la ligne d'en-tête et la colonne de catégories dans la plage et le graphique s'étiquette tout seul.
Réglez .ChartType avant ou après — les valeurs courantes sont xlColumnClustered, xlLine, xlPie et
xlXYScatter.
Ajouter et contrôler les séries à la main
Quand il vous faut un contrôle précis — une série à la fois, des valeurs venues d'un endroit non contigu, un
nom personnalisé — ajoutez les séries via SeriesCollection :
Dim s As Series
Set s = ch.SeriesCollection.NewSeries
s.Name = "2026"
s.XValues = Worksheets("Data").Range("A2:A13")
s.Values = Worksheets("Data").Range("B2:B13")
Chaque série a trois parties qui correspondent directement à cette formule SERIES(...) : .Name,
.XValues (les étiquettes de catégories) et .Values (les nombres). Ajoutez une deuxième série avec un
autre NewSeries ; retirez-en une avec ch.SeriesCollection(2).Delete. Affecter une plage à .Values
revient à écrire la référence dans la formule de la série — ce qui est le mécanisme derrière le bug des
mauvaises données, et la raison pour laquelle la liaison à une source stable compte.
Le piège du graphique en double, et l'effacement des anciens graphiques
Voici le bug qui produit douze graphiques après douze exécutions : ChartObjects.Add ajoute toujours un
nouveau graphique. Il ne réutilise jamais celui de la dernière fois, si bien qu'une macro sans
surveillance empile discrètement des copies. Effacez les graphiques existants de la feuille avant de
construire :
Dim co As ChartObject
For Each co In Worksheets("Report").ChartObjects
co.Delete ' supprime d'abord les graphiques de la derniere execution
Next co
' ...construisez maintenant le nouveau graphique
Bouclez sur ChartObjects et faites Delete sur chacun, puis créez votre graphique à partir d'une page
blanche — la même discipline de collection que vous appliqueriez à toute
construction répétée. Si vous préférez garder et mettre à jour un graphique précis, nommez-le
(co.Name = "chtSales"), retrouvez-le par ce nom à l'exécution suivante, et rappelez SetSourceData au
lieu d'ajouter un nouveau cadre. Dans les deux cas, décidez délibérément : construire à neuf ou mettre à
jour sur place, jamais ajouter aveuglément.
Lier la source à une Table pour que le graphique suive les données
Maintenant le correctif durable du bug des mauvaises données. Parce qu'une série est une référence, un
graphique lié à A1:B13 se fige à treize lignes — ajoutez un mois et le nouveau point est hors du
graphique. Liez plutôt la source à une Table, et la référence grandit avec les données :
' La source du graphique est la plage d'une Table -> les nouvelles lignes apparaissent automatiquement
ch.SetSourceData Source:=Worksheets("Data").ListObjects("tblSales").Range
Quand la source est un ListObject, ajouter une ligne étend la Table, la Table étend la plage que la série
référence, et le graphique se redessine avec le nouveau point — sans code, sans nouveau SetSourceData.
C'est le même geste qui garde un pivot à jour, et c'est pourquoi une
Table est la fondation à bâtir en premier : pointez vos pivots et graphiques dessus
une fois et les deux se mettent à jour tout seuls. Pour livrer un graphique sous forme d'image,
co.Chart.Export "C:\Reports\sales.png" écrit un PNG directement sur le disque.
Comment ExcelMaster aide
Les erreurs de graphique qui atteignent un rapport fini sont discrètes : le deuxième graphique que personne
n'a supprimé, la série qui pointe encore sur la plage du trimestre dernier, les barres qui tracent la
mauvaise colonne parce que SetSourceData a reçu un bloc qui avait bougé. Chacune s'affiche proprement —
elle montre juste la mauvaise image.
ExcelMaster construit les graphiques
comme quelqu'un qui s'est brûlé aux trois. Demandez-lui de « tracer les ventes mensuelles par région », et
il efface les anciens ChartObjects avant de dessiner, lie la source à une Table pour que les nouvelles
lignes apparaissent d'elles-mêmes, utilise SetSourceData pour tout le bloc au lieu de câbler les séries à
la main, et formate via co.Chart au lieu de trébucher sur la scission cadre/graphique. Vous décrivez
l'image voulue ; il câble la référence pour que le graphique continue de dire la vérité à mesure que les
données grandissent.
Questions fréquentes
Comment créer un graphique en VBA ?
Ajoutez un graphique incorporé avec ChartObjects.Add, puis réglez son type et ses données via .Chart :
Set co = ws.ChartObjects.Add(300, 20, 420, 260), Set ch = co.Chart,
ch.ChartType = xlColumnClustered, ch.SetSourceData Source:=Range("A1:B13"). Le ChartObject est le
cadre et son .Chart est le graphique que vous formatez. SetSourceData lie toute la plage en un seul
appel.
Pourquoi mon graphique VBA trace-t-il les mauvaises données ?
Parce qu'un graphique tient une référence à une plage, pas une copie — le .Values de chaque série est
une formule comme =Sheet1!$B$2:$B$13. Si les données bougent, que des lignes sont insérées, ou que la
source est reconstruite ailleurs, la référence pointe toujours sur les anciennes cellules et le graphique
les dessine. Reliez à nouveau avec SetSourceData, ou pointez la source sur une Table pour que la référence
suive les données.
Quelle est la différence entre ChartObjects et Charts en VBA ?
ChartObjects est la collection des graphiques incorporés d'une feuille, qui flottent sur la feuille ;
chaque ChartObject est un cadre dont le .Chart est le graphique réel. Charts est la collection des
feuilles de graphique du classeur — des onglets qui ne sont rien d'autre qu'un graphique. Aller chercher
Charts(1) quand votre graphique est incorporé déclenche une erreur ; utilisez plutôt
ws.ChartObjects(1).Chart.
Comment ajouter une série à un graphique en VBA ?
Utilisez SeriesCollection.NewSeries, puis réglez ses parties : Set s = ch.SeriesCollection.NewSeries,
s.Name = "2026", s.XValues = Range("A2:A13"), s.Values = Range("B2:B13"). Ajoutez-en d'autres avec un
autre NewSeries ; retirez-en une avec ch.SeriesCollection(2).Delete. Pour un graphique simple,
SetSourceData sur toute la plage est plus facile que d'ajouter les séries à la main.
Comment empêcher VBA de créer des graphiques en double ?
ChartObjects.Add ajoute toujours un nouveau graphique, donc réexécuter une macro empile des copies. Avant
de construire, supprimez les existants : For Each co In ws.ChartObjects: co.Delete: Next co. Si vous voulez
garder et rafraîchir un graphique précis, nommez-le (co.Name = "chtSales"), retrouvez-le par ce nom à
l'exécution suivante, et rappelez SetSourceData au lieu d'ajouter un nouveau cadre.
Testé dans
Testé dans : Excel 365 (Windows 11), VBA 7.1 — vérifié le 02/09/2026.
Guides connexes : VBA Pivot Table · VBA Table · VBA Range · VBA Collection · VBA Worksheet
