Se connecter avec
S'enregistrer | Connectez-vous

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

Dernière réponse : dans Programmation

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) :

  1. 'Ajout de graphique en renommant la feuille avec un nom fixe
  2. '(car variables non acceptées dans la syntaxe de localisation d'un graphique)
  3. 'et sauvegarde du nom de la feuille dans une variable pour le lui réattribuer ensuite
  4. SauvegardeNomFeuille = ActiveSheet.Name
  5. ActiveSheet.Name = "Feuille active"
  6. DerniereLigne = Range("A65536").End(xlUp).Row
  7. Range("A1:C" & DerniereLigne).Select
  8. Charts.Add
  9. ActiveChart.ChartType = xlLine
  10. ActiveChart.SetSourceData Source:=Sheets("Feuille active").Range("A1:C" & DerniereLigne), PlotBy:= _
  11. xlColumns
  12. ActiveChart.SeriesCollection(2).Name = "=""OI dans tâches en cours"""
  13. ActiveChart.SeriesCollection(1).Name = "=""OI dans tâches en cours à J0"""
  14.  
  15. ActiveChart.Location Where:=xlLocationAsObject, Name:="Feuille active"
  16. With ActiveChart.Axes(xlValue)
  17. .HasMajorGridlines = True
  18. .HasMinorGridlines = False
  19. End With
  20. With ActiveChart
  21. .HasTitle = True
  22. .ChartTitle.Characters.Text = "OI" & " " & SauvegardeNomFeuille & " " & "le" & " " & Aujourdhui
  23. End With
  24.  
  25. 'MISE EN FORME DU GRAPHIQUE DE FACON A LE CASER DANS LA FEUILLE "Graphiques charge" :
  26.  
  27. '1- TAILLE DU GRAPHIQUE ENTIER :
  28. ActiveChart.ChartArea.Select
  29. ActiveSheet.Shapes("Graphique 1").ScaleWidth 0.84, msoFalse, _
  30. msoScaleFromTopLeft
  31. ActiveSheet.Shapes("Graphique 1").ScaleHeight 0.57, msoFalse, _
  32. msoScaleFromTopLeft
  33.  
  34. '2- TAILLE DE LA ZONE GRAPHIQUE :
  35. ActiveChart.PlotArea.Select
  36. Selection.Width = 270
  37. Selection.Height = 110
  38. Selection.Top = 12
  39. ActiveChart.ChartArea.Select
  40.  
  41. '3- POLICE DES DATES EN ABSCISSE :
  42. ActiveChart.Axes(xlCategory).Select
  43. Selection.TickLabels.AutoScaleFont = True
  44. With Selection.TickLabels.Font
  45. .Name = "Arial"
  46. .FontStyle = "Normal"
  47. .Size = 5
  48. End With
  49.  
  50. '4- POLICE DES NOMBRES EN ORDONNEE :
  51. ActiveChart.Axes(xlValue).Select
  52. Selection.TickLabels.AutoScaleFont = True
  53. With Selection.TickLabels.Font
  54. .Name = "Arial"
  55. .FontStyle = "Normal"
  56. .Size = 5
  57. End With
  58.  
  59. '5- POLICE DU TITRE DU GRAPHIQUE :
  60. ActiveChart.ChartTitle.Select
  61. Selection.AutoScaleFont = True
  62. With Selection.Font
  63. .Name = "Arial"
  64. .FontStyle = "Gras"
  65. .Size = 6
  66. End With
  67. ActiveChart.ChartArea.Select
  68.  
  69. '6- COPIE-COLLAGE DU GRAPHIQUE CREE DANS LA FEUILLE "Graphiques charge" :
  70. ActiveSheet.ChartObjects("Graphique 1").Activate
  71. ActiveChart.ChartArea.Select
  72. ActiveChart.ChartArea.Copy
  73. ActiveWindow.Visible = False
  74. Windows("Courbes OI.xls").Activate
  75. Sheets("Graphiques charge").Select
  76.  
  77. '6- a) Recherche de l'endroit où coller le nouveau graphique
  78. Cells.Find(What:="<Zone collage nouveau graphique>", After:=ActiveCell, LookIn:=xlFormulas, LookAt _
  79. :=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:= _
  80. False).Activate
  81. LigneZoneCollage = ActiveCell.Row
  82. ColZoneCollage = ActiveCell.Column
  83.  
  84. '6- b) Collage du nouveau graphique
  85. ActiveSheet.Paste
  86. Windows("Courbes OI.xls").Activate
  87.  
  88. '6- c) Déplacement du marqueur de zone de collage, pour le prochain graphique
  89. Cells(LigneZoneCollage, ColZoneCollage).Formula = ""
  90. If ColZoneCollage >= 15 Then
  91. Cells(LigneZoneCollage + 10, 1).Formula = "<Zone collage nouveau graphique>"
  92. Else
  93. Cells(LigneZoneCollage, ColZoneCollage + 5).Formula = "<Zone collage nouveau graphique>"
  94. End If
  95.  
  96. '7- RE-AGRANDISSEMENT DU GRAPHIQUE DE LA FEUILLE D'ORIGINE (POUR LISIBILITE) :
  97. Sheets("Feuille active").Select
  98. Charts("Graphique1").Activate
  99.  
  100. '7- 1- TAILLE DU GRAPHIQUE ENTIER :
  101. ActiveChart.ChartArea.Select
  102. ActiveSheet.Shapes("Graphique 1").ScaleWidth 2.1, msoFalse, _
  103. msoScaleFromTopLeft
  104. ActiveSheet.Shapes("Graphique 1").ScaleHeight 1.8, msoFalse, _
  105. msoScaleFromTopLeft
  106.  
  107. '7- 2- TAILLE DE LA ZONE GRAPHIQUE :
  108. ActiveChart.PlotArea.Select
  109. Selection.Width = 270
  110. Selection.Height = 110
  111. Selection.Top = 12
  112. ActiveChart.ChartArea.Select
  113.  
  114. '7- 3- POLICE DES DATES EN ABSCISSE :
  115. ActiveChart.Axes(xlCategory).Select
  116. Selection.TickLabels.AutoScaleFont = True
  117. With Selection.TickLabels.Font
  118. .Name = "Arial"
  119. .FontStyle = "Normal"
  120. .Size = 10
  121. End With
  122.  
  123. '7- 4- POLICE DES NOMBRES D'OI EN ORDONNEE :
  124. ActiveChart.Axes(xlValue).Select
  125. Selection.TickLabels.AutoScaleFont = True
  126. With Selection.TickLabels.Font
  127. .Name = "Arial"
  128. .FontStyle = "Normal"
  129. .Size = 10
  130. End With
  131.  
  132. '7- 5- POLICE DU TITRE DU GRAPHIQUE :
  133. ActiveChart.ChartTitle.Select
  134. Selection.AutoScaleFont = True
  135. With Selection.Font
  136. .Name = "Arial"
  137. .FontStyle = "Gras"
  138. .Size = 12
  139. End With
  140. ActiveChart.ChartArea.Select
  141.  
  142. '8- REATTRIBUTION A LA FEUILLE DE SON NOM D'ORIGINE
  143. ActiveSheet.Name = SauvegardeNomFeuille


Merci d'avance pour votre aide

Autres pages sur : fonctionne bien mal lancement

Lassé par la pub ? Créez un compte

Meilleure solution

Expert Programmation

  1. ' // Ajout de graphique en renommant la feuille avec un nom fixe
  2. ' // (car variables non acceptées dans la syntaxe de localisation d'un graphique)
  3. ' // 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 ;) 

  1. DerniereLigne = Range("A65536").End(xlUp).Row
  2. Range("A1:C" & DerniereLigne).Select
  3. Charts.Add
  4. ActiveChart.ChartType = xlLine
  5. 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.
  1. Dim mafeuille As Worksheet
  2. Dim cellule_1er As Range
  3. Dim cellule_Der As Range
  4. Dim plage_source As Range
  5.  
  6. Set mafeuille = ActiveSheet ' // Là, une fois, t'as le droit, tout au début, de considérer la feuille active.
  7. Set cellule_1er = mafeuille.Range("A1")
  8. Set cellule_Der = mafeuille.Range("A65536").End(xlUp) ' // On est en colonne A
  9. Set cellule_Der = cellule_Der.Offset(0, 2) ' // On se décale de deux colonnes : C
  10. Set plage_source = mafeuille.Range(cellule_1er, cellule_Der)
  11.  
  12. Set newchart = Charts.Add
  13. newchart.ChartType = xlLine
  14. newchart.SetSourceData Source:=plage_source, PlotBy:= xlColumns
Bon, c'est bien pour bien comprendre, mais c'est un peu lourd. A étudier. Ecrire :
  1. Dim mafeuille As Worksheet
  2.  
  3. Set mafeuille = ActiveSheet ' // Là, une fois, t'as le droit, tout au début, de considérer la feuille active.
  4.  
  5. Set newchart = Charts.Add
  6. newchart.ChartType = xlLine
  7. 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 :
  1. 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 !
  1. Dim mongraph As ChartObject
  2. Dim dergraphnum As Integer
  3. dergraphnum = mafeuille.ChartObjects.Count
  4. Set mongraph = mafeuille.ChartObjects(dergraphnum)
En plus concis :
  1. Dim mongraph As ChartObject
  2. Set mongraph = mafeuille.ChartObjects(mafeuille.ChartObjects.Count)


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


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


etc.
Expert Programmation

Salut et bienvenue.

Citation :
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
Citation :
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]

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

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... (?)
Expert Programmation

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.

  1. Range("A" & 12-13+1*2).Value = 10
  2. Range("A" & 12-13+1*2).Interior.ColorIndex = 6
  3. Range("A" & 12-13+1*2).Interior.Pattern = xlSolid
  4. 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 :
  1. With Range("A" & 12-13+1*2)
  2. .Value = 10
  3. With .Interior
  4. .ColorIndex = 6
  5. .Pattern = xlSolid
  6. End With
  7. .Font.ColorIndex = 33
  8. End With
Lassé par la pub ? Créez un compte