VBA faire une RECHERCHEV sur un grand nombre de cellule d'une même colonne
Bonjour à tous,
Je débute en VBA et j'ai besoin de votre aide. J'ai un fichier composant de 3 feuilles: Devis, Base, Prix négocié.
La feuille "Base" comporte tout les cas de figures "d'ensemble de produit" avec leur prix de revient. Elle est en interaction avec la feuille "Prix négocié" dans le cas où nous devons changer le prix du bois ou du miroir dans un ensemble de produit.
Bien sur, ces deux feuilles sont en lien avec le feuille "Devis". Le lien se fait au niveau du prix de revient et de sa décomposition.
Aujourd'hui, j'aimerais mettre à jour tout les prix dans le cas où on renégocierait le prix du bois ou du miroir, à l'aide du bouton "Mettre à jour le prix de revient".
J'ai déjà trouvé une programmation pour la première ligne (ligne 5):
Sub Bouton9_Cliquer()
If Range("A5") = "" Then
Range("H5") = ""
Else
Range("H5") = Application.VLookup(Range("A5"), Sheets("Base").Range("A7:L17"), 7, False)
Range("K5") = Application.VLookup(Range("A5"), Sheets("Base").Range("A7:L17"), 8, False)
Range("L5") = Application.VLookup(Range("A5"), Sheets("Base").Range("A7:L17"), 9, False)
Range("M5") = Application.VLookup(Range("A5"), Sheets("Base").Range("A7:L17"), 10, False)
Range("N5") = Application.VLookup(Range("A5"), Sheets("Base").Range("A7:L17"), 11, False)
Range("O5") = Application.VLookup(Range("A5"), Sheets("Base").Range("A7:L17"), 12, False)
End If
End SubCependant, il se peut que nous ajoutions un certain nombre de ligne dans le devis et le code risque de se démultiplier. Et je ne me vois pas faire le même code pour 1000 lignes.
Avez-vous une solution à me proposer? J'ai pensé à faire un code "Boucle".
Merci d'avance
Bonjour paulo78670,
Voici le fichier en retour pour tester :
Merci IronBoule,
C'est exactement ce que je voulais.
Bonjour IronBoule,
J'ai adapté ton codage sur mon fichier d'origine avec ton code suivant
Sub update_price()
lastline_devis = Range("A" & Rows.Count).End(xlUp).Row
lastline_base = Sheets("Base").Range("A" & Rows.Count).End(xlUp).Row
For i = 5 To lastline_devis
line_cas = Cells(i, 1).Value
For j = 7 To lastline_base
If Cells(i, 1) = "" Then
Cells(i, 8) = ""
Else
If line_cas = Sheets("Base").Cells(j, 1) Then
Cells(i, 8) = Sheets("Base").Cells(j, 7)
Cells(i, 11) = Sheets("Base").Cells(j, 8)
Cells(i, 12) = Sheets("Base").Cells(j, 9)
Cells(i, 13) = Sheets("Base").Cells(j, 10)
Cells(i, 14) = Sheets("Base").Cells(j, 11)
Cells(i, 15) = Sheets("Base").Cells(j, 12)
End If
End If
Next j
Next i
End SubSauf que dès que j'appuis sur "mettre à jour le prix de revient", les prix mettent un certain temps à se mettre à jour.
J'aimerais faire un gain de temps pour la mise à jour, est-il possible de lui dire, dans le code, de commencer à la dernière cellule de la colonne A rempli ou de lui dire de commencer à telle cellule de chaque feuille?
Au lieu de lui dire de commencer à la dernière ligne de la feuille Base et la dernière ligne de la feuille devis.
Bonjour Paulo,
Au tout début du code, ajoute
Application.ScreenUpdating = FalseCe qui va permettre de figer l'écran et d'accélérer u peu le processus.
Vois déjà avec ça et dis moi si cela convient.
Bonjour IronBoule,
Alors, voici le code initiale que j'ai adapté à mon fichier:
Sub Bouton9_Cliquer()
lastline_estimation = Range("A1000").End(xlUp).Row
lastline_base = Sheets("Base").Range("A1000").End(xlUp).Row
For i = 21 To lastline_estimation
line_cas = Cells(i, 1).Value
For j = 10 To lastline_base
If Cells(i, 1) = "" Then
Cells(i, 15) = ""
Else
If line_cas = Sheets("Base").Cells(j, 1) Then
Cells(i, 15) = Sheets("Base").Cells(j, 10)
Cells(i, 20) = Sheets("Base").Cells(j, 13)
Cells(i, 22) = Sheets("Base").Cells(j, 14)
Cells(i, 24) = Sheets("Base").Cells(j, 15)
Cells(i, 26) = Sheets("Base").Cells(j, 16)
Cells(i, 28) = Sheets("Base").Cells(j, 17)
Cells(i, 30) = Sheets("Base").Cells(j, 18)
Cells(i, 32) = Sheets("Base").Cells(j, 19)
Cells(i, 34) = Sheets("Base").Cells(j, 20)
Cells(i, 36) = Sheets("Base").Cells(j, 21)
Cells(i, 38) = "X"
End If
End If
Next j
Next i
End SubJe lui ai demandé de commencer à la cellule A1000 de chaque feuille et la mise à jour met exactement 2,41 min avant que je puisse faire autre chose sur le fichier.
Quand j'ai intégré ton code:
Sub Bouton9_Cliquer()
Application.ScreenUpdating = False
lastline_estimation = Range("A1000").End(xlUp).Row
lastline_base = Sheets("Base").Range("A1000").End(xlUp).Row
For i = 21 To lastline_estimation
line_cas = Cells(i, 1).Value
For j = 10 To lastline_base
If Cells(i, 1) = "" Then
Cells(i, 15) = ""
Else
If line_cas = Sheets("Base").Cells(j, 1) Then
Cells(i, 15) = Sheets("Base").Cells(j, 10)
Cells(i, 20) = Sheets("Base").Cells(j, 13)
Cells(i, 22) = Sheets("Base").Cells(j, 14)
Cells(i, 24) = Sheets("Base").Cells(j, 15)
Cells(i, 26) = Sheets("Base").Cells(j, 16)
Cells(i, 28) = Sheets("Base").Cells(j, 17)
Cells(i, 30) = Sheets("Base").Cells(j, 18)
Cells(i, 32) = Sheets("Base").Cells(j, 19)
Cells(i, 34) = Sheets("Base").Cells(j, 20)
Cells(i, 36) = Sheets("Base").Cells(j, 21)
Cells(i, 38) = "X"
End If
End If
Next j
Next i
End SubJe mets 1,06 min, c'est mieux mais connaissant ceux qui vont l'utiliser cela sera trop long.
As-tu une autre solution?
Merci d'avance.
Paulo
Je vais regarder dans la journée voir si je trouve quelque chose, mais bon, je sais qu'1 minute ça peut faire beaucoup à attendre, mais pour mettre à jour presque 1000 références, ça va encore :)
Je te tiens informé dans la journée !
Merci IronBoule.
Pour info, il y aura à peu prés 800 ligne, sachant que les utilisateur pourront rajouter des ligne dans la feuille à mettre à jour et je suppose que le temps se multipliera.
Dans l'attente de ton retour, merci encore.
Paulo
Re,
Sinon, sans passer par du VBA, mais avec des formules (bien sûr, en protégeant les cellules concernées pour éviter de "casser" le fichier) :
Pour tester, dans la colonne A tu ajoute ou enlève un nombre "cas" et les lignes se mettent à jour automatiquement grâce aux formules et à l'onglet "Base".
Le fichier se met à jour à l'instant T et à chaque ajout de lignes. Et si tu dois modifier les valeurs de l'onglet "base", le tableau se met à jour aussi.
Re,
Je connais cette solution mais le problème est que avant de mettre à jour les prix de revient les utilisateur utilise un Userbox pour faire leur choix et des que le choix est fait. Le prix de revient d’intégré dans la cellule concerné. Du coup la formule s’efface.
Merci tout de même
Mais cela revient au même avec le système mit en place en VBA non !?
L'utilisateur va ajouter dans le UserForm la valeur voulue qui va donc se mettre dans la cellule concernée, mais cette valeur, ne faisant pas partie de l'onglet "base", sera supprimée dès que tu cliqueras sur "Mettre à jour", puisque les colonnes se remplissent avec les valeurs de l'onglet "base" seulement en fonction du N° de cas.
Pour être plus clair, le fichier s'ouvre et l'Userform ci-dessous s’exécute:
L'utilisateur choisi son produit, le "Prix de revient" se mettra dans la cellule concerné.
Quelques temps plus tard, l'utilisateur veux agir sur le "Prix de revient" pour gratter un peu, il va donc aller dans la feuille BDD pour modifier le prix de matière première.
Ensuite il appuiera sur "mettre à jour" pour que le "Prix de revient" soit modifié.
Je pense que cette explication est plus précise IronBoule non !?
Oui, la je comprends mieux le principe de l'onglet "base" et de la mise à jour des données.
Par contre, je ne vois pas comment rendre la procédure + rapide... J'ai essayé en ajoutant une condition mais on ne gagne presque rien.
Après, en faisant les tests, la durée du script est à peu prés de 1 minute, quand aucune données n'est saisies. Une fois que toutes les données sont saisies et que l'on vient à modifier l'onglet "base" puis mettre à jour, la durée (après 3-4 tests) n'est que de 6-7 secondes.
Quand on prend le temps de bien expliquer c'est toujours mieux
Après ta réponse, je reste sur le code que tu m'as conseillé
Application.ScreenUpdating = FalseCe qui donnerait dans le code complet:
Sub Bouton9_Cliquer()
Application.ScreenUpdating = False
lastline_estimation = Range("A1000").End(xlUp).Row
lastline_base = Sheets("Base").Range("A1000").End(xlUp).Row
For i = 21 To lastline_estimation
line_cas = Cells(i, 1).Value
For j = 10 To lastline_base
If Cells(i, 1) = "" Then
Cells(i, 15) = ""
Else
If line_cas = Sheets("Base").Cells(j, 1) Then
Cells(i, 15) = Sheets("Base").Cells(j, 10)
Cells(i, 20) = Sheets("Base").Cells(j, 13)
Cells(i, 22) = Sheets("Base").Cells(j, 14)
Cells(i, 24) = Sheets("Base").Cells(j, 15)
Cells(i, 26) = Sheets("Base").Cells(j, 16)
Cells(i, 28) = Sheets("Base").Cells(j, 17)
Cells(i, 30) = Sheets("Base").Cells(j, 18)
Cells(i, 32) = Sheets("Base").Cells(j, 19)
Cells(i, 34) = Sheets("Base").Cells(j, 20)
Cells(i, 36) = Sheets("Base").Cells(j, 21)
Cells(i, 38) = "X"
End If
End If
Next j
Next i
End SubPeux-tu me confirmer?
Pour le temps, je suis septique que sur mon fichier j'en ai pour 6-7 secondes, car les utilisateur vont insérer beaucoup de ligne pour décrire un maximum de produit et le code va prendre beaucoup de temps à rechercher les "Cas" pour les mettre à jour.......
Oui, c'est bien ça !
Ca peut être un peu plus long, mais le plus long c'est de remplir les données manquantes, une fois que toutes les données sont saisies, ce ne sera que du cas par cas donc plus rapide .
J'ai fait plusieurs essai avec un tableau de 1 100 lignes (je me suis amusé !) et la mise à jour ne m'a pris que 6-7 secondes.
Bonjour tout le monde !
Si le fichier contient aussi des formules diverses, l'ajout des instructions ci dessous fera gagner beaucoup de temps :
Application.Calculation = xlCalculationManual 'en début de macro
'Reste du code...
Application.Calculation = xlCalculationAutomatic 'en fin de macroMerci Pedro et IronBoule !!!!!
La MAJ des "prix de revient marche du feu de dieu (- de 5s).
Bonne continuation à vous deux
Ps: J'ai un autre sujet où personne ne m'a répondu. Si vous pouvez m'aider.....