Copier dans une listbox d'un userform

Bonjour,

Je démarre en VBA avec excel. Le fichier excel est un fichier d'inventaire de stock. Le but de cette VBA est de pouvoir a l'aide d'un userform aller voir dans chaque page de mon classeur ( 1 page = 1 fournisseur ) la liste des pièces à commander ( si la colonne g de la feuille sélectionné est égale à 0). Et de renvoyer ensuite toutes les lignes des pièces à commander vers une listbox. Pour ensuite à l'aide d'un autre bouton pouvoir exporter (de cette listbox) le nom et la référence de la pièce vers un fichier txt ou un mail.

En revanche je bloque dans mes lignes de codes pour sélectionner ma listbox1 afin d'y copier mes lignes remplissant mes conditions.

Si quelqu'un pouvait m'aider, j’apprécierais grandement. Je ne veux pas une solution toute faite. J'aimerais comprendre mon erreur afin de progresser et a terme ne plus avoir besoin d'aide mais aider les autres .

Merci par avance à celui qui m'aidera.

Voici les lignes de codes de la photo :

Private Sub pièces_Click()

If OptionButton1 = True Then

Sheets("Shimadzu").Select

Else: End If

FinalRow = Cells(Rows.Count, 1).End(xlUp).Row

For x = 2 To FinalRow

Thisvalue = Cells(x, 7).Value

If Thisvalue = 0 Then

Cells(x, 1).Resize(1, 33).Copy

nextrow = Cells(Rows.Count, 1).End(xlUp).Row + 1

Cells(nextrow, 1).Select

With Me.ListBox1.Selected

ListBox.Paste

ElseIf Thisvalue <> 0 Then

End If

Next x

If OptionButton2 = True Then

Sheets("Sciex").Select

Else: End If

If OptionButton3 = True Then

Sheets("Brechbulher").Select

Else: End If

If OptionButton4 = True Then

Sheets("Autres").Select

Else: End If

End Sub

exemple

Bonjour et sur le forum,

Comme tu es nouveau/nouvelle sur le forum, tu ne sembles pas bien connaitre les bonnes habitudes pour poster un sujet, pour aider quelqu'un de manière efficace, on aime bien avoir des fichiers Excel comme celui que tu as pris en photo

Si le souci est que tu as des données confidentielles, tu peux toujours mettre des noms de fournisseurs bidons, des articles bidons, des faux prix, enlever le logo de ton entreprise...

Si tu peux nous fournir un fichier non confidentiel, ce sera déjà plus simple de visualiser et tester ton code afin de t'indiquer à quel(s) endroit(s) tu as fait des erreurs

Effectivement c'est plus simple pour vous. Voici donc le fichier avec les données confidentielles enlevées et des données "bidon" ajoutées mais peu importe je transposerai par la suite .

Merci de cette réponse rapide.

25test-fav-forum.xlsm (52.95 Ko)

Bonjour!

Maintenant que je vois un peu ton fichier et le reste je vois déjà mieux ce que tu veux faire, et grâce à la fenêtre VBA je vois mieux l'erreur que tu as fait

Quand tu écris:

    If OptionButton1 = True Then
        Sheets("Shimadzu").Select
    Else: End If
            FinalRow = Cells(Rows.Count, 1).End(xlUp).Row
            For x = 2 To FinalRow
                Thisvalue = Cells(x, 7).Value
                    If Thisvalue = 0 Then
                    Cells(x, 1).Resize(1, 33).Copy
                    nextrow = Cells(Rows.Count, 1).End(xlUp).Row + 1
                    Cells(nextrow, 1).Select
                    With Me.ListBox1.Selected
                    ListBox.Paste
                    ElseIf Thisvalue <> 0 Then
                End If
            Next x
    If OptionButton2 = True Then
        Sheets("Sciex").Select
    Else: End If
    If OptionButton3 = True Then
        Sheets("Brechbulher").Select
    Else: End If
    If OptionButton4 = True Then
        Sheets("Autres").Select
    Else: End If

Cela revient à écrire:

Private Sub pièces_Click()
    If OptionButton1 = True Then
        Sheets("Shimadzu").Select
    Else: End If 'sinon je ne fais rien...
            'Je fais mon programme
    If OptionButton2 = True Then
        Sheets("Sciex").Select
    Else: End If
    If OptionButton3 = True Then
        Sheets("Brechbulher").Select
    Else: End If
    If OptionButton4 = True Then
        Sheets("Autres").Select
    Else: End If
End Sub

En clair, si le premier bouton est sélectionné, tu sélectionnes sa feuille, sinon rien, puis tu fais ton programme d'import, et ensuites tu regardes si un autre des boutons est sélectionné pour sélectionner sa feuille, ce qui ne sert plus à grand chose à cette étape, la partie importante de ton programme est déjà finie.

La logique voudrait que tu écrives plutôt ton programme comme ceci:

Private Sub pièces_Click()
    'choix de la feuille
    If OptionButton1 = True Then
        Sheets("Shimadzu").Select
    Else: End If
    If OptionButton2 = True Then
        Sheets("Sciex").Select
    Else: End If
    If OptionButton3 = True Then
        Sheets("Brechbulher").Select
    Else: End If
    If OptionButton4 = True Then
        Sheets("Autres").Select
    Else: End If

    'Je fais mon programme
End Sub

Tes Conditions aussi sont améliorables, quand tu écris:

    
    If OptionButton1 = True Then
        Sheets("Shimadzu").Select
    Else: End If

ça revient à écrire:

    If OptionButton1 = True Then
        Sheets("Shimadzu").Select
    End If

Quand tu mets Else, c'est que tu t'attends à ce que le programme fasse autre chose, comme afficher un message par exemple, mais ici, comme tu ne fais rien, ce n'est pas la peine.

Ta suite de If peut d'ailleurs s'écrire:

    If OptionButton1 = True Then
        Sheets("Shimadzu").Select
    ElseIf OptionButton2 = True Then
        Sheets("Sciex").Select
    ElseIf OptionButton3 = True Then
        Sheets("Brechbulher").Select
    ElseIf OptionButton4 = True Then
        Sheets("Autres").Select
    End If

ça revient exactement à la même chose que ce que tu as mis plus tôt

On peut même se permettre d'écrire ça:

    If OptionButton1 Then
        Sheets("Shimadzu").Select
    ElseIf OptionButton2 Then
        Sheets("Sciex").Select
    ElseIf OptionButton3 Then
        Sheets("Brechbulher").Select
    ElseIf OptionButton4 Then
        Sheets("Autres").Select
    End If

La raison c'est qu'un test logique renvoie soit True, soit False, et que ces contrôles stockent en valeur soit True, soit False, tu n'as donc pas à retester que la valeur soit True ou False à la limite, si tu veux que le contrôle ne soit pas sélectionné, tu peux écrire:

If Not OptionButton1

Un autre souci avec ton programme, tu ne gères pas le cas où aucun bouton n'est sélectionné, ce qui peut-être un gros souci, un moyen simple d'y remédier c'est de mettre la valeur par défaut du premier bouton à True, tu peux changer ça dans ses propriétés

Je te laisse déjà digérer tout ça, si tu as besoin de voir à quoi ressemble le résultat après toutes ces modifications, tu me le diras et je te le transmettrai

Super !!!! C'est deja top et beaucoup plus lisible. J'ai repris le fichier en tenant compte des remarques et j'obtiens au final ceci.

En revanche je n'ai toujours pas de piste pour la suite. Pourrais-tu m'orienter ?

Merci encore de prendre le temps de regarder.

17test-fav-forum.xlsm (52.88 Ko)

Re,

super, on peut donc passer à la suite, le programme que tu as mis pour faire ta copie:

FinalRow = Cells(Rows.Count, 1).End(xlUp).Row 'ok
For x = 2 To FinalRow 'ok
    Thisvalue = Cells(x, 7).Value 'ok mais ne mets pas .value, ça ne sert pas
    If Thisvalue = 0 Then 'ok
        Cells(x, 1).Resize(1, 33).Copy 'pas d'accord
        nextrow = Cells(Rows.Count, 1).End(xlUp).Row + 1 'je ne comprends pas à quoi sert cette ligne
        Cells(nextrow, 1).Select 'ni celle la
        With Me.ListBox1.Selected 'pas d'accord non plus
        ListBox.Paste 'pas d'accord
    ElseIf Thisvalue <> 0 Then 
    '???
    End If
Next x

Comme tu peux voir, j'ai pas mal de choses avec lesquelles je ne suis pas d'accord, on va faire chaque chose une par une:

le .value, en fait, de ce que j'ai compris, cette propriété d'un contrôle ou d'un objet ne sert que si tu utilises quelque chose comme:

With MonContrôle
    msgbox(.caption)
    msgbox(.value)
End With 'ne pas m'oublier

En fait, quand tu écris Range("a1"), ça fait tout de suite référence à la valeur de la cellule A1 de la feuille active, le .value sert quand tu dois faire appel à la valeur et que tu as déjà mis ton contrôle ou objet dans un With, le seul moyen d'appeler sa valeur c'est de mettre .Value

La raison pour laquelle je ne suis pas d'accord avec la ligne .Copy, c'est que je ne comprends pas pourquoi tu prends 33 colonnes, et pourquoi tu veux copier les valeurs de cette façon, surtout que ça ne va pas marcher avec ta Listbox, elles sont un peu... "sensibles" on va dire, pour insérer des données dans ce type de contrôle, c'est "compliqué".

Ensuite:

With Me.ListBox1.Selected

Si tu regardes le contrôle Listbox avec l'explorateur d'objet, que tu regardes ensuite la propriété selected de ce contrôle, tu as cette information: Selected(pvargIndex) As Boolean

Cela veut dire que la fonction Selected renvoie une variable booléenne, et a besoin d'un index pour te dire si il est sélectionné, cet argument est obligatoire car pas mis entre crochets comme ça : [variable facultative]

Cette propriété sert à savoir si une ligne précise de ta ListBox est sélectionnée ou non, la fonction renvoie True si c'est le cas.

Je pense que tu voulais écrire :

With ListBox1

"Me" n'est pas nécessaire d'ailleurs

ListBox.Paste, je ne suis pas d'accord avec ça non plus car si tu tapes ListBox1.Paste, tu ne trouveras rien qui y correspond, aucune fonction, aucune propriété, un contrôle listbox ne connaît pas, et ne pourra rien en faire, je t'expliquerai comment ajouter des infos à une listbox, mais si tu veux chercher un peu, il faut utiliser la méthode/fonction Add, pour enlever un élément, utiliser Remove.

Je te laisse encore digérer tout ça et me retire pour aujourd'hui

Je te remercie encore une fois pour cette aide ci précieuse.

J'ai pu bien avancer et j'arrive maintenant à cela (cf fichier joint). J'arrive donc à renvoyer la colonne référence dans ma listbox1 si une ou plusieurs valeurs sont égales à 0. J'aimerais savoir s'il était possible de renvoyer une ligne ou (encore mieux) un tableau réduit par rapport à celui de la page avec seulement les deux premières colonnes (si non vides) et la ref.

Et une fois que j'arriverais à compiler tout cela, j'aimerais ensuite exporter ma listbox1 vers un fichier txt ou un mail mais chaque chose en son temps .

Bonne soirée.

20test-fav-forum.xlsm (48.94 Ko)

Bonjour,

bien joué

Ton code est encore améliorable mais il fonctionne, c'est déjà ça

On va d'abord se concentrer sur le fait de le faire fonctionner, donc tu ajoutes un item à ta listbox, tu crées donc une nouvelle ligne de données dans ce contrôle, par contre, une fois que tu as crées cette ligne, il faut pouvoir ajouter des choses sur les autres colonnes.

Je t'explique un peu (avec ce que je sais )

Avec une ListBox, pour ajouter 3 informations sur une ligne, il faut déjà que ton contrôle puisse contenir 3 colonnes, ça se gère avec la propriété ColumnCount qu'il faut alors passer à 3.

Pour créer ta ligne qui contiendra les 3 informations, il faut d'abord crée cette ligne avec le contenu de la première colonne, en utilisant ListBox.AddItem, ça tu sais le faire mais ensuite... il faut pouvoir ajouter les 2 autres colonnes, et c'est pas très pratique, mais il faut procéder de la façon suivante...

ListBox.List(ligne,colonne) = TaValeur

Sachant qu'un contrôle ListBox commence à la ligne 0, et à la colonne 0, pour savoir à quelle ligne tu te trouves, tu peux utiliser ListBox1.ListCount - 1

ça donnerait:

ListBox1.AddItem valeur1
ListBox1.List(ListBox1.ListCount - 1, 1) = valeur2
ListBox1.List(ListBox1.ListCount - 1, 2) = valeur3

De cette façon, tu pourras créer tes 3 colonnes de données

Pour gérer la largeur des colonnes... Je t'invite à te diriger vers la propriété suivante : ColumnWidths

Le lien pour la documentation de la propriété : https://docs.microsoft.com/fr-fr/office/vba/api/access.listbox.columnwidths

Courage!

Bonjour,

J'ai réussis enfin à faire presque tout ce que je voulais ...lol

J'arrive à faire apparaître les colonnes que je veux, les dimensionner comme cela m'arrange. Et même jusqu'à exporter ma listbox jusqua un fichier txt. (rien d'exceptionnel pour vous autres mais un grand pas pour moi ^^).

En revanche le transfert sur le fichier txt fait n'importe quoi. Pourrait-on voir ensemble pour avoir l'améliorer ? Le but est d'obtenir le contenue de ma listbox dans un tableau et, si c'est pas trop demander, de créer des en-têtes dans le fichier txt. Par la suite le but est d'envoyer ce fichier txt par mail à une autre personne afin de passer commande des pièces manquantes (par mail tout simplement pas de vba quoique..... haha... ).

Merci encore pour l'aide apportée et celle qui va suivre.

30test-fav-forum.xlsm (56.02 Ko)

Bonjour,

Bien joué

Pour l'export en fichier texte... Je dois avouer que je n'y connais rien, donc je suis allé regarder un exemple sur la documentation de microsoft pour la fonction Print: https://docs.microsoft.com/fr-fr/office/vba/language/reference/user-interface-help/printstatement

On va d'abord voir les "bugs" de ton code

Print #1, CStr(ListBox1.ListCount)

Je ne sais pas pourquoi, mais visiblement tu souhaites exporter le nombre de lignes que tu as dans ta Liste, je ne suis pas sûr que c'était ce que tu voulais faire....

For i = 0 To ListBox1.ListCount - 1
    Print #1, ListBox1.List(i)
Next

La boucle est niquel, par contre la façon dont tu écris dans le fichier est erronnée

premièrement car comme ta liste a plusieurs lignes et plusieurs colonnes, il faut préciser ces 2 choses, quand tu écris ListBox1.List(i,0) pour exporter la première colonne de la ligne par exemple

Ensuite l'instruction Print, de ce que j'ai compris, cette instruction écrit à chaque fois sur une nouvelle ligne, du coup il faut exporter toutes les colonnes d'un coup avec cette instruction

Je me suis donc permis de modifier un peu ton code pour l'export, ce qui me donne quelque chose comme ça:

Private Sub CommandButton2_Click()
Open "C:\Users\DY3H\Desktop\pieces.txt" For Output As #1
Print #1, "Dénomination"; ";"; "Référence"; ";"; "Stock mini tampon"; ";"; "Fournisseur" 'en-têtes

For i = 0 To ListBox1.ListCount - 1
    Print #1, ListBox1.List(i, 0); ";"; ListBox1.List(i, 1); ";"; ListBox1.List(i, 2); ";"; ListBox1.List(i, 3)
Next
Close #1
End Sub

Explications:

Print #1, "Dénomination"; ";"; "Référence"; ";"; "Stock mini tampon"; ";"; "Fournisseur" 'en-têtes

Ce code permet d'écrire les en-têtes dans ton fichier texte, le format d'export est un peu particulier tu l'auras remarqué, je fais:

texte1; ";"; texte2; ";"; texte3; ";"; texte4

Je rajoute à chaque fois un séparateur pour indiquer les différentes colonnes, sinon ça te met tous les texte collé... et du coup après ça devient impossible de travailler avec... J'ai choisi le point virgule comme séparateur, c'est simple et visible

Du coup pour le reste des données j'ai utilisé la même syntaxe:

Print #1, ListBox1.List(i, 0); ";"; ListBox1.List(i, 1); ";"; ListBox1.List(i, 2); ";"; ListBox1.List(i, 3)

j'ai juste changé le numéro de colonne à chaque fois

Je te laisse tester et me dire ce que tu en penses, et surtout comprendre et assimiler tout ça!

Pour ce qu'il reste à faire, tu me diras quand tu voudras t'en occuper (optimisation etc...)

Bonjour,

Je viens de mettre à jour l'instruction mais celle-ci m'affiche l'erreur suivante : "objet requis" sur la ligne entre for et next. Je ne vois pas d'ou provient l'erreur étant donnée que la ligne est semblable à celle ou l'on définit les en-têtes (sans erreur).

De plus j'aimerais ajouter un bouton supplémentaire, export vers mail afin d'ouvrir un mail (Microsoft Outlook) et faire la même chose que sur le fichier txt. Déjà, est-ce possible ? Et peut-on voir cela ensemble ?

Pour finir, je me suis amusée à ajouter des petites macros pour chaque fournisseur afin qu'à chaque réception de pièce ou utilisation d'une pièce, on ne perd pas son temps à chercher la pièce dans le tableau. Pourriez-vous jeter un œil ? Le code fonctionne correctement pour l'ajout et la suppression mais je pense que la syntaxe du code n'est peut-être pas des plus traditionnelle haha...

Merci

47test-fav-forum.xlsm (61.87 Ko)

Re,

C'est très étrange que tu aies une erreur au niveau de cette ligne de code, je l'ai testée chez moi avant de te l'envoyer, et ça présentait aucun problème... Ah moins qu'il ne trouve plus la listbox, je ne comprends pas bien...

L'envoi de mail ce n'est pas quelque chose que je sais bien faire, mais on peut trouver des informations sur internet (comme pour l'export en texte), en tout cas oui c'est possible, il existe un objet qui définit l'application Outlook, on peut envoyer un mail automatiquement via VBA, mais je dois avouer que je n'ai jamais fait de programme pour ça

Pour ce que tu as ajouté, l'idée est bonne, mais par contre la forme est à revoir, tu as fait 4 fois le même formulaire pour changer de fournisseur, et il faut connaître par coeur le code de la référence pour faire la modification.

J'aurais plutôt vu ça avec une liste déroulante pour choisir le fournisseur, une liste déroulante pour le code article comme ça on peut être guidé pour la saisie, voir la désignation de l'article et le stock quand on met le code, ou pouvoir chercher l'article suivant la désignation, permettre de modifier directement la valeur soit en tapant +20, -100..., soit en tapant directement la valeur de stock que l'on souhaite.

ça demande plus de codage mais ça ferait un formulaire pratique à utiliser

Re,

J'ai trouvé la bêtise que je viens de faire, il manquer le 1 sur la dernière commande listbox1 d'ou l'objet non défini ......

Je suis perfectionniste (et je m'en excuse lol). L'export vers le fichier txt se fait très bien, mais est-il possible d'écarter les colonnes pour une meilleures visibilités ?

Et oui votre solution semble plus simple d'utilisation que la mienne. Je vais essayer de faire cet outil et vous le présenter.

Merci encore c'est top

Re,

Ah mais tu souhaites aller regarder dans ton fichier texte?

Je ne fais jamais ça moi Si tu veux consulter un fichier texte sur Excel tu peux utiliser "Données" puis "importer à partir d'un fichier texte", choisir délimité et choisir point virgule en délimiteur

Rechercher des sujets similaires à "copier listbox userform"