Comment remplir un tableau word à partir de check-box et text-box d'un userform?

Fermé
isa38600 Messages postés 38 Date d'inscription samedi 27 août 2011 Statut Membre Dernière intervention 19 avril 2022 - 11 mai 2020 à 18:44
isa38600 Messages postés 38 Date d'inscription samedi 27 août 2011 Statut Membre Dernière intervention 19 avril 2022 - 12 juin 2020 à 14:14
Bonjour à toutes et à tous!

Dans le cadre de mon travail, je prépare un formulaire WORD qui sera rempli par une quarantaine d'utilisateurs différents à l'aide d'un USERFORM. Le document est quasiment prêt, la mise en page est faite, les signets sont placés, mais...

Le document final comporte 3 tableaux qui devront être remplis à partir des données renseignées dans le userform sous forme de checkbox et/ou de textbox. Et c'est là que ça coince!

J'arrive à récupérer la caption des checkbox pour les faire apparaître en colonne 1 de mon tableau, mais certaines checkbox nécessitent d'êtres complétées par une information que l'utilisateur devra saisir dans une textbox. Et je n'arrive pas à faire en sorte que les données saisies dans la textbox soient placées en colonne 2 mais sur la même ligne que la checkbox qui lui correspond!

Pour l'instant, seule la dernière textbox renseignée apparaît systématiquement dans la dernière ligne du tableau, et donc pas forcément en face du texte de la checkbox qu'elle est sensée compléter...

Comment puis-je faire pour m'assurer que le contenu de ma textbox apparaisse systématiquement sur la même ligne que la checkbox qui lui est associée?

Une fois ce problème résolu je m'attaquerai à la création d'un 4ème tableau qui contiendra 6 colonnes (nombre de lignes à définir par l'utilisateur car tout dépendra du nombre de groupes qu'il aura à renseigner, cela pourra être 1 seule ligne pour certains, et monter jusqu'à une 30aine pour d'autres...) Là encore, vos conseils seront plus que bienvenus sur la méthode la plus appropriée...

Un immense merci d'avance à tous! :)

Pour info:
Ce post est la suite de la discussion suivante: https://forums.commentcamarche.net/forum/affich-36595568-mettre-un-texte-par-defaut-dans-une-zone-de-texte-controle-activex#p36598117 mais comme la thématique abordée est trop différente du sujet de départ, j'ai préféré sur les conseils d'eriiic créer un nouveau post. Si ça peut aider d'autres personnes à régler le même problème que moi c'est tant mieux!

Et pour aider la boule de cristal d'eriiic à comprendre de quoi je parle, et tous ceux et celles qui voudront bien se pencher sur mon problème, vous trouverez mon document via le lien suivant:
https://www.cjoint.com/c/JElp6oZw6tz
(j'ai mis des commentaires dans le document aux emplacements de mes 4 tableaux)




Configuration: Windows / Chrome 81.0.4044.138
A voir également:

19 réponses

m@rina Messages postés 20087 Date d'inscription mardi 12 juin 2007 Statut Contributeur Dernière intervention 26 avril 2024 11 272
Modifié le 13 mai 2020 à 03:26
Bonjour,

Bon, l'ancien devenait illisible...

J'ai vu un peu les réponses d'Eric, et oui pour les cases à cocher "J'ai", "J'ai pas"... C'est inutile, ou t'as ou t'as pas.

Il y a sans doute plein de choses qui ne vont pas. Dans un premier temps, je suis choquée par la taille ! Pourquoi si grand ?? Il faut un écran 27" pour voir le formulaire en entier... Faut vraiment réduire tout ça, les espacements, la police trop grosse, etc.

Par ailleurs, je me suis arrêtée sur les dates. Faut une vérif pour être sûr que ce sont des dates, car avec tes listes déroulantes, on peut mettre un 31 février sans que Word ne lève le petit doigt.

Pour les tableaux, je n'ai pas encore compris la problématique, il faut que je regarde de plus près. Mais effectivement avec une Listbox, y a moyen de faire ce que tu veux.

m@rina

0
isa38600 Messages postés 38 Date d'inscription samedi 27 août 2011 Statut Membre Dernière intervention 19 avril 2022 2
13 mai 2020 à 15:44
Bonjour m@rina,

Merci pour tes remarques.

Je ne m'étais pas doutée un instant que la taille du userform puisse être un problème. J'avais volontairement fait quelque chose d'aéré et facile à lire pour le confort visuel des utilisateurs... Maintenant si ça doit poser problème sur des petits écrans effectivement c'est pas le top! Quelles dimensions préconises-tu pour être sûre que ça passe sur n'importe quel écran?

Pour les dates je vais voir ce que je peux faire pour mettre en place ma vérif. Je suppose qu'il faut faire appel à un code du type:
Si la valeur de la combobox "mois" est février, alors la valeur de la combobox "jour" doit être inférieure ou égale à 29. Et idem pour les mois de 30 jours évidemment. J'ai juste?

Pendant qu'on y est, si tu vois d'autres détails qui t'écorchent les yeux (je m'en excuse d'avance! ^^) n'aie pas peur de m'en faire part, je ne le prendrai pas mal, au contraire si ça me fait progresser c'est tout bénef!

Et effectivement pour les cases à cocher, j'ai tenu compte de vos remarques et je n'en ai gardé que 2: j'ai un bureau et j'ai un club house.

Bon mercredi!
0
m@rina Messages postés 20087 Date d'inscription mardi 12 juin 2007 Statut Contributeur Dernière intervention 26 avril 2024 11 272
13 mai 2020 à 22:10
Bonjour,

On peut déjà modifier le zoom. Dans ton document que j'ai modifié, j'ai mis le zoom à 70. Mais surtout, même si tu veux garder des caractères assez gros, il faut resserrer tout ça.

Pour les dates, non, non, on ne s'amuse pas à tester toutes les dates soi-même ! :)) On n'en finirait pas !!! Il y a des années bissextiles, et les mois n'ont pas tous le même nombre de jours. DOnc, on se contente de demander à Word si la date est valide. Je l'ai fait dans ton doc pour la date de publication : la macro teste la date une fois les 3 cases saisies, et si c'est pas bon, ça donne un message de date invalide.

Pour la listbox, je t'ai fait un exemple que tu peaufineras toi même avec les tailles, peut être avec des combobox comme j'ai fait pour le sexe, avec des tabulations qui vont bien, etc.

https://www.cjoint.com/c/JEnujGhbQbH

m@rina

ps : je viens de voir qu'Eric t'avait donné un exemple de ListBox... bon, tant pis, c'est fait... De toutes façons, fallait bien améliorer pour Word ! ;)

0
isa38600 Messages postés 38 Date d'inscription samedi 27 août 2011 Statut Membre Dernière intervention 19 avril 2022 2
14 mai 2020 à 12:01
Alors là tu viens de me faire gagner un temps considérable, merci beaucoup!

Ok pour le zoom, j'ai vu où se trouve la propriété, je m'y atèle, par contre je ne vois pas l'intérêt de resserrer du coup, si j'arrive à tout rentrer dans mon userform à 70%, autant que ça reste aéré non?
Je garde à l'esprit que j'ai beaucoup de personnes d'un certain âge parmi mes utilisateurs, le confort visuel aura sûrement un impact sur la qualité de remplissage de mon document.

D'ailleurs j'ai fait le test avec le document que tu m'as renvoyé, j'ai trouvé les CheckBox très petites pour le coup, ce qui rend leur sélection pas évidente. Connais-tu un moyen de les grossir sans pour autant grossir le texte de la caption?

Je m'attaque à toutes ces modifications cet après midi sur mon document original. Encore merci pour ton aide! :)
0

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

Posez votre question
isa38600 Messages postés 38 Date d'inscription samedi 27 août 2011 Statut Membre Dernière intervention 19 avril 2022 2
15 mai 2020 à 15:29
Bonjour m@rina, bonjour à tous,

Je te fais un petit retour sur mes essais d'hier à partir de tes propositions:

1. Problème avec le test de la date :
Lorsque je teste le remplissage du formulaire, dès que j’ai choisi le jour et que je clique pour choisir le mois, j’ai le message d’erreur suivant :
erreur de compilation: membre de méthode ou de données introuvable
le problème vient visiblement de cette ligne, le .datepub est en surbrillance :
Else: Me.datepub = ComboBox1JOUR.Value & " " & ComboBox2MOIS.Value & " " & ComboBox3ANNEE


2. Problème avec la listbox
Lorsque j’essaie de supprimer une ligne de ma listbox, j’ai une Erreur de compilation : variable non définie (maligne est en surbrillance)
Private Sub CB_suppr_Click()
'on supprime les lignes sélectionnées de la listbox
maligne = Me.ListBox1.ListIndex
If maligne <> -1 Then Me.ListBox1.RemoveItem ligne
End Sub


Je ne comprends pas pourquoi ça me fait ça alors que tout marchait bien dans tes documents. Il me semble avoir bien veillé à ce que tout soit renommé correctement par rapport à mon document de départ. Quelque chose m'échappe!

3. Questions concernant la listbox
Comment puis-je faire pour que l’utilisateur ait la possibilité de modifier une ligne déjà entrée dans la listbox ? Il faudrait que lorsque l’on clique sur le bouton « Modifier », les informations de la ligne apparaissent de nouveau dans les textbox et combobox, et que le fait de valider ne crée pas une nouvelle ligne mais mette les informations saisies à la place de la ligne existante.

Est-ce également possible de déplacer la ligne sélectionnée vers le haut ou vers le bas dans la listbox ? Si l’utilisateur se rend compte après avoir saisi ses groupes qu’il ne les a pas mis dans un ordre logique, il faudrait qu’il puisse y remédier sans avoir besoin de tout effacer et recommencer.

J'essaie de penser à tous les cas de figure qui risqueraient de se présenter, plus je creuse, plus je me rends compte que les possibilités sont infinies! J'ai encore plein d'idées d'optimisation que je garde pour plus tard... C'est presque déprimant lol

Bonne journée et bon week end :)
0
m@rina Messages postés 20087 Date d'inscription mardi 12 juin 2007 Statut Contributeur Dernière intervention 26 avril 2024 11 272
15 mai 2020 à 19:59
Bonjour

Rappelle toi quand même que tout ce qu'on te donne sont des exemples faits souvent rapidement, et qu'ensuite il faut peaufiner.

1) dans l'exemple donné, j'ai inséré une textbox nommée datepub qui reprend (en caché) la date puisqu'elle est saisie en 3 morceaux. ça permet de la conserver dans cette textbox pour l'envoyer facilement ensuite dans ton document.

2) Quand il y a "variable non définie"... c'est que euh.... comment dire ? .... que la variable maligne n'est pas définie ! OK, c'est Lapalisse qui l'aurait dit mais je peux difficilement dire autrement... Donc, faut la définir
https://docs.microsoft.com/fr-FR/office/vba/Language/Concepts/Getting-Started/declaring-variables
Quand on met Option Explicit (très recommandé), la déclaration des variables est obligatoire.

3) Pour donner la possibilité de modifier, faut faire l'inverse du bouton Ajouter Textbox vers listbox, et donc ce sera Listbox vers les Textbox, avec quelque chose comme ça :

x = Me.ListBox1.ListIndex
Me.TextBox1 = Me.ListBox1.List(x, 0)
Me.TextBox2 = Me.ListBox1.List(x, 1)
etc.

N'oublie que les colonnes de la Listbox commencent à 0.

Pour modifier l'ordre, peut être avec des boutons toupie (spinbutton).

m@rina



0
eriiic Messages postés 24570 Date d'inscription mardi 11 septembre 2007 Statut Contributeur Dernière intervention 23 avril 2024 7 214
15 mai 2020 à 22:49
Bonjour à toutes et tous,

un exemple de gestion de listbox : https://www.cjoint.com/c/JEpuWAzXh6V
eric
0
isa38600 Messages postés 38 Date d'inscription samedi 27 août 2011 Statut Membre Dernière intervention 19 avril 2022 2
16 mai 2020 à 14:44
Bonjour m@rina, bonjour eriiic, et les autres,

Merci m@rina pour l'explication, je comprends mieux! Je viens effectivement de voir la fameuse textbox datepub sur ton exemple. Si je comprends bien, l'intérêt est de n'avoir à créer qu'un seul signet pour placer ma date sur le document? Je vais essayer.

Et merci eriiic pour l'exemple d'utilisation de spinbutton, je vois mieux comment m'y prendre, j'essaie tout de suite.

Vous êtes tellement adorables, merci mille fois pour votre bienveillance et votre disponibilité!
0
isa38600 Messages postés 38 Date d'inscription samedi 27 août 2011 Statut Membre Dernière intervention 19 avril 2022 2
Modifié le 19 mai 2020 à 17:35
Bonjour à tous,

La sous douée du vba a encore besoin d'aide ????

Si ça peut vous rassurer j'ai quand même l'impression que je m'approche de plus en plus de la version finale de mon document... Mais j'ai encore quelques soucis avec ma listbox qui sert à remplir mon tableau 4:

1. Problème avec la colonne « commentaire » :
La 6 ème colonne de ma listbox n’apparaît pas dans le tableau de mon document , je ne comprends pas d’où vient ce problème…

2. Problème avec le spinbutton
J’arrive bien à déplacer la ligne sélectionnée vers le haut ou vers le bas, mais la mise en surbrillance ne se déplace pas avec la ligne, donc si on veut décaler une ligne de plusieurs crans, il faut la resélectionner à chaque fois et désélectionner la ligne qui se trouve du coup à sa place initiale... Le code que j’ai trouvé pour pallier à cela ne fonctionne pas.

3. Pour modifier une ligne déjà saisie
J’arrive à faire remonter les infos de ma listbox vers les textbox et combobox, pour les modifier, mais je ne sais pas comment m’y prendre pour que la ligne reste à la même place qu’au départ lorsque je revalide. Pour l’instant cela me supprime la ligne existante et en crée une nouvelle qui du coup se retrouve en bas.

4. Question bonus si cette option existe: Comment faire pour que la largeur des colonnes dans la listbox corresponde à la largeur des textbox et combobox du dessus ?

5. Question bonus N°2: Est-ce possible de grossir la taille des cases à cocher sans pour autant modifier la taille de la police? Je n'ai pas trouvé d'option qui fasse mon bonheur dans les propriétés de la checkBox...

Je vous joins le document dans sa forme actuelle pour que vous puissiez voir par vous-même: https://www.cjoint.com/c/JEtpEITIH66

Merci d'avance!
0
eriiic Messages postés 24570 Date d'inscription mardi 11 septembre 2007 Statut Contributeur Dernière intervention 23 avril 2024 7 214
Modifié le 19 mai 2020 à 19:54
Bonjour,

qq réponses.

2) tu as laissé la propriété MultiSelect à multi, il faut la passer en single.
Sinon ça se gère autrement. Il faut utiliser ListBox1.Selected(i) = True/False, i étant le n° d'item.
Ca me parait limite de conserver la multisélection. S'il t'en sélectionne 3, c'est laquelle qu'il veut éditer ? Mystère et boule de gomme.
Et puis tu vas t'amuser pour gérer les sélections des autres items (sélectionnés ou non) au fil du déplacement de celui à déplacer.
Faisable mais ça demande du temps et de la rigueur...

3) pourquoi tu supprimes la ligne à éditer de la listbox ?
Il faut la laisser et mettre un bouton de validation des modifs pour écrire là où tu as récupéré les éléments.

4) propriété ColumnWidths : 200;66;etc largeur des colonnes

5) pas de .Zoom sur ce contrôle, donc je dirais non.
Tu pourrais mettre un TextBox avec une coche qui se met et s'enlève sur l'événement MouseUp (pas d'événement Click sur les textbox), et un label à coté pour le libellé.
eric

Edit :
1)
peut-être parce que tu n'en mets que 5 ? ;-)
    For y = 0 To Me.ListBox1.ListCount - 1

        tablo4.Rows(y + 2).Cells(1).Range.Text = Me.ListBox1.List(y, 0)
        tablo4.Rows(y + 2).Cells(2).Range.Text = Me.ListBox1.List(y, 1)
        tablo4.Rows(y + 2).Cells(3).Range.Text = Me.ListBox1.List(y, 2)
        tablo4.Rows(y + 2).Cells(4).Range.Text = Me.ListBox1.List(y, 3)
        tablo4.Rows(y + 2).Cells(5).Range.Text = Me.ListBox1.List(y, 4)
    Next

Tu pourrais aussi y mettre une autre boucle pour les colonnes :
    For y = 0 To Me.ListBox1.ListCount - 1
        For col = 1 To 6
            tablo4.Rows(y + 2).Cells(col).Range.Text = Me.ListBox1.List(y, col - 1)
        Next col
    Next y



0
isa38600 Messages postés 38 Date d'inscription samedi 27 août 2011 Statut Membre Dernière intervention 19 avril 2022 2
Modifié le 20 mai 2020 à 17:17
Génial eric! J'ai bien avancé grâce à tes conseils :)

Il me reste un problème avec mon spin button que je n'arrive pas à résoudre: lorsque la ligne sélectionnée est tout en bas de la listbox, si l'utilisateur clique sur la flèche vers le bas (et on sait que ça va arriver!) ça me met un message d'erreur... Ce qui m'étonne c'est que je n'ai pas la même problème quand il s'agit d'aller vers le haut...
Voici le code utilisé pour l'instant:
Private Sub SpinButton1_SpinDown()
    Dim x, y
    Dim Suiv()
    ReDim Suiv(0 To 5)
    
    With ListBox1
        If .ListCount = 0 Then Exit Sub
        For y = 0 To 5
            Suiv(y) = .List(.ListIndex + 1, y)
            .List(.ListIndex + 1, y) = .List(.ListIndex, y)
            .List(.ListIndex, y) = Suiv(y)
        Next
        
        ' Resélection de l'élément déplacé
        .ListIndex = .ListIndex + 1
    End With
End Sub

Private Sub SpinButton1_SpinUp()
    Dim x, y
    Dim Prec()
    ReDim Prec(0 To 5)
    
    With ListBox1
        If .ListCount = 0 Or .ListIndex = -1 Or .ListIndex = 0 Then Exit Sub
        For y = 0 To 5
            Prec(y) = .List(.ListIndex - 1, y)
            .List(.ListIndex - 1, y) = .List(.ListIndex, y)
            .List(.ListIndex, y) = Prec(y)
        Next
        
        ' Resélection de l'élément déplacé
        .ListIndex = .ListIndex - 1
    End With
End Sub


J'ai essayé la méthode
On error Resume Next

Mais c'est pas mieux...

Concernant le problème de la taille des checkbox, je crois que je ne vais pas mettre en application ta proposition de les remplacer par des textbox car ça m'obligerait à revoir complètement mes codes de remplissage de mes tableaux 1, 2 et 3. Si j'avais un meilleur niveau ce ne serait peut être pas un problème, mais pour moi ça semble bien compliqué.

Du coup je me dis que la solution pour que l'utilisateur visualise bien ce qu'il a coché ou non serait de créer un événement qui change la couleur de la caption de mes chekbox lorsque leur valeur passe à True.

J'ai réussi à le faire pour une seule checkbox avec le code suivant:
Private Sub a1_Click()
If a1.Value = True Then
a1.ForeColor = RGB(0, 0, 255)
Else: a1.ForeColor = RGB(0, 0, 0)
End If
End Sub


Mais vu que j'ai pas mal de checkbox dans mon userform et que je vais devoir en ajouter encore quelques unes pour le tableau 3, je me dis qu'il serait préférable de faire une boucle pour ne pas avoir des kilomètres de code juste pour ça... Sauf que les boucles c'est pas mon fort, je galère à chaque fois... Voilà mon essai qui ne produit aucun effet:
Private Sub CheckBox_Click()
Dim cb As Control

For Each cb In Me.Controls
If TypeOf cb Is MSForms.CheckBox Then
If cb.Value = True Then
cb.ForeColor = RGB(0, 0, 255)
Else: cb.ForeColor = RGB(0, 0, 0)
End If
End If
Next
End Sub


Help please!
0
eriiic Messages postés 24570 Date d'inscription mardi 11 septembre 2007 Statut Contributeur Dernière intervention 23 avril 2024 7 214 > isa38600 Messages postés 38 Date d'inscription samedi 27 août 2011 Statut Membre Dernière intervention 19 avril 2022
Modifié le 20 mai 2020 à 23:08
Bonjour,

Il me reste un problème avec mon spin button que je n'arrive pas à résoudre
Reprend le modèle que je t'avais fait et qui fonctionne. Tu verras les différences.
Regarde les tests que je fais pour SpinUp et SpinDown

J'ai essayé la méthode On error Resume Next
Ah non, là on ne va plus être copains...
Ca sert à faire un vrai traitement d'erreur, pas à mettre la poussière sous le tapis.

je me dis qu'il serait préférable de faire une boucle
Sauf que l'utilisateur voudra sûrement voir l'effet dès qu'il coche, et pas quand il a tout coché via une boucle.
Pour pour ne pas avoir des km de code, écrit plus compact ;-)
Private Sub CheckBox1_Click()
    ActiveControl.ForeColor = IIf(ctrl, vbRed, vbBlack)
End Sub

Tellement compact que ça ne vaut pas le coup de faire un Sub commun ;-)
Mais si tu as d'autres actions à faire ça donnerait ça :
Private Sub CheckBox1_Click()
    couleur ActiveControl
End Sub

Private Sub couleur(ctrl As Control)
    ctrl.ForeColor = IIf(ctrl, vbRed, vbBlack)
    'autres action sur control
    '...
End Sub

Tu pourrais aussi mettre une belle grosse coche verte en label à gauche de tes cases à cocher (comme celle que je t'avais mis dans l'exemple et qui servait de bouton), que tu rends visible ou non sur l'événement Click.
Une fois que tu l'as faite, tu la propages par des copiés-collés.
eric
0
la reponse https://quicktripstips.com/comment-remplir-un-tableau-word-a-partir-de-check-box-et-text-box-dun-userform/
0
isa38600 Messages postés 38 Date d'inscription samedi 27 août 2011 Statut Membre Dernière intervention 19 avril 2022 2
20 mai 2020 à 18:55
Merci pour ta réponse sofiane, malheureusement cet article ne parle pas des userforms mais des contrôles de contenus, donc il ne peut pas m'aider...
0
isa38600 Messages postés 38 Date d'inscription samedi 27 août 2011 Statut Membre Dernière intervention 19 avril 2022 2
21 mai 2020 à 00:51
bonsoir eriiic,

Ah non, là on ne va plus être copains...
Ok promis je ne recommencerai plus! J'ai vu ce code dans un tuto qui donnait le résultat que je cherchais alors, en désespoir de cause...

J'ai finalement opté pour ton idée de coche dans un label vu que mon idée de boucle n'était pas bonne (je crois avoir compris pourquoi...). Pour la rendre visible ou non j'ai conservé la façon d'écrire IIF que tu viens de me faire découvrir et que je trouve plutôt pratique!

Par contre pour le spin button, ton code ne fonctionne que pour la colonne 1 (je sais c'est désespérant, je n'apprends pas vite, désolée) Je vois bien que je dois indiquer qu'il faut déplacer les colonnes de 0 à 5, mais j'ai encore du mal à le traduire en langage vba... Un jour peut être j'y arriverai!
0
eriiic Messages postés 24570 Date d'inscription mardi 11 septembre 2007 Statut Contributeur Dernière intervention 23 avril 2024 7 214
Modifié le 21 mai 2020 à 07:09
Bonjour,
Pour la rendre visible ou non j'ai conservé la façon d'écrire IIF
Là tu peux faire encore plus court :
labelCoche.visible=CheckBox1.Value


Par contre pour le spin button...
Copie-colle mon code que tu adaptes avec ton y, et tu ajoutes Ton For y= là où tu l'as mis.
Tu ne fais pas le bon test .ListIndex < .ListCount - 1 pour ne pas faire le dernier item justement puisque .List(.ListIndex + 1) n'existe pas.
Et pour SpinUp c'est If .ListIndex > 0 Then puisque le .ListIndex - 1 n'existe pas non plus.

Et tu n'as pas besoin d'un tableau suiv() ou prec().
Une seule variable tampon suffit puisque utilisée en fin de boucle, elle redevient disponible.
eric
0
isa38600 Messages postés 38 Date d'inscription samedi 27 août 2011 Statut Membre Dernière intervention 19 avril 2022 2
25 mai 2020 à 17:27
Bonjour eric,

Je reprends mon formulaire après ces quelques jours de repos. J'espère que tu as pu en profiter également.

Ce fichu code pour le spin button me fait encore de la résistance! Je suis repartie sur la base de ton code, en ajoutant mon for y à l'endroit que tu m'as indiqué et j'ai encore une erreur que je n'arrive pas à comprendre:

"erreur de compilation: incompatibilité de type" ... avec le y de ma ligne for y qui est en surbrillance.

Voici le code tel que je l'ai copié dans mon fichier:

Private Sub SpinButton1_SpinDown()

    Dim y As String
    With ListBox1
        If .ListIndex < .ListCount - 1 Then
            For y = 0 To 5
                y = .List(.ListIndex)
                .List(.ListIndex) = .List(.ListIndex + 1)
                .List(.ListIndex + 1) = y
                .ListIndex = .ListIndex + 1
            Next
        End If
    End With
End Sub

Private Sub SpinButton1_SpinUp()

    Dim y As String
    With Me.ListBox1
        If .ListIndex > 0 Then
            For y = 0 To 5
                y = .List(.ListIndex)
                .List(.ListIndex) = .List(.ListIndex - 1)
                .List(.ListIndex - 1) = y
                .ListIndex = .ListIndex - 1
            Next
        End If
    End With
End Sub


J'ai passé une bonne partie de l'après midi dessus, je craque un peu là mdr

Un petit conseil de plus serait le bienvenu... Merci d'avance!
0
eriiic Messages postés 24570 Date d'inscription mardi 11 septembre 2007 Statut Contributeur Dernière intervention 23 avril 2024 7 214
25 mai 2020 à 20:33
Bonjour,

Dim y As String
!!!! String = chaine
As Long pour un entier
A lire d'urgence ;-) https://www.excel-pratique.com/fr/vba/variables
Et si tu veux approfondir : https://silkyroad.developpez.com/VBA/LesVariables/
eric
0
isa38600 Messages postés 38 Date d'inscription samedi 27 août 2011 Statut Membre Dernière intervention 19 avril 2022 2
26 mai 2020 à 16:46
Bonjour eriiic,

Je suis désolée, je ne comprends pas ta correction...

Dans ton code, tu déclarais pourtant
Dim s As String
et cela marchait très bien.

J'ai été lire les 2 liens que tu me proposes pour en savoir plus sur les variables, effectivement je crois comprendre un peu mieux le concept général.

Alors si je comprends bien, on peut annoncer une variable de type string pour un tableau qui ne comporte qu'une colonne (comme dans ton exemple) car on n'a pas besoin de compter les colonnes, on s'attache donc à la chaîne de caractères.

Par contre pour un tableau à plusieurs colonnes, on doit les compter pour savoir combien en déplacer (dans mon cas), du coup la variable doit être de type numérique: byte, integer, long, currency, single ou double (plutôt une des 3 premières en l'occurrence vu qu'il s'agit de nombres entiers)

Sauf que:
- Dans ton post précédent, tu me dis de déclarer une variable de type long (d'après les définitions des variables de ton 1er lien, je ne comprends pas pourquoi ce choix plutôt que byte qui semble tout indiqué pour la novice que je suis, ou alors y'a encore un truc que j'ai pas compris! lol)

- Quand je fais la modification avec long à la place de string ça me marque de nouveau un message d'erreur:
"erreur d'exécution 13: incompatibilité de type"
sauf que cette fois ci c'est la ligne du dessous qui se retrouve en surbrillance
y = .List(.ListIndex)


Je ne sais plus de quel côté chercher là...
0
eriiic Messages postés 24570 Date d'inscription mardi 11 septembre 2007 Statut Contributeur Dernière intervention 23 avril 2024 7 214
26 mai 2020 à 20:17
Bonjour,

Sauf que:
- Dans ton post précédent, tu me dis de déclarer une variable de type long (d'après les définitions des variables de ton 1er lien, je ne comprends pas pourquoi ce choix plutôt que byte qui semble tout indiqué pour la novice que je suis, ou alors y'a encore un truc que j'ai pas compris! lol)

Tu as bien compris.
Dans un langage bien fait il faut utiliser Byte ou Integer si ils suffisent, c'est plus rapide.
Sauf qu'en VBA, excel les convertit en Long dans la majeure partie des cas. Du coup c'est plus lent qu'en Long directement, on y perd...
Donc oui, mais non ;-) T'embête pas, un entier : Long, un décimal : Single ou Double.

Je suis désolée, je ne comprends pas ta correction...
Dans ton code, tu déclarais pourtant Dim s As String et cela marchait très bien.

- Quand je fais la modification avec long à la place de string ça me marque de nouveau un message d'erreur:
"erreur d'exécution 13: incompatibilité de type"
sauf que cette fois ci c'est la ligne du dessous qui se retrouve en surbrillance
y = .List(.ListIndex)

J'avais mis s As String pour y mettre.... un String.
Le but est de permuter 2 valeurs chaines. Pour le faire on est obligé d'en sauvegarder une dans une variable avant de l'écraser avec l'autre, c'est le rôle de s. Un tampon temporaire.
Donc laisse tranquille mon s et remet
s = .List(.ListIndex) 


Et toi tu veux boucler sur les colonnes.
Donc tu déclares TA variable y As Long pour faire ta boucle (ou As Byte si tu veux).
Chaque variable a son rôle et doit être typée selon l'usage qu'on compte en faire, tu as besoin d'un entier.
Et tu remets la notion de colonne dans ta liste que tu as supprimée alors que tu l'avais bien mise auparavant :
s = .List(.ListIndex, y)
.List(.ListIndex, y) = ...
etc

Bon, fait à main levée faute de fichier pour tester mais c'est l'idée.
eric
0
isa38600 Messages postés 38 Date d'inscription samedi 27 août 2011 Statut Membre Dernière intervention 19 avril 2022 2
28 mai 2020 à 11:36
Décidément je n'arrive pas à voir ce qui coince...

J'ai pourtant essayé d'appliquer à la lettre tes conseils.

Je te joins mon fichier avec la dernière version de mes essais infructueux pour que tu voies par toi même ce que ça donne: https://www.cjoint.com/c/JECjFpuXoOJ

Je voudrais vraiment comprendre pour pouvoir m'en resservir par la suite sans avoir à embêter tout le monde...

Désolée d'être une si mauvaise élève, c'est frustrant de ne pas comprendre!
0
eriiic Messages postés 24570 Date d'inscription mardi 11 septembre 2007 Statut Contributeur Dernière intervention 23 avril 2024 7 214
Modifié le 28 mai 2020 à 19:49
Bonjour,

Rassure-toi, tu es loin d'être une mauvaise élève, tu es même au-dessus du panier ;-)

Le pb auquel je n'avais pas vu faute de pouvoir tester (pas trop envie de recréer un fichier) c'est que tu as mis :
.ListIndex = .ListIndex - 1

dans ta boucle y.
Donc forcément tu te retrouves avec un index hors limite.

Cette ligne sert juste à déplacer la sélection après avoir déplacé les données, et n'est donc à faire qu'une seule fois après ta boucle.
Private Sub SpinButton1_SpinUp()
    Dim y As Long
    Dim s As String

    With Me.ListBox1
        If .ListIndex > 0 Then
            For y = 0 To 5 ' déplacer les données
                s = .List(.ListIndex, y)
                .List(.ListIndex, y) = .List(.ListIndex - 1, y)
                .List(.ListIndex - 1, y) = s
            Next
            .ListIndex = .ListIndex - 1 ' déplacer la sélection
        End If
    End With
End Sub

idem pour SpinDown

eric

PS : Si jamais par la suite tu veux autoriser la multi-sélection, ListItem ne sera plus valable. Il faudra faire autrement en bouclant sur tous les items pour repérer les sélectionnés.

0
isa38600 Messages postés 38 Date d'inscription samedi 27 août 2011 Statut Membre Dernière intervention 19 avril 2022 2
29 mai 2020 à 11:40
Merci beaucoup eric, une fois de plus plus, ton aide a été d'un grand secours!

Je crois maintenant être arrivée à une version plutôt complète et fonctionnelle de mon userform. Il me semble avoir pensé à tous les scénarios possibles et avoir anticipé au maximum pour guider au mieux les utilisateurs.

Le tout est certainement perfectible, c'est la première fois que je me lance dans une telle entreprise, alors si vous avez des critiques à faire je prends!

Il me reste encore un petit point à ajouter pour être totalement satisfaite: Je voudrais ajouter des boutons de commande dans le document.
- Un pour effacer les informations saisies
- Un pour relancer le formulaire vierge
- Et enfin si cela est possible, un pour ré afficher le formulaire en conservant les informations saisies pour permettre de le corriger ou de le compléter. Je suppose que ça demande encore du codage pour que les corrections et/ou ajouts ne viennent pas se rajouter à côté des premières infos saisies… Je ne sais pas si c’est un procédé complexe ou non.

J’ai déjà créé celui qui ré affiche le formulaire vierge. Il fonctionne bien.

Celui pour effacer les données est créé également mais je n’ai pas encore trouvé le code pour que cela fonctionne.

Le 3ème pour modifier les réponses déjà validées, je n'ai pas encore osé m'y attaquer, je ne vois pas trop comment m'y prendre.

Mais surtout il y a un mystère que je ne m’explique pas : pourquoi j’arrive à masquer mes boutons pour l’impression (en passant par l’option Police > Masqué) uniquement en mode création… Dès que je désactive le mode création, les boutons se superposent donc je ne vois plus que celui pour ré afficher le formulaire vierge, et dans mon aperçu avant impression je le vois toujours… C'est très étrange car lorsque je suis en mode création, tout se passe très bien!

Je vous mets mon document dans sa forme actuelle pour constater par vous même: https://www.cjoint.com/c/JEDjGoTOddP

Merci d'avance pour ce qui, je l'espère, sera le dernier coup de pouce que je demanderai pour ce document!

Bonne journée,

Isa
0
eriiic Messages postés 24570 Date d'inscription mardi 11 septembre 2007 Statut Contributeur Dernière intervention 23 avril 2024 7 214
29 mai 2020 à 20:04
Bonjour,

- Un pour effacer les informations saisies
- Un pour relancer le formulaire vierge

C'est quoi la différence ?
Enregistre ton fichier en choisissant dans la liste déroulante le Type modèle : *.dotm
A l'ouverture une copie est crée à Enregistrer sous..., ton modèle reste vierge
Garde ta version *.docm pour les évolutions ultérieures.

il y a un mystère que je ne m’explique pas : pourquoi j’arrive à masquer mes boutons pour l’impression (en passant par l’option Police > Masqué
Utilise la propriété .Visible :
CommandButton1.Visible = True
CommandButton11.Visible = False




//////////////////////// maintenant : le lourd \\\\\\\\\\\\\\\\\\\\\\
- Et enfin si cela est possible, un pour ré afficher le formulaire en conservant les informations saisies pour permettre de le corriger ou de le compléter.
C'est là même chose, mais à l'envers :-)
Remplir tes contrôles à partir de la feuille.
Par exemple là où à l'enregistrement tu avais :
tablo1.Rows(nbl).Cells(1).Range.Text = cb.Caption

dans ta macro d'initialisation tu mets :
cb.Caption = tablo1.Rows(nbl).Cells(1).Range.Text

Parfois il faudra reconstituer ou au contraire découper l'information récupérée sur la feuille.
Par exemple le n° de SIRET qui est découpé dans le Userform.

Attention, ça va être assez long à expliquer, et c'est à lire lentement...
Eventuellement, tu pourrais t'aider en préparant dans les .Tag des contrôles (c'est une propriété à ta disposition pour y mettre ce que tu veux) un texte qui t'indiquera que tu as des données à récupérer et les élément nécessaires pour leur récupération.
Je vais prendre un exemple un peu compliqué, une écriture qu'il faudra découper pour restituer les valeurs.
Si tu comprends celui-ci, les cas simple ne te poseront pas de difficulté.

Lorsque tu enregistres le formulaire, ajoute une ligne pour le tag descriptif.
C'est toi qui choisi sa construction en fonction de ce que tu auras besoin comme infos pour restituer les données.
Ca n'est qu'une chaine, même pour les données numériques
Par exemple pour Tableau2 tu démarres ainsi :
    For Each cb In Me.Controls
        If TypeOf cb Is MSForms.CheckBox Then
            If (cb.Name) = "b1" And cb.Value = True Then
                nb2 = tablo2.Rows.Count
                tablo2.Rows.Add
                nb2 = nb2 + 1
                tablo2.Rows(nb2).Cells(1).Range.Text = cb.Caption + Me.surface1.Text + "m²."

Si la check box est cochée (elle sert vraiment elle ??), tu mets dans Tables(2) ligne nb2 colonne 1 la concaténation du Caption et du Text (2 contrôles)
ajoute cette ligne en-dessous :
cb.tag = "type1,2,nb2,1,cb.name,surface1"

Ne pas insérer d'espace après les "," sinon il faudra en tenir compte lors du découpage.
Ca te liste d'où vient ce que tu as écris dans ton tableau : le type de restitution que tu as prévu, le n° du tableau utilisé, sa cellule (ligne, colonne), que tu as un checkbox cb.name à mettre à jour, ainsi qu'un textbox surface1
Comme le tag est mis sur la chekbox, ne pas en mettre sur celui de la textbox puisque qu'elle sera traitée en même temps.

Pour la restitution, il faut boucler sur tous les contrôles et regarder si un tag a été mis.
Si oui, mettre à jour les contrôles concernés en découpant la donnée de la cellule.
Exemple (non testé) :
Sub initForm()
     ' boucler sur les contrôles
     ' pour traiter ceux avec un Tag
    Dim ctrl As Control
    For Each ctrl In UserForm1.Controls
        Select Case TypeName(ctrl)
        Case "CheckBox"
            If ctrl.tag <> "" Then recup ctrl.tag ' on appelle un sub en lui passant en paramètre le tag
        Case "TextBox"
        
        Case "ComboBox"
        
        End Select
    Next ctrl
End Sub

Sub recup(tag As String)
    Dim dataTable As String
    Dim tmp, tmp2
    ' rappel constitution du tag type1 :
    'cb.tag = "type1,2,nb2,1,cb.name,surface1"

    ' découpage du Tag sur la ,
    tmp = Split(tag, ",")
    ' on récupère un tableau :
    'tmp(0) : type
    'tmp(1) : n° Table
    'tmp(2) : ligne table
    ' etc
    With UserForm1
        Select Case tmp(0)    ' type
        Case "type1"

            ' lecture de la cellule
            dataTable = ActiveDocument.Tables(tmp(1)).Rows(CLng(tmp(2))).Cells(CLng(tmp(3))).Range.Text
            '******
            ' tu as 2 données dans la cellule du tableau
            ' en supposant que le séparateur est l'espace,
            'à sa gauche tu as le caption de cb, à sa droite la surface
            tmp2 = Split(dataTable, " ")    ' on découpe sur l'espace
            ' si tu as qq part une cellule où il y aurait plusieurs mots pour une donnée,
            ' il faudra que tu ajoutes un séparateur (par exemple ", ") au moment de l'écriture
            ' qui ne servira qu'à ça : découper.
            ' La chaine de séparation choisie ne devra pas être présente ailleurs dans le texte !!!

            ' maj du checkbox
            .Controls(tmp(4)).Value = True
            .Controls(tmp(4)).Caption = tmp2(0)    ' partie gauche du texte récupéré
            ' maj du textbox
            .Controls(tmp(5)).Text = Left(tmp2(1), Len(tmp2(1) - 3))    ' tmp2(1) :partie droite du texte récupéré,
            ' dont on prend la partie gauche : il faut enlever "m²."

        Case "type2"
            ' tu te crées les types nécessaire au fur et à mesure des besoins
        Case "type 3"
            ' etc
        Case Else
            msgbox "pb, tag type inconnu"
        End Select
    End With
End Sub


Non testé, il est possible, et même probable, qu'il y ait des approximations et des erreurs de syntaxes à corriger.
Bon courage, avec 2 dolipranes ça devrait passer ;-)
eric
0
eriiic Messages postés 24570 Date d'inscription mardi 11 septembre 2007 Statut Contributeur Dernière intervention 23 avril 2024 7 214
12 juin 2020 à 12:57
Bonjour,

tu as réussi à t'en sortir ?
eric
0
isa38600 Messages postés 38 Date d'inscription samedi 27 août 2011 Statut Membre Dernière intervention 19 avril 2022 2
12 juin 2020 à 14:14
Bonjour eric,

Merci de venir aux nouvelles!

Malheureusement non je n'ai pas encore réussi à résoudre ce dernier petit problème, je suis plutôt en train d'envisager de me passer de cette dernière option parce que le temps me manque pour faire de nouveaux essais maintenant que je suis de retour au bureau...

Comme d'habitude quand j'aborde une nouvelle macro, j'ai du mal à saisir la "philosophie du système", où placer mes lignes de commande, dans quel ordre etc... Quand je lis tes explications, j'ai l'impression d'avoir à peu près compris, mais la mise en pratique ne fonctionne pas, et je ne suis pas encore capable de comprendre ce que signifient les messages d'erreur et comment y remédier sans appeler une nouvelle fois au secours!

Bref, je ne sais pas trop si j'irai au bout ou si je présenterai le projet aux dirigeants en l'état.

Dans tous les cas, je te remercie mille fois pour tout ce temps que tu m'as gentiment accordé, pour ta pédagogie et tes encouragements qui m'ont énormément aidée :)
0