MshflexGrid - Ajuster la Taille des Colonnes au Texte

Signaler
Messages postés
133
Date d'inscription
mercredi 30 octobre 2002
Statut
Membre
Dernière intervention
25 septembre 2007
-
jmfmarques
Messages postés
7668
Date d'inscription
samedi 5 novembre 2005
Statut
Membre
Dernière intervention
22 août 2014
-
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.

Par avance merci.


 

23 réponses

Messages postés
3877
Date d'inscription
mardi 19 mars 2002
Statut
Membre
Dernière intervention
23 août 2018
16
regarde du côté de ColWidth(IndexDeColonne)
ou de
FormatString

MPi
Messages postés
7668
Date d'inscription
samedi 5 novembre 2005
Statut
Membre
Dernière intervention
22 août 2014
19
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)
Messages postés
940
Date d'inscription
jeudi 20 février 2003
Statut
Membre
Dernière intervention
3 février 2011
7
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
Messages postés
133
Date d'inscription
mercredi 30 octobre 2002
Statut
Membre
Dernière intervention
25 septembre 2007

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.
Messages postés
7668
Date d'inscription
samedi 5 novembre 2005
Statut
Membre
Dernière intervention
22 août 2014
19
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.
Messages postés
133
Date d'inscription
mercredi 30 octobre 2002
Statut
Membre
Dernière intervention
25 septembre 2007

Premier essais --> Msgbox = 6810 
Deuxième  "                         = 16200


 


Attention, je travaille sur un fichier de taille réduite. en réalité, il y aura au minimum 25000 rows.


 


Merci encore
Messages postés
7668
Date d'inscription
samedi 5 novembre 2005
Statut
Membre
Dernière intervention
22 août 2014
19
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 
Messages postés
7668
Date d'inscription
samedi 5 novembre 2005
Statut
Membre
Dernière intervention
22 août 2014
19
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 ?
Messages postés
3877
Date d'inscription
mardi 19 mars 2002
Statut
Membre
Dernière intervention
23 août 2018
16
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 ...

MPi
Messages postés
7668
Date d'inscription
samedi 5 novembre 2005
Statut
Membre
Dernière intervention
22 août 2014
19
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
Messages postés
3877
Date d'inscription
mardi 19 mars 2002
Statut
Membre
Dernière intervention
23 août 2018
16
Salut JMF,

Mais rien ne dit qu'il y pourrait y avoir un nombre de caractères définis autre que celui par défaut...

Je pensais à une requête SQL qui lirait la longueur de ces champs, mais je ne pense que ça puisse se faire ... (?)

Quelquefois, la nuit porte conseil... j'attends donc son conseil...

MPi
Messages postés
7668
Date d'inscription
samedi 5 novembre 2005
Statut
Membre
Dernière intervention
22 août 2014
19
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...)
Messages postés
133
Date d'inscription
mercredi 30 octobre 2002
Statut
Membre
Dernière intervention
25 septembre 2007

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. 


<hr />
Nconnection = ".............;
Zsql = "Select * from ..................

Set Nrecordset = New Recordset
Nrecordset.CursorLocation = adUseClient
Nrecordset.Open Zsql, Nconnection
Set MSHFlexGrid1.DataSource = Nrecordset
<hr />
 
Messages postés
3877
Date d'inscription
mardi 19 mars 2002
Statut
Membre
Dernière intervention
23 août 2018
16
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 ?

MPi
Messages postés
133
Date d'inscription
mercredi 30 octobre 2002
Statut
Membre
Dernière intervention
25 septembre 2007

Oui Quelqu'un à parlé d'une Msgbox (Voir Page 1)   - Pourquoi cette question ?

Comme je le disais plus haut, je ne tiens pas à scanner toutes les colonnes des tables qui peuvent contenir 25000
35000 rows ou plus. 
Messages postés
7668
Date d'inscription
samedi 5 novembre 2005
Statut
Membre
Dernière intervention
22 août 2014
19
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.

Dis-nous ta décision...
Messages postés
133
Date d'inscription
mercredi 30 octobre 2002
Statut
Membre
Dernière intervention
25 septembre 2007

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.

Je tiens à vous remercier encore pour votre aide

 
Messages postés
3877
Date d'inscription
mardi 19 mars 2002
Statut
Membre
Dernière intervention
23 août 2018
16
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 ?

MPi
Messages postés
133
Date d'inscription
mercredi 30 octobre 2002
Statut
Membre
Dernière intervention
25 septembre 2007

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.

Je te remercie encore une fois pour ton support

Bonne journée    
Messages postés
3877
Date d'inscription
mardi 19 mars 2002
Statut
Membre
Dernière intervention
23 août 2018
16
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
   
    Grid1.Redraw = True
    Temps = Timer - Temps
   
    MsgBox Temps
End Sub

MPi
1 2