Je me casse actuellement les dents pour mettre à jour un graphique complexe (avec des couleurs de remplissage "Fill Color") pour lequel je change de plages de données via des macros.
Pour un graphique simple, je n'ai pas de problème en changeant les différentes plages via la propriété "Ranges".
Par contre dès que le diagramme se complexifie (plage pour couleurs de remplissage, titre non contigu), cette façon de procéder ne marche plus et il faut passer par des macros plus élaborées (voir ce sujet où j'en parlais déjà : https://forum.openoffice.org/fr/forum/v ... =8&t=59257).
Je vous joins un fichier reprenant les différentes macros ainsi que les différents diagrammes :
- La première feuille contient les données en ligne à traiter
- La deuxième contient un graphique simple que j'actualise en fonction d'une date de début et d"une date de fin, via une première macro qui ne pose pas de problème : tout fonctionne correctement
- La troisième feuille est un graphique complexe obtenu manuellement.
- La quatrième feuille reprend la structure du troisième graphique mais je veux modifier les plages de données en fonction d'une date de début et d'une date de fin : il y a 2 macros associées (la première ne fonctionnant pas et la seconde non plus sauf si on ne change pas les catégories avec la propriétés "Ranges" (le code est commenté).
Code : Tout sélectionner
REM ***** BASIC *****
Sub MAJHistogrammeJourEcole 'Macro fonctionnant très bien
'Macro permettant de mettre à jour le graphique du taux de présences journalier
' en fonction des dates de début et de fin d'observation
monClasseur=thisComponent
fData=monClasseur.Sheets.getByName("Recueil Stats")
nomEcole=fData.getCellRangeByName("A4").String
fGraphique=monClasseur.Sheets.getByName("Histogramme Journées École")
dateDeb=fGraphique.getCellRangeByName("B1").String
dateFin=fGraphique.getCellRangeByName("F1").String
premiereColonneDates=fGraphique.getCellRangeByName("D1").Value
derniereColonneDates=fGraphique.getCellRangeByName("H1").Value
ch1=fGraphique.Charts(0)
plages1=ch1.getRanges
plageDates=plages1(0)
plageDates.StartColumn=premiereColonneDates
plageDates.EndColumn=derniereColonneDates
plages1(0)=plageDates
plageNom=plages1(1)
plageValeurs=plages1(2)
plageValeurs.StartColumn=premiereColonneDates
plageValeurs.EndColumn=derniereColonneDates
plages1(2)=plageValeurs
ch1.setRanges(plages1())
diag1=fGraphique.Charts(0).EmbeddedObject
diag1.Title.String= "Taux de présence journalier de l'école " & nomEcole & " du " & dateDeb & " au " & dateFin
'xray diag1
End Sub
Sub MAJHistogrammeDemiJourEcole 'NE MARCHE PAS !!!
'Macro permettant de mettre à jour le graphique du taux de présences par demi-journées
' en fonction des dates de début et de fin d'observation
monClasseur=thisComponent
fData=monClasseur.Sheets.getByName("Recueil Stats")
nomEcole=fData.getCellRangeByName("A4").String
fGraphique=monClasseur.Sheets.getByName("Histogramme Demi Journées École_2")
dateDeb=fGraphique.getCellRangeByName("B1").String
dateFin=fGraphique.getCellRangeByName("F1").String
premiereColonneDates=fGraphique.getCellRangeByName("D1").Value
derniereColonneDates=fGraphique.getCellRangeByName("H1").Value
ch=fGraphique.Charts(0)
plages=ch.getRanges
xray plages
'exit sub
'plageCouleurs=plages(0)
'plageCouleurs.StartColumn=premiereColonneDates+1
'plageCouleurs.EndColumn=derniereColonneDates+1
'plages(0)=plageCouleurs
plageDates=plages(0)
plageDates.StartColumn=premiereColonneDates+2
plageDates.EndColumn=derniereColonneDates+1
plages(0)=plageDates
plageNom=plages(1)
plageValeurs=plages(2)
plageValeurs.StartColumn=premiereColonneDates+2
plageValeurs.EndColumn=derniereColonneDates+1
plages(2)=plageValeurs
xray plages
ch.setRanges(plages())
diag1=fGraphique.Charts(0).EmbeddedObject
diag1.Title.String= "Taux de présence par demi-journées de l'école " & nomEcole & " du " & dateDeb & " au " & dateFin & " (matin en vert, après-midi en jaune)"
'xray diag1
End Sub
'------------------------------------------------------------------------------------------------------------------------------------------------------------
REM ***** BASIC *****
'Macros trouvée ici : https://ask.libreoffice.org/en/question/75127/macro-change-categories-data-range/
'Permet de mettre à jour les diagrammes
' Macro adaptée pour des données en ligne
Sub UpdateDocChartRanges
monClasseur=thisComponent
fData=monClasseur.Sheets.getByName("Recueil Stats")
nomEcole=fData.getCellRangeByName("A4").String
fGraphique=monClasseur.Sheets.getByName("Histogramme Demi Journées École_2")
dateDeb=fGraphique.getCellRangeByName("B1").String
dateFin=fGraphique.getCellRangeByName("F1").String
premiereColonneDates=fGraphique.getCellRangeByName("D1").Value
derniereColonneDates=fGraphique.getCellRangeByName("H1").Value
ch=fGraphique.Charts(0)
'xray ch.EmbeddedObject
'Replace chart datasequences of chart series
UpdateChartRanges( ch, premiereColonneDates, derniereColonneDates-1)
End Sub
Sub UpdateChartRanges( oChart As Object, iFirstColumn As Long, iLastColumn As Long )
Dim oChartDoc As Object
Dim oDataProvider As Object
Dim oCooSys As Object
Dim oCoods As Object
Dim oChartTypes As Object
Dim oChartType As Object
Dim oDataSeriesList As Variant
Dim oDataSequence As Object
Dim oValues As Object
Dim oNewDataSeries() As Object
Dim oSequenceY As Object
Dim oSequenceLabel As Object
Dim i As Integer
Dim n As Integer
Dim bCategories As Boolean
Dim il As Integer
Dim iu As Integer
Dim vSequences() As Object
Dim bFirstColumnLabel As Boolean
Dim oRange As Object
oChartDoc = oChart.EmbeddedObject
oDataProvider = oChartDoc.getDataProvider()
oCooSys = oChartDoc.getFirstDiagram().getCoordinateSystems()
oCoods = oCooSys(0) ' this chart has only a coordinate system
oChartTypes = oCoods.getChartTypes() ' chart type one by one
oChartType = oChartTypes(0)
' all data series belongs the chart type
oDataSeriesList = oChartType.getDataSeries()
' Save and then disable categories so we can treat them as series and restore later
bCategories = oChartDoc.DataSourceLabelsInFirstRow
' Record if first row is label
'bFirstColumnLabel = oChartDoc.DataSourceLabelsInFirstColumn
ReDim oNewDataSeries(lbound(oDataSeriesList) To ubound(oDataSeriesList)) As Object
' For each series in the chart
For i = lbound(oDataSeriesList) To ubound(oDataSeriesList)
' create new DataSeries
oNewDataSeries(i) = CreateUnoService("com.sun.star.chart2.DataSeries")
' Copy the existing formatting of this series
oNewDataSeries(i) = oDataSeriesList(i)
il = lbound(oNewDataSeries(i).DataSequences)
iu = ubound(oNewDataSeries(i).DataSequences)
ReDim vSequences(il To iu) As Object
' Update each data sequence in each series
For n = il To iu
oDataSequence = oNewDataSeries(i).DataSequences(n)
'xray oDataSequence
vSequences(n) = CreateUnoService("com.sun.star.chart2.data.LabeledDataSequence")
oSequenceY = CreateDataSequence(oDataProvider, _
UpdateSeriesRange( oDataSequence.Values.SourceRangeRepresentation, iFirstColumn, iLastColumn ), _
oDataSequence.Values.Role)
'xray oSequenceY
If NOT IsNull(oSequenceY) Then
vSequences(n).setValues(oSequenceY)
If NOT IsNull(oDataSequence.Label) Then
oSequenceLabel = CreateDataSequence(oDataProvider, oDataSequence.Label.SourceRangeRepresentation, "")
'xray oSequenceLabel
vSequences(n).setLabel(oSequenceLabel) ' label is used as name
End If
End If
Next n
oNewDataSeries(i).setData(vSequences)
Next i
' ******** PARTIE PROBLÉMATIQUE concernant le changement de plage pour la catégorie
If bCategories Then
' Change the range of the category data
print iFirstColumn, iLastColumn
plages = oChart.Ranges
plageCateg=plages(0)
plageCateg.StartColumn = iFirstColumn
plageCateg.EndColumn = iLastColumn
plages(0)=plageCateg
xray plages
' Set the new category data range in the chart data range
oChart.Ranges = plages
' ********************************************
' Put the data series back in the chart
oChartType.DataSeries = oNewDataSeries
End If
End Sub
Function UpdateSeriesRange( ByRef sRange As String, iFirstColumn As Long, iLastColumn As Long ) As String
Dim sUpdateSeriesRange As String
Dim iFeuille As Integer, plageMAJ As Object
' print sRange
'Récupère le nom de la feuille
iFeuille=InStr(sRange,".")
nomFeuille=Mid(sRange,3,iFeuille-4)
'Traduit l'AbsoluteNAme de la plage en plage de cellules
plageDepart=thisComponent.Sheets.getByName(nomFeuille).getCellRangeByName(sRange)
nFeuille=plageDepart.RangeAddress.Sheet
ligneDepart=plageDepart.RangeAddress.StartRow
colonneDepart=iFirstColumn
ligneArriv=plageDepart.RangeAddress.EndRow
colonneArriv=iLastColumn
plageMAJ=thisComponent.Sheets(nFeuille).getCellRangeByPosition(colonneDepart,ligneDepart,ColonneArriv,LigneArriv)
'xray plageMAJ'.RangeAddress
' print plageMAJ.AbsoluteName
sUpdateSeriesRange = plageMAJ.AbsoluteName
UpdateSeriesRange = sUpdateSeriesRange
End Function
Function CreateDataSequence( _
oDataProvider As Object, _
sRangeRepresentation As String, sRole As String ) As Object
' Based on post by Hanya
' https://forum.openoffice.org/en/forum/viewtopic.php?f=20&t=8991#p46467
' creat new DataSequence from range representaion
' that provides real data and its role in the series
' oDataProvider: com.sun.star.chart2.data.XDataProvider
' sRangeRepresentation: range address e.g. Sheet1.A1:B2
' sRole: role is defined in com.sun.star.chart2.data.DataSequenceRole
Dim oDataSequence As Object
On Error GoTo Handler
' create .chart2.data.DataSequence from range representation
oDataSequence = oDataProvider.createDataSequenceByRangeRepresentation(sRangeRepresentation)
If NOT IsNull(oDataSequence) Then
oDataSequence.Role = sRole
End If
Handler:
CreateDataSequence = oDataSequence
End Function
En vous remerciant pour vos éclairages, cordialement,
Thierry