Mshflexgrid avec un nombre de colonnes pouvant varier

Résolu
cpapy - 12 mars 2017 à 15:38
vb95 Messages postés 3472 Date d'inscription samedi 11 janvier 2014 Statut Contributeur Dernière intervention 13 avril 2024 - 13 mars 2017 à 12:36
Bonjour,

J'ai un Mshflexgrid de largeur fixe. Je souhaiterais faire varier le nombre de ses colonnes de 1 à 300 tout en leur affectant la même largeur. Il est également impératif que la totalité des colonnes occupe la largeur de mon Mshflexgrid.
.
J'ai fais plusieurs essais sans réussite.
.
Exemple: Mshflexgrid1.width = 14535
.
Avec 150 colonnes, la taille d'une colonne est 14535/150 soit 96,9
Après avoir affecté ces 96,9 à mes 150 colonnes (Colwidth(x))
.
La taille réelle des colonnes après cette opération est de 90.
.
On perd donc 6,9 par colonne. Les 150 colonnes n'occupent donc pas la totalité de la largeur de mon Mshflexgrid.
.
Merci au technicien qui pourra m'aider à solutionner ce petit problème.

9 réponses

vb95 Messages postés 3472 Date d'inscription samedi 11 janvier 2014 Statut Contributeur Dernière intervention 13 avril 2024 169
Modifié par vb95 le 12/03/2017 à 18:54
Bonsoir
La largeur d'une colonne est toujours un nombre entier : donc 96,9 serait rapporté à 96
De plus dans ton calcul est-ce que tiens compte des 149 lignes verticales qui dessinent tes colonnes
Car la largeur totale de la MSHFlexGrid est égale à
(NbCols * ColWidth) * Nbcols - 1

A tester sans certitude


' Nombre de colonnes
Dim NbCols as Integer = MshFlexGrid.Cols
' Largeur utile de la grille
Dim LargeurGrille as Integer = MshFlexGrid.Width - (NbCols - 1)
' largeur utile d'une colonne
Dim LargeurColonne as Integer = LargeurGrille \ NCols
' largeur de la MshFlexGrid
MshFlexGrid.Width = (LargeurColonne * (Nbcols +1)) - 1


NbCols = nombre de colonne
LargeurGrille = largeur de la MshFlexGrid
LargeurColonne = largeur utile d'une colonne

J'ai fermé ta discussion précédente sur laquelle tu aurais dû continuer : http://codes-sources.commentcamarche.net/forum/affich-10074199-calculer-la-largeur-des-colonnes-d-un-mshflexgrid


La théorie, c'est quand on sait tout et que rien ne fonctionne. La pratique, c'est quand tout fonctionne et que personne ne sait pourquoi. 
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
12 mars 2017 à 19:58
Bonjour, vb95
Ce problème n'a hélas apparemment pas de solution.
J'ai tout essayé (contrôle "flat", gridlines au minimum, Borderstyle à 0, etc ...)
Il faut à chaque fois "corriger" arithmétiquement, mais ("big problem") la correction n'est jamais de type parfaitement linéaire.
Ce qui marche avec un nombre de colonnes compris par exemple entre 10 et 30 et une largeur définie entre100 et 200 ne marche plus parfaitement avec des paramètres très différents.
Il semble que le contrôle activex lui-même fasse des calculs de "répartition" qui échappent (qui ont peut-être échappé au créateur de cet activex).
Quand je dis que j'ai tout essayé, je précise que je suis allé jusqu'à considérer que l'épaisseur des séparations était toujours la même. Il semble que tel ne soit pas le cas.
Nous savons tous que l'épaisseur minimum est celle de 1 pixel (non visible autrement !). Je retrouve bien cette épaisseur minimum avec certains paramètres, mais elle change avec d'autres (nb de colonnes et largeur des colonnes) !!!! A partir de cette constatation ===>> j'abdique !
0
vb95 Messages postés 3472 Date d'inscription samedi 11 janvier 2014 Statut Contributeur Dernière intervention 13 avril 2024 169
12 mars 2017 à 20:31
Bonsoir ucfoutu
J'ai réfléchi vite fait au problème et en ai déduit mes calculs !
Mis ceux-ci ne font pas référence loin de là !
J'ai d'ailleurs mis "A tester sans certitude"
toutes mes salutations mon cher et au plaisir
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
Modifié par ucfoutu le 12/03/2017 à 20:54
En y réfléchissant et re-réfléchissant plusieurs fois, je dirais assez volontiers que le créateur de cet activex a du procéder à des "rattrapages" de positions des séparations du fait de la conjugaison de ces trois facteurs :
1) son usercontrol base tous ses calculs sur des unités en twips
2) mais l'affichage en soi ne peut se faire qu'en pixels
3) des positions en twips ne sauraient trouver une correspondance exacte en pixels (la plupart des machines travaillent avec 15 twips par pixel)
Des rattrapages sont alors nécessaires pour arriver à l'affichage final (des pixels, forcément).
Il faudrait connaître le code-source de cet activex pour savoir comment et en fonction de quoi le créateur a décidé ces rattrapages, qui ne sont pas toujours les mêmes.

Une solution consisterait peut-être à choisir à la base des valeurs en pixels de sorte à ce que la largeur totale soit égale à un nombre entier de pixels, que la largeur des colonnes soit également égale à un nombre entier de pixels, puis de traduire toutes ces valeurs en twips en les multipliant par la constante twipsperpixely.
En espérant que les calculs arithmétiques du créateur de cet activex ne prennent alors pas "le pas" malgré tout (ce qui pourrait fort bien être le cas s'il a choisi d'appliquer systématiquement des Select Case (du nb de colonnes, de leur largeur, etc ...)
Moi, j'abdique, là ...

A cpapy : il est probablement nécessaire ici de rappeler que cet activex n'a pas d'autre vocation de celle de l'affichage de données.
Il a donc été construit dans cet esprit et non dans l'un de ceux, autres, :
- d'une construction d'image
- d'une représentation graphique
- d'un jeu de type morpions, bataille navale, dominos, jeu de dames, etc ...
Avec la vocation qui est la sienne (et si on s'en sert pour cette vocation) l'aspect visuel "parfait" que tu recherches est loin d'avoir une importance.
-
________________________
Nul ne saurait valablement coder ce qu'il ne saurait exposer clairement.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
Modifié par ucfoutu le 13/03/2017 à 09:07
Voilà ce que je propose, en prenant le problème à l'envers (en partant de ce que l'on veut, plutôt que d'une largeur à diviser) :
nb = 100 '--->> le nombre de colonnes que l'on veut
lpix = 10 ' largeur en pixels que l'on veut pour chaque colonne
ltwip = lpix * Screen.TwipsPerPixelX ' --->> sa traduction en twips
With MSFlexGrid1 '-----------------------------------------
.GridLines = 1
.GridLineWidth = 1
.BorderStyle = flexBorderNone
.ScrollBars = flexScrollBarNone
.Cols = nb
For i1 = 0 To nb - 1
.ColWidth(i1) = ltwip
Next i1
.Width = (nb * ltwip)
End With

C'est ce qui me parait le moins inefficace (essayé avec plusieurs paramètres), mais non totalement parfait.
Pour être certain d'être toujours en mesures entières, je pars de Pixels que je traduis ensuite en twips.
Je ne pense pas pouvoir faire mieux que cela.
Bonne nuit



Hé oui, on peut faire mieux ===>>

nb = 100 '--->> le nombre de colonnes que l'on veut
lpix = 10 ' largeur en pixels que l'on veut pour chaque colonne
ltwip = lpix * Screen.TwipsPerPixelX ' --->> sa traduction en twips
With MSFlexGrid1 '-----------------------------------------
.GridLines = 1
.GridLineWidth = 1
.BorderStyle = flexBorderNone
.ScrollBars = flexScrollBarNone
.Cols = nb
For i1 = 0 To nb - 1
.ColWidth(i1) = ltwip
Next i1
.Width = (nb * ltwip) - (1 * Screen.TwipsPerPixelX)
End With


(c'est tiré par les cheveux et je me suis mis dans la tête du créateur de cet activex pour tenter de deviner ses rattrapages, mais bon ...)


EDIT : je viens de faire de bon matin l'inverse (partir de la largeur totale que l'on veut).
Calculs un peu plus compliqués, mais faits. Le résultat est forcément alors une largeur "corrigée" (le twip n'étant pas, lui, une unité affichable)
Si cela t'intéresse également, dis-le


________________________
Nul ne saurait valablement coder ce qu'il ne saurait exposer clairement.
0
Bonjour,
.
Comme je dois tenir compte impérativement de la largeur du Mshflexgrid, l'exemple que vous me proposez Mr ucfoutu ne peut solutionner mon problème.
.
J'ai donc décidé d'abandonner ce programme que je voulais réaliser
pour mon usage personnel et surtout pour passer le temps.
.
Encore merci pour votre aide.
.
Très cordialement.
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
13 mars 2017 à 10:26
Voilà dans ce cas de quoi partir sur la base d'une largeur définie
lgtwip = 17000 ' =====>> la largeur totale que l'on veut, exprimée en twips
lgpic = lgtwip / Screen.TwipsPerPixelY ' on calcule sa correspondance en pixels
nb = 50
lpix = (lgpic - (nb - 1)) \ nb ' ===>> on en déduit la largeur de chaque colonne, en pixels entiers. On est
' de ce fait forcé de perdre quelques twips (insignifiant, mais ...)
' sur la largeur totale de la grille (ces twips ne peuvent être représentés
' puisque la plus petite unité affichable est le pixel
' ATTENTION : il s'agit bien de diviser avec \ (et non /)
ltwip = lpix * Screen.TwipsPerPixelY ' ===>> et on la traduit en twips
With MSFlexGrid1
.GridLines = 1
.GridLineWidth = 1
.BorderStyle = flexBorderNone
.ScrollBars = flexScrollBarNone
.Cols = nb
For i1 = 0 To nb - 1
.ColWidth(i1) = ltwip
Next i1
.Width = (nb * ltwip) - (1 * Screen.TwipsPerPixelY)
MsgBox "nous avons perdu forcément " & ((lgtwip - .Width) / nb) / Screen.TwipsPerPixelX & " pixels au total"
End With

On y perd forcément 1 ou 2 pixels (lorsque la division par le nombre de cellules n'est pas un entier en pixels).
0
Bonjour Mr. ucfoutu,

.
Je viens de faire plusieurs essais avec votre code, les résultats sont excellents.
.
Je reprends donc mon petit programme et vous remercie à nouveau
0
PS: Je n'ai pas trouvé le bouton "Résolu"
0
vb95 Messages postés 3472 Date d'inscription samedi 11 janvier 2014 Statut Contributeur Dernière intervention 13 avril 2024 169
Modifié par vb95 le 13/03/2017 à 12:38
Bonjour
C'est normal que vous n'ayez pas le bouton "Résolu"
Vous n'êtes pas enregistré ou vous avez ouvert le site sans vous "loguer" dessus avec votre pseudo et votre mot de passe ;
Je mets le sujet en résolu
Bonne fin de journée
0
Rejoignez-nous