Macro pour changer les dates de reférence d'un graph

matthieu_2b

Nouveau membre
Bonjour à tous,

Je suis débutant sur vba et les macros, mais je dois (dans le cadre d'un stage), faire une macro qui m'a l'air complexe pour moi...

J'ai déjà chercher dans les anciens messages du forum mais je n'ai hélas rien trouvé

Le problème est le suivant:

J'ai une feuille excel avec beaucoup de graphs et les données associées à ces graphs en dessous. Je dois faire une macro pour me permettre d'afficher ces graphiques que pour une certaine période ( j'ai des donnés pour les 10 dernieres années). Il faudrait donc qu'en mettant la date du début et de fin de la période qui m'interresse, le graphique se redimmensionne en n'affichant que la période qui m'interesse.

Je ne sais pas si j'ai été très clair, mais j'ai vraiment besoin d'aide.

Merci d'avance

Matthieu
 

zeb

Modérateur
Salut,

Si tu es en stage, c'est que tu y es pour apprendre. Je ne vais donc pas te donner la solution. Mais je vais t'aider à la trouver.

T'es d'accord ?

Alors, à l'aide de l'enregistreur de macro, crée un petit graphe sur des données de test. Vois-tu dans le code produit par l'enregistreur où se situe l'affectation des données ? C'est en te servant de cette méthode que tu pourras restreindre l'étendue des données de tes graphes.

Publie ici (relis bien le règlement pour ne pas commettre d'impair ;) ) le code obtenu, qu'on s'en serve comme support.
 

matthieu_2b

Nouveau membre
Bonjour Zeb,

Je crois que tu as (hélas) un peu raison, j'ai donc fait ce que tu m'as dit et j'obtiens le code suivant:

Code:
 Range("A12:N13").Select
    ActiveSheet.Shapes.AddChart.Select
    ActiveChart.SetSourceData Source:=Range("'Sheet1'!$A$12:$N$13")
    ActiveChart.ChartType = xlLine

J'avais essayer hier quelque chose d'autre en enregistrant une macro oú je changeais la source du graphique et après j'ai regardé ce que cela donnait... Mais le truc que je n'arrive vraiement pas à comprendre c'est comment faire pour que, en entrant une date, la macro aille chercher cette date sur la ligne des dates et commence à partir de cette date....

Merci d'avance



 

zeb

Modérateur
Alors d'après ton code, il faut référencer un graphique et lui appliquer la méthode SetSourceData(). Bon, personnellement, plutôt que de les pointer à la souris et de laisser le système faie sur l'objet actif, je préfère être plus précis. Seulement, il faut connaître le nom de chaque graphique.

Code:
Worksheets("Sheet1").ChartObjets("Graphique 1").Chart.SetSourceData Source:=Range("'Sheet1'!A12:N13")

Comment, tu ne connais pas le nom de tous tes graphiques ?
En voici la liste :
Code:
Dim co As ChartObject
Dim s  As String

s = "La liste des graphique de la feuille 1"
For Each co In Worksheets(1).ChartObjects
    s = s & vbCrLf & " * " & co.Name
Next
MsgBox s

Code:
zone = "A12:N13"
Worksheets("Sheet1").ChartObjets("Graphique 1").Chart.SetSourceData Source:=Range("'Sheet1'!" & zone)

Bon, donc en fait, il juste faut fabriquer la chaîne zone.
Pour cela, il suffit de parcourir tes données...

T'as une idée de comment faire ?
 

matthieu_2b

Nouveau membre
Bonjour,

Désole de ma réponse tardive mais c'était la folie au bureau!
Merci beaucoup de ta réponse, j'ai regardé comment faire mais en faite je crois que je comprend pas très bien l'histoire des noms de graphiques.... Donc forcement je ne vois pas non plus comment faire pour la chaine zone.

Parce que effectivement, ce que je veux créer c'est pour ne pas avoir à pointer la souris.

Mais dans l'ensemble, j'avoue que je suis totalement perdu...

 

zeb

Modérateur
Oki. Pour me suivre, pars d'un classeur vide. Exécute le code La liste des graphique. Tu obtiens exactement rien. C'est normal :spamafote:

Bon, maintenant, écris un peu de données dans le premier onglet, et crée un graphique basé sur ces données dans cet onglet. Réexécute le code La liste des graphique. Tu obtiens un nom de graphique que tu n'as pourtant pas donné explicitement.

Donc première difficulté, soit se servir des noms qu'Excel donne à ses graphiques, soit décider nous-même de ces noms.

Comprends-tu ce premier problème ?
 

matthieu_2b

Nouveau membre
ok, quand j'excute cette macro, excel m'envoie un message avec la liste des graphiques de la feuille. Effectivement, il donne des noms que je n'ai pas du tout mis.

Il faudrait donc qu'à un moment donné il me demande le nom du graphique que je veux transformer pour au'il aille choisire les bonnes données ou quelque chose comme ca?
 

zeb

Modérateur
Ah... En voilà un qui à tout compris ! :D

Donc maintenant, il va falloir identifier quel(s) graphique(s) tu veux changer.
Moi, je serais partisan d'imposer des noms explicites à chaque graphe.

Voilà comment l'enregistreur de macro voit la création d'un graphe tout bête :
Code:
Charts.Add
ActiveChart.ChartType = xlColumnClustered
ActiveChart.SetSourceData Source:=Sheets("Feuil1").Range("A12:N13"), PlotBy:=xlRows
ActiveChart.Location Where:=xlLocationAsObject, Name:="Feuil1"
Le revoilà à faire confiance au fait qu'un objet plutôt qu'un autre est actif. (Il m'énerve cet enregistreur de macro :fou: )
Code:
Dim ch As Chart
Set ch = Charts.Add
ch.ChartType = xlColumnClustered
ch.SetSourceData Source:=Sheets("Feuil1").Range("A12:N13"), PlotBy:=xlRows
ch.Location Where:=xlLocationAsObject, Name:="Feuil1"
J'utilise une variable - C'est quand même plus "informatique" - que j'initialise au moment de la création.
J'exécute ce code pas-à-pas. Et je m'aperçois qu'il fabrique un onglet de type Chart et qu'à la ligne 5, il transforme mon onglet en objet de feuille :pfff:

On va réécrire tout ça, avec un objet ChartObjet, directement !
Code:
Dim sh As Worksheet
Dim co As ChartObject

Set sh = Worksheets(1)

Set co = sh.ChartObjects.Add(100, 100, 200, 100)
co.Name = "Un graphe pour Matthieu"
co.Chart.ChartType = xlColumnClustered
co.Chart.SetSourceData Source:=sh.Range("A12:N13"), PlotBy:=xlRows
Ah, c'est pas mal hein ? Et surtout, on a nommé nous même notre graphe. Comme ça, on peut changer la plage des données facilement :

Code:
Dim sh As Worksheet
Dim co As ChartObject

Set sh = Worksheets(1)

Set co = sh.ChartObjects("Un graphe pour Matthieu")
co.Chart.SetSourceData Source:=sh.Range("A12:B13")

Et voilà :bounce:

------------------------------------

Bon, évidemment, il faut avoir nommé soi-même ses graphes à la création, d'une part, et surtout, il faut avoir des noms uniques. :spamafote:

Or, donc, comment nommé ses graphes quand ils sont déjà créés ?
Voià une question intéressante.

Je te laisse chercher un peu. Tu as presque tous les éléments. Il faut :
■ Savoir parcourir tous les graphes (cf. La liste des graphique de la feuille 1)
■ Savoir en sélectionner un (l'enregistreur t'a montré comment faire)
■ Savoir afficher le nom actuel du graphe
■ Savoir demander à l'utilisateur d'en changer (ah, j'ai encore des choses à t'apprendre si tu ne sais pas te débrouiller ;) )

Quand tu sauras faire ça, il restera à gérer les dates et tu auras trouvé une solution à ton problème de départ.
 

matthieu_2b

Nouveau membre
Alors quand j'excute ma nouvelle macro, je commencé par mettre la liste des graphes mais il me les affiche pas tous... (6 au lieu de 25).

Mon problème c'est que je n'arrive pas a selectionner un graphique particulier pour en chager le nom, je n'arrive pas à comprendre comment faire pour qu'il m'affiche le nom de tel ou tel graphique... Bref j'arrive pas a grand chose, je pense comprendre le raisonement mais je suis très loin de réussir a le traduire en VBA


 

matthieu_2b

Nouveau membre
Alors je commence par tenter d'afficher la liste des graphs:

Code:
Dim co As ChartObject
    Dim s  As String
    
    s = "La liste des graphique de la feuille 1"
    For Each co In Worksheets(1).ChartObjects
        s = s & vbCrLf & " * " & co.Name
    Next
    MsgBox s

Donc la il m'affiche certains graphs, et après j'essaye de d'en nommer un mais je suis pas sur de comprendre très bien le code sur leque je m'appuie:

Code:
    Set co = sh.ChartObjects.Add(100, 100, 200, 100)
    co.Name = "Un graphe pour Matthieu"
    co.Chart.ChartType = xlColumnClustered
    co.Chart.SetSourceData Source:=sh.Range("A12:N13"), PlotBy:=xlRows

Est ce qu'il nomme "un graph pour Matthieu" le graphe qui a comme source "A12:N13" ? Et à quoi sert la ligne Add100, 100,200,100?

La j'ai l'impression qu'avec mon code il me donne une liste de graph puis me creer un graph à chaque fois basé sur A12:N13...
 

zeb

Modérateur
Ohlala !!!!
Il ne faut pas exécuter bêtement les codes que je te propose, il faut les étudier et les comprendre !!!!

Ton nouvel ami est la touche F1.

Alors tu vas te balader sur chacun des mots de ton code, et tu vas appuyer sur F1.
Quand je le fais pour Add par exemple, j'obtiens :

_______________________________________________________________
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯​

Méthode Add telle qu'elle s'applique à l'objet ChartObjects.

Cette méthode crée un graphique incorporé. Elle renvoie un objet ChartObject.

[fixed]expression.Add(Left, Top, Width, Height)[/fixed]

expression Obligatoire. Expression qui renvoie un objet ChartObjects.

Left, Top Argument de type Double obligatoire. Coordonnées initiales du nouvel objet (en points), par rapport au coin supérieur gauche de la cellule A1 d'une feuille de calcul ou du coin supérieur gauche d'un graphique.

Width, Height Argument de type Double obligatoire. Taille initiale du nouvel objet, en points.

_______________________________________________________________
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯​

A cette très enrichissante lecture, je me dis que ce n'est pas la méthode Add qu'il faut utiliser. N'est-ce pas ?

Je reprends :
1°) parcourir tous les graphes
2°) en sélectionner un
3°) afficher le nom actuel du graphe
4°) demander à l'utilisateur d'en changer

Code:
Dim co  As ChartObject
Dim nom As String

' // Parcourir tous les graphiques de la feuille 1
For Each co In Worksheets(1).ChartObjects
    ' // En sélectionner un :
    co.Activate
    co.Chart.ChartArea.Select

    ' // Afficher son nom
    If MsgBox("Voulez-vous changer le nom du graphique " & co.Name & " ?", _
              vbQuestion Or vbYesNo, "Graphique") = vbYes Then
        ' // Oui, il veut !
        nom = InputBox("Nouveau nom")
        
        ' // Si quelque chose a été saisi et que l'utilisateur n'a pas annulé...
        If nom <> "" Then
            ' // ... On change le nom
            co.Name = nom
        End If
    End If
Next

A étudier :o
 

matthieu_2b

Nouveau membre
Alleluia, ca marche!!

Je crois comprendre à peu près comment le code marche, j'ai rajouté une partie pour qu'il m'affiche d'abord le nom de tous les graphes présent.

Il faut maintenant que je fasse un code pour choisir le graphique que je veux renommer, sinon avec la boucle "for", il me redemande à chaque fois de tous les renommer...

Je pensais donc faire avec un "If", tel ou tel graph est activé alors le code me demande de changer el nom de ce graph.

Code:
    MsgBox ("Selectionnez un graph")
    ActiveSheet.ChartObjects("Chart 3 ").Activate
    ActiveChart.SeriesCollection(1).Select
    
    If co("Chart 3 ").ChartObjects = Activate Then
        co.Activate
        co.Chart.ChartArea.Select

Et je continue avec le code précedent, mais j'ai un probleme avec mon if et avec le fait qu j'arrive pas a selctionner le graph que je veux autrement que en mettant son nom dans le code...
 

zeb

Modérateur
:pfff:

Voila comment on fait pour être sûr de ce qui est sélectionné ou pas. Ensuite, on peut travailler dessus :

Code:
Dim co As ChartObject

If TypeOf Selection Is ChartObject Then
    Set co = Selection
ElseIf TypeOf Selection Is ChartArea Or _
       TypeOf Selection Is Axis Or _
       TypeOf Selection Is Legend Or _
       TypeOf Selection Is PlotArea Then
    Set co = Selection.Parent.Parent
ElseIf TypeOf Selection Is Gridlines Or _
       TypeOf Selection Is Series Or _
       TypeOf Selection Is AxisTitle Then
    Set co = Selection.Parent.Parent.Parent
ElseIf TypeOf Selection Is DataLabels Then
    Set co = Selection.Parent.Parent.Parent.Parent
Else
    MsgBox "Vous avez sélectionné un '" & TypeName(Selection) & "', qui n'est pas (encore) pris en compte"
    Exit Sub
End If
co.Activate
co.Chart.ChartArea.Select
MsgBox "L'objet sélectionné est '" & o.Name & "'" & vbCr & " (en fait, c'est la zone de chart du chart de l'objet)"
 

matthieu_2b

Nouveau membre
Bonjour,

Merci encore une fois de ta réponse,

Je ne comprends pas trés bien ton dernier code: ce que je crois comprendre c'est qu'avant de l'excuter je clique sur un objet et si c'est un graph il me donne le non de ce graph. Cependant, quand je l'execute, il y a un problème au niveau de la ligne 20, il me dit que la variable n'est pas "set" alors que j'ai l'impression qu'elle l'est en ligne 4.

 

zeb

Modérateur
Salut,

En fait, quand tu cliques sur un graphe pour le sélectionner, tu n'es pas sûr de l'objet exact sur lequel tu es. Est-ce le graphe, l'objet conteneur du graphe, la zone de dessin du graphe, le titre, etc.

D'où la succession de tests et de Sets pour choisir le bon objet.

Il y avait une petite coquille dans mon code, j'avais écrit xo pour co. C'est mal. J'ai corrigé.
Mais il y a pire. Tu n'as pas utilisé l'option explicit, ce qui t'aurait permis de t'en apercevoir toi-même !!!! C'est très mal. Alors, utilise-la.

--------------

Ça y est ? Tu peux renommer tes graphes, et changer leurs données comme tu l'entends ?
 

matthieu_2b

Nouveau membre
Bonjour,

Je me suis focalisé sur la ligne 20 pour comprendre ce qui aller pas et je ne suis pas aller plus haut :whistle:

Donc maintenant je peux renomer mes graphes, ce qui me semble pas mal du tout. J'ai rajouté quelque chose pour que si je ne change pas le nom il continue quand meme.

Après, je rajoute une ligne pour demander a l'utilisateur s'il veut changer la source, puis une ligne pour changer la source.

On en arrive donc au deuxieme problème, comment faire pour que je décide des dates, sans rentrer dans le code.

Mon deuxieme probleme est que j'ai une série de date, et en dessous j'ai toutes les données, il faut donc que mon graphes prennent les bonnes données.

Je me disais de peut etre essayer de demander a l'utilisateur de mettre un "range" pour les données que la macro irait rechercher avec le "setcourcedate". Ca serait une premiere étape pour ensuite n'avoir qu'à rentrer les dates et que ma macro aille chercher les données.
 

zeb

Modérateur
Bon. On a donc un nom explicite pour chaque graphe.
Et le graphe "grafdaté" peut changer en fonction des dates.

Bon. Ben voilà :
Code:
Dim plage As Range
Worksheets(1).ChartObjets("grafdaté").Chart.SetSourceData Source:=plage

Y'a plus qu'à alimenter la zone plage. Facile :

Code:
plage = vide
Pour toutes les cellules concernées,
Si date est correcte Alors  plage = plage + cellule

Code:
For Each cell In Range("A1:E1")
    If cell.Column <> 3 Then
        Set plage = Union(zone, cell)
    End If
Next

Bon, la fonction Union() n'est pas fichue de traiter des arguments vides. C'est nul. Donc on le gère :
Code:
For Each cell In Range("A1:E1")
    If cell.Column <> 3 Then
        If plage Is Nothing Then
            Set plage = cell
        Else
            Set plage = Union(plage, cell)
        End
    End If
Next
Bon, ma condition c'est que je n'aime pas les colonnes 3.
Toi, c'est un problème de choix dans la date.

Tu vois ce qui te reste à faire ?
 

matthieu_2b

Nouveau membre
Bonjour,

J'aime beaucoup ta contrepétrie de mon probléme de "choix dans la date" mais par contre je ne comprend pas trés bien ce que fait ce programme, donc je vois pas trop ce que je dois faire avec...

 

zeb

Modérateur
Pour remplir la variable plage, je parcours la zone "A1:E1", et je prends toutes les cellules qui ne sont pas dans la colonne 3.

Toi, tu dois parcourir la zone ?????, et tu dois prendre toutes les cellules qui correspondent ????? à telle période.

Comme je ne connais pas l'organisation de ton fichier, je te laisse le faire.
(De toute façon, je préfère que tu le fasses toi-même).

Vois-tu un peu mieux ce que tu as à faire ?
 
Vous devez vous inscrire ou vous connecter pour répondre ici.
Derniers messages publiés
Statistiques globales
Discussions
730 098
Messages
6 717 065
Membres
1 586 286
Dernier membre
petitangebleu1977
Partager cette page
Haut