Optimisation de code sur un USF
Bonjour,
Je suis en train de travailler sur un programme pour accélérer le traitement des commandes dans mon entreprise. Je me suis penché sur le langage VBA depuis quelques semaines et grâce à ce forum, j'avance un peu chaque jour.
Comme vous pourrez le voir en PJ, j'ai un premier USF qui permet d'aller chercher un fichier csv en local afin de l'importer dans une nouvelle feuille (Bouton IMPORTER), puis un second traitement (TRAITER) qui ouvre un autre USF de saisi à destination d'une douchette.
Certains points restent pour moi mystérieux malgré de nombreuses recherches ou tentatives :
- comment remplacer le contenu de TextBoxScan à chaque "flashage" de la douchette (l'utilisation de SetFocus reste obscure) ?
- comment, si la donnée recherchée via ce champ est présente plusieurs fois, afficher les occurrences correspondantes dans les TextBox en dessous ?
J'espère que mes questions sont assez claires, et j'imagine bien que mon code n'est pas encore très optimisé, j’essaie de commenter au maximum.
Merci à ceux qui prendront le temps de consulter mon fichier.
Je me sert pour le moment de ceci pour remplacer le contenu à chaque saisie :
UserForm2.TextBoxScan.SelStart = 0
UserForm2.TextBoxScan.SelLength = Len(UserForm2.TextBoxScan.Text)
UserForm2.TextBoxScan.SetFocusJe ne suis pas sûr de la pertinence du procédé....
Et j'utilise pour le moment ceci pour rechercher la donnée scannée/saisie, mais cela ne gère pas le cas où la valeur est présente plusieurs fois (j'aimerais une ligne / résultat) :
Private Sub TextBoxScan_Exit(ByVal Cancel As MSForms.ReturnBoolean)
'On sélectionne tout le contenu du champ avant saisie
UserForm2.TextBoxScan.SelStart = 0
UserForm2.TextBoxScan.SelLength = Len(UserForm2.TextBoxScan.Text)
UserForm2.TextBoxScan.SetFocus
'Fonction qui va rechercher la valeur ou partie de la valeur dans le fichier importé
If TextBoxScan <> "" Then
Set re = Range("B1:B5000").Find(TextBoxScan.Value, lookat:=xlPart)
If Not re Is Nothing Then
'color la cellule en vert
re.Interior.ColorIndex = 43
'Coche la cellule
re.Offset(, -1) = "X"
'Affiche la quantité et le casier de destination
UserForm2.TextBoxCasier.Value = Right(re.Offset(0, 6).Value, 1)
UserForm2.TextBoxNom.Value = re.Offset(0, 2).Value
Cancel = True
Else
'Informe de l'absence de la pièce dans le fichier de commande
UserForm2.TextBoxQte.Value = "ABSENT"
UserForm2.TextBoxCasier.Value = ""
Cancel = True
End If
End If
End SubBonjour,
Hum... Sans vouloir t'offenser, ça va être une histoire de ouf !
Je te retourne ton fichier modifier, pour illustrer un peu mon propos.
Le problème est que je ne vois pas trop ou tu veux en venir donc tu ne pourras pas trop en tirer quelque chose mébon...
Ce fichier ne répond qu'à la question comment parcourir toute les lignes et lire celles qui t'intéressent...
après savoir ce que tu veux faire de ce que tu as mis dans les TextBox, Bin... j'en sais rien !
Concernant le focus sur le textbox dans la mesure ou tu mets toujours le cancel = true puisqu'il n'y a rien d'autre à remplir, tu n'as pas besoin de SetFocus puisque tu ne peux pas sortir du TextBox...
Le problème est que tu ne peux même pas fermer le UserForm puisque tu ne peux pas quitter ton TextBox... Mébon tu pourras quand même quitter avec la croix de fermeture : Tu règleras le problème après...
Bref pour parcourir toutes les lignes find ne te sera d'aucune utilité : YAKE un moyen c'est... de parcourir toutes les lignes de la première à la dernière comme le fait mon programme.
En pratique on ne fait jamais ça parce que c'est souvent trop long, mébon c'est juste pour te donner des idées...
Pour la première référence je t'ai rajouté une occurrence pour que tu voies bien que le programme à parcouru toutes les lignes. Après comme je ne sais pas ce que tu fais des données relevées dans les autres TextBox je n'ai pas fignolé, mais au moins ça peux te donner des idées...
Bon tu me diras...
Ha, j'ai renommé les TextBox et j'ai donné le TabIndex 0 (zéro) à ton TextBox de saisie (tbScan)
Tu testeras avec TE28012 , puis avec une donnée absente et tu fermeras avec la croix de fermeture...
A+
Bonjour Galopin01 et merci pour ton retour,
L'objectif de l'USF2 est d'afficher les données suivantes suivant la valeur saisie :
- dans le TextBoxQte la quantité correspondant à la valeur si elle est présente dans le fichier importé
- dans le TextBoxCasier le dernier chiffre de la dernière colonne (qui détermine dans quel casier la pièce va être rangée)
Ce formulaire doit permettre à un opérateur muni d'une douchette de scanner les produits réceptionnés et de les répartir dans les bonnes quantités et dans les différents casiers de préparation.
Il se peut donc que pour une même référence (un même produit), il y ai une ligne avec la qté 2 et le casier 8, et une autre ligne avec la qté 1 et un autre casier (illustration en PJ).
Lorsque les lignes sont détectées, la colonne créée préalablement en A est cochée et permet de voir d'un coup d'oeil qu'elles pièces ont été reçues ou non.
J'ai bien testé le fichier sur lequel tu as travaillé et la boucle de recherche remonte bien les quantité mais un seul casier dans le cas de 2 lignes avec le même produit. Je cherche à utiliser la notion "lookat:=xlPart" si possible pour remonter un résultat même si la saisie n'est pas identique (ex de saisie: 28012, il trouve néanmoins la valeur dans la cellule ET28012). Je ne te cache pas que je ne suis pas Ouf dans la compréhension de ton code mais j'y travaille
Je vois aussi que dans le code, la feuille est directement nommée (Set Ws = Worksheets("Etesia-Wolf-02-03-20")), cela ne pose pas de soucis si nous souhaitons importer à chaque livraison de pièce un fichier différent (grâce à l'USF1 d'import) ?
J'espère que tout ça est assez clair, j'avais rédigé un mini cahier des charges (toujours pas Ouf) au départ de ce projet, je le met en PJ si cela peut aider à la compréhension.
Merci encore pour le temps passé, j'espère pouvoir renvoyer l'ascenseur d'une manière ou d'une autre.
PS : j'ai beau être jeune, je suis un grand fan des Shadoks !
La manière dont tu importe les données n'a pas d'importance.
Si tu veux une autre ligne pour le casier c'est pas un problème : YAKA remplaces la ligne .tbCasier par celle-ci :
.tbCasier = IIf(.tbCasier = "", Right(Ws.Cells(iR, 8), 1), .tbCasier & Chr(13) & Right(Ws.Cells(iR, 8), 1))Le problème c'est ce que tu fais de ces TextBox une fois que tu as scanné le premier ET28012 par exemple tout a été relevé dsns ces TextBox et le tbScan est vidé pour permettre une autre saisie, mébon :
Tu en fait quoi du tbQte et du tbCasier ? C'est bien joli de relever toutes les occurences mébon quand tu auras saisi ou flashé tout le monde tu vas avoir un tbQte avec 1,3,2,1,1 et une série de N° de casier qui ne vont pas te servir à grand chose.
Bref concrètement ce USF il sert à rien. Juste à flasher ce qui a déjà été importé mébon si tu sais lire ça sert pas à grand chose : Un UserForm ça sert pas à lire une Feuille, la plupart du temps ça sert plutôt à la remplir.
Compris ?
Sinon pour xlpart là tu peux oublier dans ce contexte ce n'est pas possible.
A+
D'accord, j'ai bien compris. Je n'utilise peut-être pas le bon outil pour afficher les informations à l'opérateur...
Le but est juste d'afficher la qté et le casier à l'opérateur (avant il recherchait sur un document papier parmi parfois 250 lignes !
Du coup tu conseillerais d'afficher cela plutôt dans un MsgBox ? Je ne connais pas bien les caractéristiques et la pertinence des outils.
Nous n'avons pas besoin de conserver ou de traiter les infos récupérées dans les TextBox, juste de "valider" les lignes traitées sur le fichier importé afin d'y extraire les "non validées" et donc déterminer les produits non reçus...
Si ça ne sert à rien pourquoi l'afficher ?
Dans ce cas le fichier joint suffit.
A+
J'ai besoin de 'l’afficher pour que l'opérateur sache où ranger la pièce reçue... mais pas de conserver l'affichage ou 'l’information. Bref, je suis en train de voir avec la première version que vous m'avez généreusement envoyé, je vais partir de cette base en cherchant comment modifier le problème du Focus et chercher une alternative à xlpart.
Merci beaucoup en tout cas
Dans ce cas je pense qu'un ListBox serait peut-être plus approprié : Je verrai cela dans un moment car je dois sortir.
A+
Tu peux peut-être essayer le fichier joint.
Il faudrait peut-être dimension le ListBox différemment (en fonction du nombre d'items), mébon pour l'instant ce n'est qu'une suggestion : Il faut d'abord voir si cette proposition est pertinente.
Comme précédemment le bouton est inefficace puisque on ne peut pas quitter le TextBox : Il faut donc quitter avec la croix de fermeture quand on a fini le job...
A+
J'ai un peu avancé mais je bute vraiment sur le clique sur le bouton (FinScan). Il est inactif car je n'arrive pas à sortir de la boucle qui permet de vider tbScan pour une nouvelle saisie de la douchette :
Private Sub tbScan_Exit(ByVal Cancel As MSForms.ReturnBoolean)
Dim Ws As Worksheet, iR&, iLR&, cherche$
Dim nb_feuilles As Long
With Me
cherche = .tbScan
Cancel = True
nb_feuilles = ActiveWorkbook.Sheets.Count
'Test du nombre de feuille pour continuer
For Each Ws In Worksheets
If nb_feuilles = "2" Then Exit For
Next
If Ws Is Nothing Then Beep: Exit Sub
Set Ws = Worksheets(2)
If .tbScan <> "" Then cherche = .tbScan
'Détermination de la dernière ligne de la colonne 2
iLR = Ws.Cells(Ws.Rows.Count, 2).End(xlUp).Row
For iR = 1 To iLR 'On examine chaque ligne
If Ws.Cells(iR, 6) = cherche Then 'Si la valeur recherchée est trouvée
Ws.Cells(iR, 2).Interior.ColorIndex = 43 'Coloration cellule ref
Ws.Cells(iR, 1) = "X" 'Coche case
.tbQte = IIf(.tbQte = "", Ws.Cells(iR, 3), .tbQte & Chr(13) & Ws.Cells(iR, 3))
.tbCasier = IIf(.tbCasier = "", Right(Ws.Cells(iR, Columns.Count).End(xlToLeft), 1), .tbCasier & Chr(13) & Right(Ws.Cells(iR, Columns.Count).End(xlToLeft), 1))
.tbNom = Ws.Cells(iR, 4)
.tbRefProd = Ws.Cells(iR, 2)
Exit For
Else
.tbQte.Value = ""
.tbNom = "ABSENT"
.tbCasier = ""
.tbRefProd = ""
End If
Next
.tbScan = ""
End With
End Sub
Private Sub FinScan_Click()
Unload Me
End SubEffectivement si tu ne peux pas quitter le TextBox, tu ne peux sortir qu'avec la croix de fermeture...
Et si tu testais mon dernier fichier joint. Je pense qu'il offre bien plus de possibilités d'amélioration. (mais pas au sujet de la sortie qui restera ainsi)
A+