Résolu Fonctionne bien en pas-à-pas, mais mal au lancement !!

  • Auteur de la discussion PoeticBeauf
  • Date de début

PoeticBeauf

Nouveau membre
Bonjour
Je dois faire une macro Excel pour le boulot. Je débute en programmation donc ce n'est pas toujours facile, mais jusque-là j'ai pu me débrouiller grâce à des sites et forums comme celui-ci. En revanche, là je suis totalement perplexe et je ne trouve rien.

Dans la macro, il y a la création de graphiques dans des feuilles (contenant les données-sources) ; cette insertion de graphiques est mise dans une boucle faisant défiler les feuilles.
En outre, tous ces graphiques créés dans des feuilles différentes, je dois les rassembler de manière présentable dans une autre feuille (la feuille "Graphiques charge").
Pour ce faire, j'ai donc redimensionné les graphiques dans leur feuille d'origine, avant de les copier/coller dans "Graphiques charge", puis ré-agrandi le graphique dans la feuille d'origine. C'est lourd mais ça m'est paru plus simple que de les redimensionner directement dans la feuille "Graphiques charge" (problèmes pour la désignation du graphe à modifier, etc).

A l'exécution de la macro, tout va bien sauf la taille des cadres de graphiques, autant dans leur feuille d'origine que dans la feuille "Graphiques charge". Ils sont toujours de la taille à laquelle ils sont apparus à leur création "brute".
(Dans la mise en forme des graphiques, il y a aussi des modifs de police etc, et ça ça marche...)

Mais ce qui est incompréhensible, c'est quand je scrute chaque étape en les faisant défiler pas à pas (F8)... Ca marche parfaitement !! Les graphiques changent de largeur, de hauteur, exactement comme je le veux

Du coup je me demande, c'est possible que pour ce genre de commande il faille à l'ordi un petit temps entre chaque action ?
(Je précise que j'ai désactivé l'affichage de l'exécution avec un Application.ScreenUpdating = False en début de macro)

Autre détail : dans un premier temps, je n'avais pas commandé de remise en forme du graphique dans sa feuille d'origine après qu'il ait été copiécollé dans "Graphiques charge" ; et ça marchait, les graphiques avaient la bonne taille dans la feuille "Graphiques charge"

Voici le code de cette partie de la macro (c'est sûrement très sale mais soyez indulgents, je débute) :

Code:
     'Ajout de graphique en renommant la feuille avec un nom fixe
     '(car variables non acceptées dans la syntaxe de localisation d'un graphique)
     'et sauvegarde du nom de la feuille dans une variable pour le lui réattribuer ensuite
       SauvegardeNomFeuille = ActiveSheet.Name
       ActiveSheet.Name = "Feuille active"
       DerniereLigne = Range("A65536").End(xlUp).Row
       Range("A1:C" & DerniereLigne).Select
       Charts.Add
       ActiveChart.ChartType = xlLine
       ActiveChart.SetSourceData Source:=Sheets("Feuille active").Range("A1:C" & DerniereLigne), PlotBy:= _
          xlColumns
       ActiveChart.SeriesCollection(2).Name = "=""OI dans tâches en cours"""
       ActiveChart.SeriesCollection(1).Name = "=""OI dans tâches en cours à J0"""

       ActiveChart.Location Where:=xlLocationAsObject, Name:="Feuille active"
       With ActiveChart.Axes(xlValue)
          .HasMajorGridlines = True
          .HasMinorGridlines = False
       End With
       With ActiveChart
          .HasTitle = True
          .ChartTitle.Characters.Text = "OI" & " " & SauvegardeNomFeuille & " " & "le" & " " & Aujourdhui
       End With
    
     'MISE EN FORME DU GRAPHIQUE DE FACON A LE CASER DANS LA FEUILLE "Graphiques charge" :
     
     '1- TAILLE DU GRAPHIQUE ENTIER :
       ActiveChart.ChartArea.Select
       ActiveSheet.Shapes("Graphique 1").ScaleWidth 0.84, msoFalse, _
          msoScaleFromTopLeft
       ActiveSheet.Shapes("Graphique 1").ScaleHeight 0.57, msoFalse, _
          msoScaleFromTopLeft
     
     '2- TAILLE DE LA ZONE GRAPHIQUE :
       ActiveChart.PlotArea.Select
       Selection.Width = 270
       Selection.Height = 110
       Selection.Top = 12
       ActiveChart.ChartArea.Select
     
     '3- POLICE DES DATES EN ABSCISSE :
       ActiveChart.Axes(xlCategory).Select
       Selection.TickLabels.AutoScaleFont = True
       With Selection.TickLabels.Font
          .Name = "Arial"
          .FontStyle = "Normal"
          .Size = 5
       End With
     
     '4- POLICE DES NOMBRES EN ORDONNEE :
       ActiveChart.Axes(xlValue).Select
       Selection.TickLabels.AutoScaleFont = True
       With Selection.TickLabels.Font
          .Name = "Arial"
          .FontStyle = "Normal"
          .Size = 5
       End With
     
     '5- POLICE DU TITRE DU GRAPHIQUE :
       ActiveChart.ChartTitle.Select
       Selection.AutoScaleFont = True
       With Selection.Font
          .Name = "Arial"
          .FontStyle = "Gras"
          .Size = 6
       End With
       ActiveChart.ChartArea.Select
     
     '6- COPIE-COLLAGE DU GRAPHIQUE CREE DANS LA FEUILLE "Graphiques charge" :
       ActiveSheet.ChartObjects("Graphique 1").Activate
       ActiveChart.ChartArea.Select
       ActiveChart.ChartArea.Copy
       ActiveWindow.Visible = False
       Windows("Courbes OI.xls").Activate
       Sheets("Graphiques charge").Select
     
     '6- a) Recherche de l'endroit où coller le nouveau graphique
       Cells.Find(What:="<Zone collage nouveau graphique>", After:=ActiveCell, LookIn:=xlFormulas, LookAt _
           :=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:= _
           False).Activate
       LigneZoneCollage = ActiveCell.Row
       ColZoneCollage = ActiveCell.Column
     
     '6- b) Collage du nouveau graphique
       ActiveSheet.Paste
       Windows("Courbes OI.xls").Activate
     
     '6- c) Déplacement du marqueur de zone de collage, pour le prochain graphique
       Cells(LigneZoneCollage, ColZoneCollage).Formula = ""
         If ColZoneCollage >= 15 Then
          Cells(LigneZoneCollage + 10, 1).Formula = "<Zone collage nouveau graphique>"
         Else
          Cells(LigneZoneCollage, ColZoneCollage + 5).Formula = "<Zone collage nouveau graphique>"
         End If

     '7- RE-AGRANDISSEMENT DU GRAPHIQUE DE LA FEUILLE D'ORIGINE (POUR LISIBILITE) :
       Sheets("Feuille active").Select
       Charts("Graphique1").Activate
     
     '7- 1- TAILLE DU GRAPHIQUE ENTIER :
       ActiveChart.ChartArea.Select
       ActiveSheet.Shapes("Graphique 1").ScaleWidth 2.1, msoFalse, _
          msoScaleFromTopLeft
       ActiveSheet.Shapes("Graphique 1").ScaleHeight 1.8, msoFalse, _
          msoScaleFromTopLeft
     
     '7- 2- TAILLE DE LA ZONE GRAPHIQUE :
       ActiveChart.PlotArea.Select
       Selection.Width = 270
       Selection.Height = 110
       Selection.Top = 12
       ActiveChart.ChartArea.Select
     
     '7- 3- POLICE DES DATES EN ABSCISSE :
       ActiveChart.Axes(xlCategory).Select
       Selection.TickLabels.AutoScaleFont = True
       With Selection.TickLabels.Font
          .Name = "Arial"
          .FontStyle = "Normal"
          .Size = 10
       End With
     
     '7- 4- POLICE DES NOMBRES D'OI EN ORDONNEE :
       ActiveChart.Axes(xlValue).Select
       Selection.TickLabels.AutoScaleFont = True
       With Selection.TickLabels.Font
          .Name = "Arial"
          .FontStyle = "Normal"
          .Size = 10
       End With
     
     '7- 5- POLICE DU TITRE DU GRAPHIQUE :
       ActiveChart.ChartTitle.Select
       Selection.AutoScaleFont = True
       With Selection.Font
          .Name = "Arial"
          .FontStyle = "Gras"
          .Size = 12
       End With
       ActiveChart.ChartArea.Select

     '8- REATTRIBUTION A LA FEUILLE DE SON NOM D'ORIGINE
       ActiveSheet.Name = SauvegardeNomFeuille

Merci d'avance pour votre aide
 

zeb

Modérateur
Salut et bienvenue.

soyez indulgents, je débute
Aucune indulgence ne te sera accordée si tu oses ne pas respecter le règlement que je t'invite à lire. Tu y apprendras que toute pièce de code doit être présenté avec une autre balise que
que je t'invite à découvrir. De la même manière, cherche, trouve le moyen de modifier ton message pour te montrer respectueux envers ce forum. En contre partie, je parie que tu auras une solution à ton problème
[:zeb:6]
 

PoeticBeauf

Nouveau membre
Ah merci, j'avais effectivement cherché une balise pour que le code soit présentable mais sans trouver.
Après le boulot je passe la soirée et une partie de la nuit sur cette fichue macro, je n'avais pas accordé de temps à la lecture du règlement.
C'est chose faite
 

zeb

Modérateur
Indulgence accordée. :merci:
Je regarde ton problème et je reviens vers toi.
 

zeb

Modérateur
Meilleure réponse
Code:
' // Ajout de graphique en renommant la feuille avec un nom fixe
' // (car variables non acceptées dans la syntaxe de localisation d'un graphique)
' // et sauvegarde du nom de la feuille dans une variable pour le lui réattribuer ensuite

N'importe quoi :pfff: (spa grave, on a arranger ça ;)

Code:
DerniereLigne = Range("A65536").End(xlUp).Row
Range("A1:C" & DerniereLigne).Select
Charts.Add
ActiveChart.ChartType = xlLine
ActiveChart.SetSourceData Source:=Sheets("Feuille active").Range("A1:C" & DerniereLigne), PlotBy:= xlColumns)
Ne fais pas confiance à Excel pour savoir quel objet est actif ou pas.
Code:
Dim mafeuille    As Worksheet
Dim cellule_1er  As Range
Dim cellule_Der  As Range
Dim plage_source As Range

Set mafeuille    = ActiveSheet ' // Là, une fois, t'as le droit, tout au début, de considérer la feuille active.
Set cellule_1er  = mafeuille.Range("A1")
Set cellule_Der  = mafeuille.Range("A65536").End(xlUp) ' // On est en colonne A
Set cellule_Der  = cellule_Der.Offset(0, 2) ' // On se décale de deux colonnes : C
Set plage_source = mafeuille.Range(cellule_1er, cellule_Der)

Set newchart = Charts.Add
newchart.ChartType = xlLine
newchart.SetSourceData Source:=plage_source, PlotBy:= xlColumns
Bon, c'est bien pour bien comprendre, mais c'est un peu lourd. A étudier. Ecrire :
Code:
Dim mafeuille As Worksheet

Set mafeuille    = ActiveSheet ' // Là, une fois, t'as le droit, tout au début, de considérer la feuille active.

Set newchart = Charts.Add
newchart.ChartType = xlLine
newchart.SetSourceData Source:=mafeuille.Range("A1", mafeuille.Range("A65536").End(xlUp).Offset(0, 2)), PlotBy:= xlColumns
C'est suffisamment clair.

M'enfin, ça aussi c'est clair :
Code:
newchart.Location Where:=xlLocationAsObject, Name:=mafeuille.Name
Ah zut, l'objet newchart de type Chart a été détruit, et la méthode Location() ne renvoie pas le nouvel objet de type ChartObject qui vient d'être créé.
Les développeurs du modèle objet du VBA/Excel se sont arrêté en route :/ Il va falloir ruser...

Notre nouvel objet est le dernier des ChartObjects de notre feuille !
Code:
Dim mongraph As ChartObject
Dim dergraphnum As Integer
dergraphnum = mafeuille.ChartObjects.Count
Set mongraph = mafeuille.ChartObjects(dergraphnum)
En plus concis :
Code:
Dim mongraph As ChartObject
Set mongraph = mafeuille.ChartObjects(mafeuille.ChartObjects.Count)

Code:
With ActiveChart.Axes(xlValue)
    .HasMajorGridlines = True
    .HasMinorGridlines = False
End With
With ActiveChart
    .HasTitle = True
    .ChartTitle.Characters.Text = "OI" & " " & SauvegardeNomFeuille & " " & "le" & " " & Aujourdhui
End With
On remplace ActiveTruc par notre variable explicite, et on vire les gros With bien lourds :
Code:
mongraph.Axes(xlValue).HasMajorGridlines = True
mongraph.Axes(xlValue).HasMinorGridlines = False
mongraph.HasTitle = True
mongraph.ChartTitle.Characters.Text = "OI" & " " & mafeuille.Name & " " & "le" & " " & Aujourdhui

Code:
ActiveChart.ChartArea.Select
ActiveSheet.Shapes("Graphique 1").ScaleWidth 0.84, msoFalse, msoScaleFromTopLeft
ActiveSheet.Shapes("Graphique 1").ScaleHeight 0.57, msoFalse, msoScaleFromTopLeft
On continue à utliser notre variable, et on vire les trucs inutiles
Code:
mongraph.ScaleWidth 0.84, msoFalse, msoScaleFromTopLeft
mongraph.ScaleHeight 0.57, msoFalse, msoScaleFromTopLeft

etc.
 

PoeticBeauf

Nouveau membre
Super, merci beaucoup ! Effectivement ça clarifie pas mal le code, et ça marche mieux (mais je ne comprends toujours pas comment c'était possible que ça déconne en exécution automatique, alors qu'en pas à pas il n'y avait aucun souci).
Pas mal le coup du charts.count, je m'en sers à un autre endroit pour les feuilles mais ça ne me serait jamais venu à l'idée pour des objets !
Sinon j'avais lu quelque part que les "With" étaient moins gourmands en temps de calcul que des instructions séparées... (?)
 

zeb

Modérateur
Les With peuvent être intéressants dans certains cas, par exemple quand des calculs amènent à désigner un objet qu'il ne sera pas la peine de recalculer.

Code:
Range("A" & 12-13+1*2).Value = 10
Range("A" & 12-13+1*2).Interior.ColorIndex = 6
Range("A" & 12-13+1*2).Interior.Pattern = xlSolid
Range("A" & 12-13+1*2).Font.ColorIndex = 33
L'opération qui consiste à calculer "A" & 12-13+1*2 est fait 4 fois ! C'est idiot. Un With dans ce cas économise donc un peu de calcul :
Code:
With Range("A" & 12-13+1*2)
    .Value = 10
    With .Interior
        .ColorIndex = 6
        .Pattern = xlSolid
    End With
    .Font.ColorIndex = 33
End With
 
Vous devez vous inscrire ou vous connecter pour répondre ici.
Derniers messages publiés
Statistiques globales
Discussions
730 128
Messages
6 717 839
Membres
1 586 370
Dernier membre
Flo In Groove
Partager cette page
Haut