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
Bonjour et
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.
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 IfCela 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 SubEn 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 SubTes 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 IfQuand 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 IfLa 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
If Not OptionButton1Un 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.
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 xComme 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'oublierEn 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.SelectedSi 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.
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 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
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) = valeur3De 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.
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)
NextLa 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 SubExplications:
Print #1, "Dénomination"; ";"; "Référence"; ";"; "Stock mini tampon"; ";"; "Fournisseur" 'en-têtesCe 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
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