MshflexGrid - Ajuster la Taille des Colonnes au Texte
cs_Cpapy
Messages postés133Date d'inscriptionmercredi 30 octobre 2002StatutMembreDernière intervention25 septembre 2007
-
26 avril 2007 à 12:04
jmfmarques
Messages postés7666Date d'inscriptionsamedi 5 novembre 2005StatutMembreDernière intervention22 août 2014
-
28 avril 2007 à 22:31
Bonjour à tous,
Mshflexgrid - Comment ajuster la largeur d'une colonne en fonction de son contenu
Si la première cellule de ma colonne contient "ABCD"
la seconde " " " " "D"
la troisième " " " " "EFGHIJKL"
Je souhaiterais que la taille de ma colonne soit ajustée pour afficher "EFGHIJKL" et pas un caractère de plus.
jmfmarques
Messages postés7666Date d'inscriptionsamedi 5 novembre 2005StatutMembreDernière intervention22 août 201427 26 avril 2007 à 13:25
Bonjour Cpapy,
Je veux bien m'y mettre, mais confirme-moi que c'est bien en VB6, que tu développes (car je saurai le faure sans hésitation en VB6, mais ne connais pas VB.Net)
tbbuim1
Messages postés940Date d'inscriptionjeudi 20 février 2003StatutMembreDernière intervention 3 février 20119 26 avril 2007 à 16:20
Alors tu peux utiliser un textbox invisible
Tu copies au préalable le texte dans ton textbox qui est à la mm police et au mm format que ta MSH et avec la propriété autosize à true. Ainsi le textbox se mettra automatiquement à la bonne taille pr afficher ton texte. Tu n'auras plus qu'à reprendre ces infos pour les appliquer à la hauteur et à la longueur de ta cellule dans ta MSH. Et/ou faire une condition pour ne retenir que la plus grande longueur obtenue.
Petit conseil, n'oublies d'encadrer la gestion de l'affichage de ta MSH par
MSH.redraw false et MSH.redraw true
cs_Cpapy
Messages postés133Date d'inscriptionmercredi 30 octobre 2002StatutMembreDernière intervention25 septembre 2007 26 avril 2007 à 18:59
Merci pour vos réponses.
La technique qui consiste à récupérer la longueur en passant par une textbox est valable pour une petite table avec très peur de colonnes mais trop longue en temps lorsque l'on à un gros fichier de plusieurs colonnes.
Il doit certainement exister une propriéte pour réaliser simplement ce que je souhaite faire. Mais je ne l'ai pas trouvé !
Je confirme, à notre ami JmfMarques que je suis bien en VB6.
Merci encore pour votre support.
Vous n’avez pas trouvé la réponse que vous recherchez ?
jmfmarques
Messages postés7666Date d'inscriptionsamedi 5 novembre 2005StatutMembreDernière intervention22 août 201427 26 avril 2007 à 19:40
Bon...
Bonsoir,
Nous allons commencer par vérifier une chose :
Mets un bouton de commande et ce code; pour voir :
Private Sub Command1_Click()
For i = 0 To MSFlexGrid1.Rows - 1
toto = toto & vbCrLf & MSFlexGrid1.TextMatrix(i, 0)
Next
Set Me.Font = MSFlexGrid1.Font
MsgBox TextWidth(toto)
End Sub
tu lances une 1ère fois et notes ce qu'affiche msgbox
tu modifies la font de ta flexgrid (mets-la à une taille plus grande) - tu lances et notes ce que dit alors msgbox
Tu me communique les 2 chiffres
Le reste (si c'est probant) viendra après dîner et sera un jeu d'enfant.
jmfmarques
Messages postés7666Date d'inscriptionsamedi 5 novembre 2005StatutMembreDernière intervention22 août 201427 26 avril 2007 à 20:36
25000 rows ? celà fait en effet beaucoup pour un msgbox avec vbcrlf !!
Mais celà dépend ...
Quelle est la longueur (en nombre de caractères) de la chaîne la plus longue ?
Selon cette longueur, on pourrait éviter cette longue série ...
Dis-moi
jmfmarques
Messages postés7666Date d'inscriptionsamedi 5 novembre 2005StatutMembreDernière intervention22 août 201427 26 avril 2007 à 20:42
arrête !
La taille maximum d'une variable sring est de 64 K = 64000 caractères . si ton divise par 25000 lignes, on arrive à moins de 3 caractères !
Va falloir que je réfléchisse à autre chose, donc .....
Mais : dis-moi tout : pour envoyer 25000 lignes, tu ne le fais pas de façon manuelle, n'est-ce-pas ?
Je crois alors volontiers que chaque ligne est "renseignée" par un champ d'une base de données. Dans ce cas, donc : quelle est la taille maximum donnée en caractères à ce champ dans la table correspondante de ta base de données ?
cs_MPi
Messages postés3877Date d'inscriptionmardi 19 mars 2002StatutMembreDernière intervention17 août 201823 26 avril 2007 à 23:28
Et si tu faisais une simple boucle et que tu stockais la plus longue valeur de Len(Grid.TextMatrix(i, 0)) dans une variable Largeur, disons, est-ce que ça prend beaucoup de temps ?
du genre
for I = 1 to Grid.Rows-1
if Len(grid1.TextMatrix(I,0) > Largeur then
Largeur = Len(grid1.TextMatrix(I,0)
ensuite, il resterait à ajuster avec Textwidth selon la police ...
jmfmarques
Messages postés7666Date d'inscriptionsamedi 5 novembre 2005StatutMembreDernière intervention22 août 201427 26 avril 2007 à 23:41
Tu as raison, MPI (j'y ai pensé aussi)... mais si ce qu'il met dans la Grid provient comme je le devine d'une SGBD, on peut éviter cette boucle sur 25000
jmfmarques
Messages postés7666Date d'inscriptionsamedi 5 novembre 2005StatutMembreDernière intervention22 août 201427 27 avril 2007 à 07:33
Salut MPI,
Il pourrait bien sur avoir défini une longueur maximim pour un champ et ne pas l'utiliser totalement, en effet....
J'ai une autre solution, dans ce cas, mais elle impliquerait qu'il accepte que sa MSFmlexGrid fasse comme un élastique (qu'elle s'adapte en fonction de ce qu'elle peut afficher sur sa hauteur à chaque instant... et ce n'est pas reposant pour l'oeil...)
cs_Cpapy
Messages postés133Date d'inscriptionmercredi 30 octobre 2002StatutMembreDernière intervention25 septembre 2007 27 avril 2007 à 09:06
Bonjour à tous,
Je rapelle comme cela est indiqué dans le Sujet qu'il s'agit d'un MshFlexGrid et non pas d'un MsgBox.
Toute les informations qui figurent dans ce contrôle sont issues de Bases de Données (comme l'indique le code ci-dessous). De plus, ce même Mshflexgrid peut être chargé avec des informations provenant de Bases ( de Tables) différentes.
cs_MPi
Messages postés3877Date d'inscriptionmardi 19 mars 2002StatutMembreDernière intervention17 août 201823 27 avril 2007 à 11:44
CPapy, est-ce que quelqu'un a parlé d'une MsgBox ?
As-tu essayé avec une boucle et stocker la longueur la plus grande dans une variable ?
Si oui, est-ce que c'est trop long comme processus pour ton bonheur ?
jmfmarques
Messages postés7666Date d'inscriptionsamedi 5 novembre 2005StatutMembreDernière intervention22 août 201427 27 avril 2007 à 19:59
Bonjour Cpapy,
as-tu lu ce que j'ai écrit ?
"J'ai une autre solution, dans ce cas, mais elle impliquerait qu'il accepte que sa MSFmlexGrid fasse comme un élastique (qu'elle s'adapte en fonction de ce qu'elle peut afficher sur sa hauteur à chaque instant... et ce n'est pas reposant pour l'oeil...) "
Quelle est ta réaction à celà ?
Si tu ne veux pas de cet effet élastique, je crains que la boucle ne soit alors indispensable, à moins que tu n'abandonnes l'idée d'une colonne "ajustée" (tu avais dit "ni plus ni moins") et que tu te contentes de "coller" au nombre de caractères le plus élevé possible (la taille maxi définie pour ton champ).
Quant à la boucle, maintenant, elle ne saurait se contenter d'aller repérer le texte présent le plus long en caractères mais bel et bien le plus long graphiquement (lenteur de plus) car, par exemple llllllll (10 l, donc) occupent moins de place graphique que mmmmm (5 m seulement !). A moins que tu ne choisisses une police à espacement constant (et là... ce sera moche à l'écran...)
Pour résumer : ton choix est restreint :
choix 1 : une boucle lente pour apprécier la taille graphique la plus grande de toutes les données présentes
choix2 : pas de boucle et on met d'office la taille la plus grande possible (longueur maximum définie pour le champ
choix 3 : l'aspect "élastique" visé plus haut (et ta grid changera alors constamment de dimensions ...)
Il y a un 4ème choix possible : celui d'une 1ère boucle pour repérer la donnée actuelle la plus longue, une fois pour toutes et enregistrer cette donnée dans un fichier texte.
On ajuste alors la dimension sur la base de ce texte-là
Puis, lors de chaque enregistrement nouveau dans ta base, on contrôle si ce champ est plus long ou non que celui déjà dans le fichier texte et :
- si moins long, on te change rien
-si plus long, on modifie le fichier texte et la dimension de ta colonne.
Celà impliquerait toutefois de relancer à nouveau la boucle chaque fois que serait modifié ou supprimé l'article se trouvant dans le fichier texte afin de déterminer quel est la nouvelle donnée la plus longue après cette modification ou suppression....!
Voilà ! tu sais tout, maintenant.
cs_Cpapy
Messages postés133Date d'inscriptionmercredi 30 octobre 2002StatutMembreDernière intervention25 septembre 2007 28 avril 2007 à 10:03
Bonjour,
Ces différentes techniques que j'ai déjà utilisées sont applicables sur des bases de petites tailles.
S'il n'existe aucune méthode simple ou propriété standard qui permette de régler mon problème, j'en resterais malheureusement à la bonne vielle méthode classique qui consiste à laisser l'utilisateur dimensionner les colonnes comme il le souhaite. Je sauvegarderais alors toutes les tailles de colonne dans un fichier pour les restituer à chaque initialisation de la table.
cs_MPi
Messages postés3877Date d'inscriptionmardi 19 mars 2002StatutMembreDernière intervention17 août 201823 28 avril 2007 à 12:40
Et si tu essayais ceci...
Tu lances ta requête
Tu boucles chaque valeur du champs concerné (donc, en mémoire et non graphiquement) et tu stockes la plus longue chaîne (nombre de caractère)
Tu fixes la largeur de la ou des colonnes
Tu affiches ton Recordset.
Est-ce que ça peut faire du sens ?
Après test, est-ce que c'est trop long comme processus ?
cs_Cpapy
Messages postés133Date d'inscriptionmercredi 30 octobre 2002StatutMembreDernière intervention25 septembre 2007 28 avril 2007 à 17:47
Bonjour MPi,
Ton idée est très bonne mais pour une petite Base et de plus elle doit être figée. Si ma base de 24000 rows par exemple comporte 10 colonnes, je devrais copier dans un label 2.400.000 informations pour déterminer la taille de mes 10 colonnes et relire ma base pour la charger.
cs_MPi
Messages postés3877Date d'inscriptionmardi 19 mars 2002StatutMembreDernière intervention17 août 201823 28 avril 2007 à 21:51
Je ne pouvais pas laisser ça là comme ça... alors j'ai fait un test avec une table de 25000 enregistrements sur 10 colonnes.
Je calcule le temps pour charger le recordset et l'afficher ligne par ligne en calculant la largeur des colonnes au fur et à mesure et ça me donne autour de 6.5 secondes
Si je ne calcule pas la largeur des colonnes, j'arrive à 2.7 sec
Environ 4 secondes de plus, c'est quand même pas si mal... et ça peut probablement être amélioré...
Note: j'ajoute 100 parce que la largeur n'est pas calculée correctement. Probablement une erreur de logique de ma part... mais c'est samedi et je prends ça mollo... Et le Redraw ne semble pas faire une différence notable.
Private Sub Command1_Click()
Dim Champ As Integer, I As Long
Dim Tablo(9) As Integer
Dim Rs As Recordset
Dim Temps As Single
Temps = Timer
Grid1.Redraw = False
Set Rs = Db.OpenRecordset("Select * from Table1")
Do Until Rs.EOF
I = I + 1
For Champ = 0 To 9
If (Len(Rs.Fields(Champ)) * TextWidth(Champ)) + 100 > Tablo(Champ) Then
Tablo(Champ) = (Len(Rs.Fields(Champ)) * TextWidth(Champ)) + 100
End If
Grid1.TextMatrix(I, Champ) = Rs.Fields(Champ)
Next
Rs.MoveNext
Loop
For I = 0 To Grid1.Cols - 1
Grid1.ColWidth(I) = Tablo(I)
Next