Le Barbatruc de Jam: Un graph dans une cellule.

Jam

XLDnaute Accro
Salut à tous,

Bon je m'y résoud. Voici donc mon Barbatruc.
Je précise tout de suite qu'il n'est PAS de moi (j'ai vraiment pas le temps de développer en ce moment) mais de Rob Van Gelder.
Ce truc donne la possibilité de faire un graph DANS une cellule (testé sous XL2K).
Il faut deux fonctions (elle est dans le zip attaché).
La formule à utiliser est:
=LineChart(plage de référence;couleur)
exemple
=LineChart(A1:J1;203) -> 203 pour du rouge.

Amusez-vous bien et découvrez (si besoin en était) qu'Excel nous réserve chaque fois des surprises surprenantes. Le mérite sur ce coup en revient encore une fois à Rob Van Gelder. [file name=Fonction.zip size=810]http://www.excel-downloads.com/components/com_simpleboard/uploaded/files/Fonction.zip[/file]
 

Pièces jointes

  • Fonction.zip
    810 bytes · Affichages: 386
  • Fonction.zip
    810 bytes · Affichages: 385
  • Fonction.zip
    810 bytes · Affichages: 381

Magic_Doctor

XLDnaute Barbatruc
Re : Le Barbatruc de Jam: Un graph dans une cellule.

Bonjour,

Fouinant dans la BD du forum pour tenter de résoudre des problèmes de graphiques, je suis tombé sur cette magnifique fonction de Rob ---> Ti ---> Chris.

Cette fonction permet donc de représenter une coube dans 1 seule cellule. Et c'est très fort.
En fait, il s'agit d'un graphique qui se superpose sur ladite cellule.
Le problème est qu'en général une cellule a une petite surface. Pour aumenter celle-ci on augmente la hauteur de la ligne et/ou celle de la colonne ; ce qui affecte fatalement toutes les cellules contiguës.
J'ai donc essayé (sans succés...) de fusionner plusieurs cellules et d'introduire dans le cellule "unique" résultant de cette fusion cette fonction. Pas folle, celle-ci adapte le graphique sur toujours une seule cellule, à savoir la 1ère de l'ensemble des cellules fusionnées.
J'ai donc tenté de bidouiller la fonction pour forcer celle-ci à ce que la surface du graphe recouvre 2 cellules contiguës et non pas une seule. Ça n'a (évidemment) pas marché...
Comment faire en sorte que, selon nos desiderata, le graphe, au lieu de recouvrir uniquement (par ex.) la cellule A1, recouvre A1:B1 ou, pourquoi pas, A1:B2 ??

La fonction en question :

Function LineChart(Points As Range, Optional ByVal Couleur%)
'Une fonction de Rob Van Gelder un peu modifiée par Ti
Const KMg = 2, KTag = "Line"
Dim Ref As Range, ShRg(), Bcle&, Cnt&
Dim Min#, Max#, Pts, Lg#, Ht#

On Error Resume Next
With Points
If .Rows.Count > 2 And .Columns.Count > 2 Then
LineChart = CVErr(xlErrValue): Exit Function
End If
Pts = .Value: Cnt = .Count
ReDim ShRg(2 To Cnt - 1)
If .Columns.Count > 2 Then Pts = WorksheetFunction.Transpose(Pts)
End With

Set Ref = Application.Caller
With Ref
.Worksheet.Shapes(KTag & .Address).Delete

Min = WorksheetFunction.Min(Pts)
Max = WorksheetFunction.Max(Pts)
Lg = (.Width - (KMg * 2)) / (Cnt - 1)
Ht = (.Height - (KMg * 2)) / (Max - Min)

For Bcle = 1 To Cnt - 1
With .Worksheet.Shapes.AddLine( _
KMg + .Left + Lg * (Bcle - 1), _
KMg + .Top + (Max - Pts(Bcle, 1)) * Ht, _
KMg + .Left + Lg * Bcle, _
KMg + .Top + (Max - Pts(Bcle + 1, 1)) * Ht)
ShRg(Bcle) = .Name
End With
Next Bcle

With .Worksheet.Shapes.Range(ShRg)
.Group
.Line.ForeColor.SchemeColor = Couleur
.Name = KTag & Ref.Address
End With
End With

LineChart = ""
End Function

Si les ténors à l'origine de cette fonction ne sont pas là, il y en aurait-il un parmi vous qui puisse les remplacer ??

Quoi qu'il en soit, ma question aura au moins servi à relancer le fil sur cette fonction étonnante.
 

wilfried_42

XLDnaute Barbatruc
Re : Le Barbatruc de Jam: Un graph dans une cellule.

Bonjour

je pense que j'ai ce que tu désires, mais pas sur une cellule fusionnée... j'en ai eu besoin pour une application. donc j'ai modifié ce merveilleux fichier

les fonctions sont expliquée, à la fin on ajoute la plage sur laquelle on veut afficher le graph, un plage nommée sur une feuille différente fonctionne aussi.
 

Pièces jointes

  • ChartCels (version 3).xls
    104.5 KB · Affichages: 135

coco_lapin

XLDnaute Impliqué
Re : Le Barbatruc de Jam: Un graph dans une cellule.

Bonsoir le forum,

Je suis totalement impressionné par ce surprenant et efficace résultat.

Cela fait super pro, je vais l'utiliser à mon boulot.

Merci et bravo à ceux qui ont contribué à sa construction ou sa modification.
 

Magic_Doctor

XLDnaute Barbatruc
Re : Le Barbatruc de Jam: Un graph dans une cellule.

Bonsoir,

J'ai essayé, sans succés, la fonction de Wilfried 42.
J'ai un peu "bidouillé" la fonction originale, avec malheureusement un résultat inconstant, commem lorsque les colonnes ont des LARGEURS DIFFÉRENTES :

Function LineChart(Points As Range, Colonnes%, Lignes%, Optional ByVal Couleur%)
'j'ai rajouté comme variables dans la fonction Lignes(%) & Colonnes(%)
'Une fonction de Rob Van Gelder un peu modifiée par Ti
Const KMg = 2, KTag = "Line"
Dim ref As Range, ShRg(), Bcle&, Cnt&
Dim Min#, Max#, Pts, Lg#, Ht#

On Error Resume Next
With Points
If .Rows.Count > 1 And .Columns.Count > 1 Then
LineChart = CVErr(xlErrValue): Exit Function
End If
Pts = .Value: Cnt = .Count
ReDim ShRg(1 To Cnt - 1)
If .Columns.Count > 1 Then Pts = WorksheetFunction.Transpose(Pts)
End With

Set ref = Application.Caller
With ref
.Worksheet.Shapes(KTag & .Address).Delete

Min = WorksheetFunction.Min(Pts)
Max = WorksheetFunction.Max(Pts)
Lg = (.Width - (KMg * 2)) / (Cnt - 1) * Colonnes
Ht = (.Height - (KMg * 2)) / (Max - Min) * Lignes

For Bcle = 1 To Cnt - 1
With .Worksheet.Shapes.AddLine( _
KMg + .Left + Lg * (Bcle - 1), _
KMg + .Top + (Max - Pts(Bcle, 1)) * Ht, _
KMg + .Left + Lg * Bcle, _
KMg + .Top + (Max - Pts(Bcle + 1, 1)) * Ht)
ShRg(Bcle) = .Name
End With
Next Bcle

With .Worksheet.Shapes.Range(ShRg)
.Group
.Line.ForeColor.SchemeColor = Couleur
.Name = KTag & ref.Address
End With
End With

LineChart = ""
End Function

Je vous aurais bien joint ici une feuille où le problème aurait été plus explicite qu'une longue et ennuyeuse explication. L'inconvéniant est, qu'étant sous Excel 2007, quand je le trancris en Excel 93 - 2003, je passe de 40 Ko à plus de 1.000 Ko... Allez savoir pourquoi...!!!???
(¡¡LPQLP!!)

Si l'un d'entre vous parvient à le résoudre...
Ce sera avec GRAND PLAISIR !!
 

wilfried_42

XLDnaute Barbatruc
Re : Le Barbatruc de Jam: Un graph dans une cellule.

re:

tu reprends le code d'origine et tu ajoute la 2eme ligne au meme endroit
Code:
    Set ref = Application.Caller
    [B]If ref.MergeCells = True Then Set ref = Range(ref.MergeArea.Address)[/B]
redefini la plage si cette plage est une cellule fusionnée
 

Magic_Doctor

XLDnaute Barbatruc
Re : Le Barbatruc de Jam: Un graph dans une cellule.

Bonjour,

Désolé Wilfried, mais je n'ai absolument rien compris...
Aucune idée où exactement placer cette modification (2ème ligne ??? Oui, mais c'est quoi la 2ème ligne ??? Après Sub, après Dim ???).
Bon, je ne suis absolument pas expert en macros et autres fonctions....
Mais si tu m'adressais intégralement ta fonction...
En revanche je m'escrime, toujours sans succés à 100%, à tenter d'améliorer cette fonction hallucinante (pour ceux qui aiment encore ça...).
Le problème majeur de cette fonction est que nous sommes assujettis à une seule cellule. Si les coordonnées de la courbe sont très nombreuses, le graphique risque d'être très ramassé, à moins que l'on élargisse la cellule avec toutes les conséquence sur l'aspect de la feuille (d'un seul coup une cellule géante !!). Donc, la solution idéale serait de pouvoir moduler le nombre de colonnes et de lignes sur lesquelles viendrait se juxtaposer le graphique.

J'ai "bidouillé" à nouveau la fonction pour au moins résoudre, dans un premier temps, le problème des colonnes (la largeur du graphique me paraissant plus importante que la hauteur). Voici la fonction avec nombre de commentaires :

Function LineChart(Points As Range, colonnes%, Lignes%, Optional ByVal Couleur%) '2 variables supplémentaires : colonnes(%) et Lignes(%)
'Une fonction de Rob Van Gelder un peu modifiée par Ti, Chris & Magic_Doctor

Const KMg = 2, KTag = "Line"
Dim ref As Range, ShRg(), Bcle&, Cnt&
Dim Min#, Max#, Pts, Lg#, Ht#
Dim i%, largeurColonne, largeurColonnesSup, facteur 'variables rajoutées pour les besoins des calculs

On Error Resume Next
With Points
If .Rows.Count > 1 And .Columns.Count > 1 Then
LineChart = CVErr(xlErrValue): Exit Function
End If
Pts = .Value: Cnt = .Count
ReDim ShRg(1 To Cnt - 1)
If .Columns.Count > 1 Then Pts = WorksheetFunction.Transpose(Pts)
End With

'-------------------------------- RAJOUTS -------------------------------------------
'soit il y a une seule colonne, soit plusieurs
If colonnes > 1 Then 's'il y a plusieurs colonnes (<=> plusieurs cellules contiguës)
'vérifie si toutes les colonnes ont la même largeur
For i% = 0 To colonnes% - 1
If ActiveCell.Offset(0, i%).ColumnWidth = ActiveCell.ColumnWidth Then 'si toute les colonnes ont la même largeur
largeurColonne = largeurColonne + 0 '(le résultat sera nul)
Else 'si toute les colonnes n'ont pas la même largeur
largeurColonne = largeurColonne + 1 '(le résultat sera le nb de colonnes dont la largeur est # de la 1ère)
End If
Next i%
If largeurColonne = 0 Then 'les colonnes ont toutes la même largeur
facteur = 1
Else 'les colonnes n'ont pas toutes la même largeur, on cherche alors un facteur de correction
'calcul de la somme des largeurs des colonnes excédentaires (puisque à l'origine, il n'y avait qu'une seule colonne)
For i% = 1 To colonnes - 1
largeurColonnesSup = largeurColonnesSup + ActiveCell.Offset(0, i%).ColumnWidth
Next i%
facteur = 1 + largeurColonnesSup / ActiveCell.ColumnWidth ^ 2 'tentative algorithme découlant de l'incontournable règle de 3, mais sujet à caution...
End If
Else 's'il n'y a qu'une seule colonne (<=> une cellule unique, comme dans la fonction originale)
facteur = 1
End If
'------------------------------------------------------------------------------------

Set ref = Application.Caller

With ref
.Worksheet.Shapes(KTag & .Address).Delete
Min = WorksheetFunction.Min(Pts)
Max = WorksheetFunction.Max(Pts)
Lg = (.Width - (KMg * 2)) / (Cnt - 1) * colonnes * facteur 'on multiplie Lg par [le nb de colonnes] * [facteur de correction] pour obtenir la largeur de l'ensemble des cellules
'Lg = ActiveCell.ColumnWidth * colonnes * facteur
Ht = (.Height - (KMg * 2)) / (Max - Min) * Lignes

For Bcle = 1 To Cnt - 1
With .Worksheet.Shapes.AddLine( _
KMg + .Left + Lg * (Bcle - 1), _
KMg + .Top + (Max - Pts(Bcle, 1)) * Ht, _
KMg + .Left + Lg * Bcle, _
KMg + .Top + (Max - Pts(Bcle + 1, 1)) * Ht)
ShRg(Bcle) = .Name
End With
Next Bcle

With .Worksheet.Shapes.Range(ShRg)
.Group
.Line.ForeColor.SchemeColor = Couleur
.Name = KTag & ref.Address
End With
End With

LineChart = ""
End Function

Copiez/Collez dans un module et testez.

Il y a une certaine amélioration dans la largeur du graphique, mais ce n'est pas encore ça...
La largeur du graphique ne correspond pas forcément au nombre de colonnes (autrement dit cellules contiguës) choisi.
Mais enfin, ça progresse !

Si cette fonction intéresse encore quelqu'un, toute suggestion sera la bienvenue.
 

Quincy

XLDnaute Occasionnel
Supporter XLD
Re : Le Barbatruc de Jam: Un graph dans une cellule.

Bonjour à tous

J'avais adopté les modifications de Chris qui permettaient l'utilisation des nombres négatifs et je l'en remercie. Aujourd'hui je découvre la méthode de Wilfried 42 qui permet de choisir la plage de cellules sur lesquelles on peut placer le graphique. Après avoir fait quelques tests j'ai trouvé cela très interessant et me suis empressé de récupérer les procédures seulement voilà... les fonctions de Wilfried 42, sauf erreur de ma part, ne prennent pas en compte les modifications de Chris et ne gèrent donc pas les nombres négatifs.

Comme je n'ai pas assez de compétences pour manipuler ces fonctions très complexes et sans vouloir abuser j'aurais aimer que Wilfried 42 ou une autre âme charitable se penche sur mon problème afin d'adapter ces fonctions.

En tous cas merci à tous pour votre investissement.
Très cordialement.

Quincy
 

wilfried_42

XLDnaute Barbatruc
Re : Le Barbatruc de Jam: Un graph dans une cellule.

re:

c'est vrai, j'ai don repris le fichier de chris...
Voici une des Fonctions de Ti
Code:
Function HistoChart(Points As Range, Optional ByVal Couleur% = 29[B][COLOR="Red"], Optional Maplage As Range = Nothing[/COLOR][/B])
'Ti pour XLD
Const KMg = 2, KTag = "Hist"
Dim Ref As Range, ShRg(), Bcle&, Cnt&
Dim Pts, Lg#, Ht#, Rp#

  On Error Resume Next
  With Points
    If .Rows.Count > 1 And .Columns.Count > 1 Then
      HistoChart = CVErr(xlErrValue): Exit Function
    End If
    Pts = .Value: Cnt = .Count
    ReDim ShRg(1 To Cnt)
    If .Columns.Count > 1 Then Pts = WorksheetFunction.Transpose(Pts)
  End With

[COLOR="red"][B]  If Not Maplage Is Nothing Then Set Ref = Maplage Else Set Ref = Application.Caller
  If Ref.MergeCells Then Set Ref = Range(Ref.MergeArea.Address) ' Sur cellule fusionnée[/B][/COLOR]
  With Ref
    .Worksheet.Shapes(KTag & .Address).Delete

    Lg = (.Width - (KMg * (Cnt + 1))) / Cnt
    Rp = WorksheetFunction.Max(Pts) / (.Height - (KMg * 2))

    For Bcle = 1 To Cnt
      Ht = Pts(Bcle, 1) / Rp
      With .Worksheet.Shapes.AddShape(msoShapeRectangle, _
                                      .Left + (KMg * Bcle + Lg * (Bcle - 1)), _
                                      .Top + .Height - Ht - KMg, Lg, Ht)
        ShRg(Bcle) = .Name
      End With
    Next Bcle

    With .Worksheet.Shapes.Range(ShRg)
      .Group
      .Fill.ForeColor.SchemeColor = Couleur
      .Name = KTag & Ref.Address
    End With
  End With

  HistoChart = ""
End Function
Comme leur travail est excellent, la modification à apporter est infime (lignes en Gras / Rouge)
en retour le fichier avec toutes les fonctions modifiées, j'en ai profité pour ajouter sur cellule fusionnées (pas de plage à definir, mettre la formule dans la cellule fusionnée)
 

Pièces jointes

  • ChartCels (version 3).zip
    33.4 KB · Affichages: 71

Quincy

XLDnaute Occasionnel
Supporter XLD
Re : Le Barbatruc de Jam: Un graph dans une cellule.

Bonjour Wilfried 42, re le forum,

Wilfried 42 je te remercie pour ta rapide intervention. Si j'ai bien compris je garde les fonctions modifiées de Chris et rajoute sur chacune les codes que tu as écris en rouge. C'est super !

Cordialement.
Quincy
 

Magic_Doctor

XLDnaute Barbatruc
Re : Le Barbatruc de Jam: Un graph dans une cellule.

Bonsoir à tous,

Merci encore Wilfried pour les améliorations de ces fonctions.
Elles marchent dans pratiquement tous les cas.
Curieusement, voulant reproduire une courbe de Gauss, ça n'a pas marché, alors qu'avec la formule originale (une seule cellule), ça marche très bien. Me serais-je planté quelque part dans le paramétrage de la fonction ?

Ci-joint un exemple.

En espérant lire tes commentaires.
 

Pièces jointes

  • ComparaisonsCellGraph.zip
    27.9 KB · Affichages: 63

wilfried_42

XLDnaute Barbatruc
Re : Le Barbatruc de Jam: Un graph dans une cellule.

re:

tout ce que je peux te dire que ce ne sont pas mes modifs qui provoquent cette erreur, ce sont tes parametres. si tu enleves ;J2:L2 tu retrouves exactement la meme erreur (Erreur gérée par les graphistes et affichée volontairement par eux meme)

le dernier parametre (la plage) est optionnelle donc n'est pas obligatoire.
 

Magic_Doctor

XLDnaute Barbatruc
Re : Le Barbatruc de Jam: Un graph dans une cellule.

Rebonsoir Wilfried,

Je pense avoir trouvé la faille.
La colonne contenant les coordonnées de la courbe de Gauss ne contient que des chiffres DÉCIMAUX : la fonction ne marche pas !
Maintenant je transforme tous ces chiffres en ENTIERS : la fonction marche !

J'ai fait quelques essais avec des séries de chiffres rationnels nettement moins longues : idem.
Si je convertis les mêmes chiffres en entiers : ça marche !!

En conséquence, je pense que les modifications que tu as faites et qui rendent la fonction nettement plus polyvalente, font que celle-ci ne marche que si elle utilise des nombres ENTIERS, ce qui, malheureusement, en limite sérieusement l'usage.
 

wilfried_42

XLDnaute Barbatruc
Re : Le Barbatruc de Jam: Un graph dans une cellule.

re:

negatif sur ton analyse de l'erreur, les modifs apportées ne concernent que l'emplacement du graph et non son calcul

voici quelles sont les conditions d'affichage de #Echelle
Code:
    Min = WorksheetFunction.Min(Pts)
    Max = WorksheetFunction.Max(Pts)
    If Abs(Min) > Abs(Echelle_mini) Or Abs(Max) > Abs(Echelle_maxi) Then
        LineChart3 = "#Echelle"
        Exit Function
    End If

finalement j'ai trouvé : EchelleMini et EchelleMaxi sont definies en long (Entier long) etant donné les valeurs que tu utilises, les valeurs passées deviennent 0 et 0. il faut les définir en double
Code:
Function LineChart3(Points As Range, Echelle_mini As [COLOR="red"][B]Double[/B][/COLOR], Echelle_maxi As [B][COLOR="Red"]Double[/COLOR][/B], Optional ByVal Axe = 1, Optional ByVal Couleur% = 2, Optional Maplage As Range = Nothing)
En conclusion, meme sans les modifs (il est facile de les retirer - 2 lignes), la fonction renvoyait #Echelle.
 
Dernière édition:

Statistiques des forums

Discussions
312 508
Messages
2 089 138
Membres
104 047
dernier inscrit
bravetta