Ceci est une page optimisée pour les mobiles. Cliquez sur ce texte pour afficher la vraie page.

Besoin d'aide pour simplifier une macro

  • Initiateur de la discussion Initiateur de la discussion Marion16
  • Date de début Date de début

Boostez vos compétences Excel avec notre communauté !

Rejoignez Excel Downloads, le rendez-vous des passionnés où l'entraide fait la force. Apprenez, échangez, progressez – et tout ça gratuitement ! 👉 Inscrivez-vous maintenant !

Marion16

XLDnaute Nouveau
Bonjour,

J'ai créé un fichier avec:

- dans la feuille éDonnées" toutes les données relatives à des articles (codes, désignation 1, désignation 2, le type, les critéres à contrôler)

-dans la feuille "contrôle", il suffit d'indiquer le code de l'articlep our faire remonter la désignation 1, la désignation 2, le type et les critéres de contrôle. Par la suite il faut renseigner le N° de la commande, la quantité sur le bon de livraison (BL), la quantité réceptionnée, le lieux de contrôle, les différentes mesures faites sur les articles, des commentaires et la décision sur le contrôle. Le bouton mise à jour de la feuille "Contrôle"permet de copier ces données dans la feuilles "Synthèse". le bouton MAJ de la feuille "Synthèse" permet de finir la copie des données et de supprimer les données inscrite dans la feuille "Contrôle".

Si plusieurs pièces ont été contrôlées chaques mesures effectuées va se copier les unes sous les autres dans la feuille "synthèse".

Au vue de ma macro, j'ai été obliger de la couper en 2 car elle était trop grande.

Quelqu'un peut-il m'aider l'améliorer?

Merci beaucoup,

Marion
 

Pièces jointes

Re : Besoin d'aide pour simplifier une macro

Bonjour Marion,

Si tu parcours les discussions sur ce forum, tu y liras souvent ce conseil: "supprime tous les '.Select' inutiles dans ton code" ... si on examine le début de ton code:
VB:
Range("B2").Select
Selection.Copy
Sheets("Synthese").Select
Range("A65535").Select
Range("A65535").End(xlUp).Select 
ActiveCell.Offset(1, 0).Select 
ActiveSheet.Paste
... l'ensemble peut s'écrire sous la forme suivante:
VB:
Sheets("controle").Range("B2").Copy Sheets("Synthese").Range("A65535").End(xlUp).Offset(1, 0)

Ton code est tellement long que je n'ai pas eu le courage d'essayer de comprendre ta question 🙁

Attention par ailleurs que dans les RechercheV dans ta feuille "controle", tu as laissé le dernier paramètre vide. Il me semble qu'une recherche de la correspondance exacte avec la référence serait préférable
 
Re : Besoin d'aide pour simplifier une macro

Bonjour Marion,

Attention à ta manière de sélectionner tes cases où tu envoies tes données. Avec ta méthode du "je sélectionne une colonne, je prends la dernière case non vide, je copie", cela fonctionnera tant que tu n'aura pas un blanc :

Prenons un exemple : si un utilisateur a oublié de remplir l'un des champs, toutes tes colonnes seront remplies au rang i+1 tandis que la colonne où il manque le renseignement sera remplie au rang i seulement. Ce qui décalera les informations de toutes les entrées suivantes...

Je te conseille d'enregistrer dans une variable (de la macro) la ligne où tu enregistres, et de toujours y faire référence.

Sinon, plutôt que de faire du copier coller tel que,

Code:
Sheets("controle").Range("B2").Copy 'Copier la cellule B2
Sheets("Synthese").Range("A65535").End(xlUp).Offset(1, 0).Paste 'coller la valeur de la cellule B2 dans la première cellule vide

je te conseil plutôt quelque chose du type
Code:
LigneDestination = Sheets("Synthese").Range("A65535").End(xlUp).Row +1 'à ne faire qu'une fois
Sheets("Synthese").Cells(LigneDestination, 1).Value = Sheets("controle").Cells(2, 2).Value


Edit :
Bon, voilà déjà le fichier partiellement simplifié. Je me suis arrêté à l'apparition des conditions if, pour lesquels je ne vois pas de logique simple. (erreurs de syntaxe sur certains? je préfère attendre les explications.)

Si tu peux nous indiquer un peu comment fonctionnent tes condition? ce que tu cherches à faire?
Attention : Vu comment tous tes if sont imbriqués (avec tous les endif à la fin), chacune de tes condition n'est testée que si la précédente est passée avec succès. A voir si cela correspond bien à ce que tu cherches.
 

Pièces jointes

Dernière édition:
Re : Besoin d'aide pour simplifier une macro

Bonjour le fil, bonjour le forum,

Marion, visiblement, ne tient pas compte des conseils qu'on lui donne... L'élimination des Select et l'utilisation de quelques boucles simplifient et allègent considérablement le code.
J'ai aussi supprimé les conditions If Not IsEmpty car si c'est vide ça copie du vide. C'est pas bien grave. Enfin, il me semble...
Le code :

Code:
Sub Bouton2_Clic()
Dim col As Byte 'déclare la variable col (COLonne)
Dim li As Integer 'déclare la variable li (LIgne)
Dim cold As Byte 'déclare la variable cold (COLonne Décalée)
Dim lid As Integer 'déclare la variable lid (LIgne Décalée)


For li = 2 To 5 Step 3 'boucle 1 : sur les lignes 3 et 5
    For col = 2 To 5 'boucle 2 : sur les colonnes 2 à 5 (B à E)
        'copie la cellule (li, col) de l'onglet "controle" et la colle dans la première ligne vide de la colonne (cold+1)
        Sheets("controle").Cells(li, col).Copy Sheets("Synthese").Cells(Application.Rows.Count, cold + 1).End(xlUp).Offset(1, 0)
        cold = cold + 1 'incrémente cold
    Next col 'prochaine colonne de la boucle 2
Next li 'prochaine ligne de la boucle 1
For li = 8 To 11 Step 3 'boucle 1 : sur les lignes 8 et 11
    For col = 2 To 4 'boucle 2 : sur les colonnes 2 à 4 (B à D)
        'copie la cellule (li, col) de l'onglet "controle" et la colle dans la première ligne vide de la colonne (cold+1)
        Sheets("controle").Cells(li, col).Copy Sheets("Synthese").Cells(Application.Rows.Count, cold + 1).End(xlUp).Offset(1, 0)
        cold = cold + 1 'incrémente cold
    Next col 'prochaine colonne de la boucle 2
Next li 'prochaine ligne de la boucle 1
For li = 18 To 28 'boucle 1 : sur les lignes 18 à 28
    For col = 2 To 5 'boucle 2 : sur les colonnes 2 à 5 (B à E)
        Sheets("controle").Cells(li, col).Copy 'copy la cellule (li, col)
        'colle la valeur de la cellule dans la première ligne vide de la colonne K déclalée de (lid) lignes et de (col+2) colonnes
        Sheets("Synthese").Cells(Application.Rows.Count, 11).End(xlUp).Offset(lid, col + 2).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
    Next col 'prochaine colonne de la boucle 2
    lid = lid + 1
Next li 'prochaine ligne de la boucle 1
Sheets("controle").Range("G23").Copy 'copie la cellule G23 de l'onglet "controle"
'colle sa valeur dans la première ligne vide de la colonne K déclalée de 12 colonnes (colonne W)
Sheets("Synthese").Cells(Application.Rows.Count, 11).End(xlUp).Offset(0, 12).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
'copie J23 de l'onglet "controle" et le colle dans la première ligne vide de la colonne K décalée de 13 colonnes (Colonne X)
Sheets("controle").Range("J23").Copy Sheets("Synthese").Cells(Application.Rows.Count, 11).End(xlUp).Offset(0, 13)
End Sub
 
Dernière édition:
Re : Besoin d'aide pour simplifier une macro

bonjour Marion,Modeste,Tirou,Robert
pas suivi les copier/coller
un autre code en exemple sans copier/coller
Code:
Sub Bouton2_Clic()
Dim L As Long

Sheets("controle").Activate 'pour être certain que la feuille est active
With Sheets("Synthese")
L = .Range("A65535").End(xlUp).Row + 1 'remonter jusqu'a la première cellule non vide
.Range("A" & L & ":D" & L).Value = Range("B2:E2").Value
.Range("E" & L & ":H" & L).Value = Range("B5:E5").Value
.Range("I" & L & ":J" & L).Value = Range("B8:D8").Value
.Range("K" & L & ":M" & L).Value = Range("B11:D11").Value
.Range("O" & L).Value = Range("B18").Value
.Range("P" & L).Value = Range("B19").Value
.Range("Q" & L).Value = Range("C18").Value
.Range("R" & L).Value = Range("C19").Value
.Range("S" & L).Value = Range("D18").Value
.Range("T" & L).Value = Range("D19").Value
.Range("U" & L).Value = Range("E18").Value
.Range("V" & L).Value = Range("E19").Value
.Range("W" & L).Value = Range("G23").Value
.Range("X" & L).Value = Range("J23").Value
End With

End Sub
 
Re : Besoin d'aide pour simplifier une macro

Bonjour le fil

Inspiré de Robert :
Code:
Sub Bouton2_Clic()
Dim col As Byte 'déclare la variable col (COLonne)
Dim li As Byte 'déclare la variable li (LIgne)


'------ Détermine la ligne de destination pour éviter d'effacer des données ------
LigneDestination = Sheets("Synthese").Range("A65535").End(xlUp).Row + 1 'à ne faire qu'une fois
For col = 2 To 24
    If (Range(Sheets("Synthese").Cells(65535, col), Sheets("Synthese").Cells(65535, col)).End(xlUp).Row + 1) > LigneDestination Then LigneDestination = Range(Sheets("Synthese").Cells(65535, col), Sheets("Synthese").Cells(65535, col)).End(xlUp).Row + 1
Next

'------ Copie des 2 premières lignes du formulaire -------
For col = 1 To 4
    Sheets("Synthese").Cells(LigneDestination, col).Value = Sheets("controle").Cells(2, col + 1).Value
    Sheets("Synthese").Cells(LigneDestination, col + 4).Value = Sheets("controle").Cells(5, col + 1).Value
Next col

For col = 1 To 3
    Sheets("Synthese").Cells(LigneDestination, col + 8).Value = Sheets("controle").Cells(8, col + 1).Value
    Sheets("Synthese").Cells(LigneDestination, col + 11).Value = Sheets("controle").Cells(11, col + 1).Value
Next col

'----- Copie de la plage des paramètres de contrôle ------
For li = 1 To 10
    For col = 1 To 4
        Sheets("Synthese").Cells(LigneDestination + li - 1, col + 14).Value = Sheets("controle").Cells(li + 17, col + 1).Value
    Next col
Next li

'----- Copie des commentaires et décision ----------------
Sheets("Synthese").Cells(LigneDestination, 23).Value = Sheets("controle").Cells(23, 7).Value
Sheets("Synthese").Cells(LigneDestination, 24).Value = Sheets("controle").Cells(23, 10).Value

End Sub

Au moment de poster, je vois la solution élégante de Bebere (l'idée est à prendre). Je recommande toutefois de bien faire attention au L de sa (ta) solution, car en ne prenant en compte que la colonne A, on va se mordre les doigts à cause de l'écrasement de données lors des entrées ultérieurs.
Code:
'------ Détermine la ligne de destination pour éviter d'effacer des données ------
LigneDestination = Sheets("Synthese").Range("A65535").End(xlUp).Row + 1 'à ne faire qu'une fois
For col = 2 To 24
    If (Range(Sheets("Synthese").Cells(65535, col), Sheets("Synthese").Cells(65535, col)).End(xlUp).Row + 1) > LigneDestination Then LigneDestination = Range(Sheets("Synthese").Cells(65535, col), Sheets("Synthese").Cells(65535, col)).End(xlUp).Row + 1
Next
 
Dernière édition:
Re : Besoin d'aide pour simplifier une macro

Pour faire avancer le schmilblick, voici la table qui est attendue dans la partie critères de contrôle. En mode rempli au max. Les colonnes avant et après doivent avoir leurs données répétées à chaque ligne.
B18 B19 C18 C19 D18 D19 E18 E19
B18 B20 C18 C20 D18 D20 E18 E20
B18 B21 C18 C21 D18 D21 E18 E21
B18 B22 C18 C22 D18 D22 E18 E22
B18 B23 C18 C23 D18 D23 E18 E23
B18 B24 C18 C24 D18 D24 E18 E24
B18 B25 C18 C25 D18 D25 E18 E25
B18 B26 C18 C26 D18 D26 E18 E26
B18 B27 C18 C27 D18 D27 E18 E27
B18 B28 C18 C28 D18 D28 E18 E28
 
Re : Besoin d'aide pour simplifier une macro

Fichier en PJ. Les arguments de rechercheV ont été rectifiés (et enjolivés)

La solution proposée s'inspire de celle de Bebere et de celle de Robert.
Je pense que là, on a déjà une bonne réduction du code ... xD et si je ne me trompe, toutes les fonctionnalités du code de base y sont.

Code:
Sub Bouton2_Clic()
Dim L As Long
Dim NombrePieces As Byte

Sheets("controle").Activate 'pour être certain que la feuille est active

'---- Détermine le nombre de pièces rentrées ---------
NombrePieces = Range("B29").End(xlUp).Row
For col = 3 To 5
    If (Range(Cells(29, col), Cells(29, col)).End(xlUp).Row > NombrePieces) Then NombrePieces = Range(Cells(29, col), Cells(29, col)).End(xlUp).Row
    Next
NombrePieces = NombrePieces - 18 'se défausse de l'offset

'---- Extraction des données ------------------------
With Sheets("Synthese")
    For i = 1 To NombrePieces
        L = .Range("A65535").End(xlUp).Row + 1 'première cellule non vide
        .Range("A" & L & ":D" & L).Value = Range("B2:E2").Value
        .Range("E" & L & ":H" & L).Value = Range("B5:E5").Value
        .Range("I" & L & ":J" & L).Value = Range("B8:D8").Value
        .Range("K" & L & ":M" & L).Value = Range("B11:D11").Value
        
        .Range("W" & L).Value = Range("G23").Value
        .Range("X" & L).Value = Range("J23").Value
        
        .Range("O" & L).Value = Range("B18").Value
        .Range("Q" & L).Value = Range("C18").Value
        .Range("S" & L).Value = Range("D18").Value
        .Range("U" & L).Value = Range("E18").Value
        
        .Range("P" & L).Value = Range("B" & 18 + i).Value
        .Range("R" & L).Value = Range("C" & 18 + i).Value
        .Range("T" & L).Value = Range("D" & 18 + i).Value
        .Range("V" & L).Value = Range("E" & 18 + i).Value
        Next i
    End With
End Sub
 

Pièces jointes

Dernière édition:
Re : Besoin d'aide pour simplifier une macro

Bonjour Modeste, Robert, Bebere et Tirou,

Un grand merci pour m'avoir aider.

Robert, je n'ai pas oublié ton conseil, j'ai essayé de l'appliquer avant de demandé de l'aide sur le forum mais ça ne voulait pas fonctionner (Grrrrrrr). J'apprends par moi-même à faire des macros et je trouve ça un peu compliqué mais comme on dit c'est en forgeant que l'on devient forgeron alors j'apprends (pas vite mais bon...). En tout cas, je te remercie pour ton aide, maintenant j'ai compris que les .select ralentisse les macros et qu'il est mieux de les remplacer par des boucles With (Merci aussi à modeste pour sa réécriture, je comprends mieux comment tout regrouper).

Tirou, ton code fonctionne à merveille! Je comprends la démarche pour l'extraction des données (effectivement beaucoup plus simple que ce que j'avais fait) par contre je ne comprends pas ce que tu as fait pour la détermination du nombre de pièces rentrées.

NombrePiece = Range(B29"). End(xlUp).row ==> comment savoir que l'on ne remonte pas trop haut?

For col = 3 to 5 ==> A quoi ça correspond?

If (Range(Cells(29, col), Cells(29, col)).End(xlUp).Row > NombrePieces) Then NombrePieces = Range(Cells(29, col), Cells(29, col)).End(xlUp).Row ==> ça veut dire quoi?

NombrePieces = NombrePieces - 18 ==> je ne comprends pas

Je suis désolé mes questions paraissent peut être un peu idiote mais je préfère les poser et comprendre le fonctionnement de la macro.

Encore merci à vous tous,

Bonne soirée,

Marion
 
Re : Besoin d'aide pour simplifier une macro

Bonjour Marion,

Voyons cela point par point 🙂

La commande With ne remplace pas le .select. En effet, le With Expression permet d'éviter de réécrire à tout bout de champ ladite expression. Ainsi, à chaque fois que tu écriras .expression2, la macro "comprendra" expression.expression2 à la place.

La disparition du .select est faite par une autre méthode. Quand tu fais sheet("machin".select) puis range("bidule").select, tu précises que tu veux sélectionner une caractéristique particulière d'un objet. Comme tu n'indiques pas quel objet, excel prend par défaut le dernier actif. (Les termes sont juste pour imager, je pense que ce ne sont pas les termes exactes (que je ne connais pas d'ailleurs))
Ainsi, tu peux combiner, sheet("machin").range("bidule").select arrive au même résultat, sauf que cette fois, tu vas directement à ce que tu cherchais.


Avant de passer à la suite, je préfère faire une petite précision. En programmation, le signe = ne signifie pas vraiment "égal", mais plutôt une affectation. Ainsi col=2 signifie que l'on affecte la valeur 2 à la variable col.
Il y a donc une différence entre le = que tu trouveras ici et celui que l'on nous inculque à l'école. (par exemple, 2=col ne signifie rien ici)


Au niveau de la fonction :
Code:
For col = 2 to 5
blabla
next col
C'est ce que l'on appelle une boucle. Une boucle permet de répéter une série d'instruction.
For col = 3 to 5 précise que l'on va avoir une variable col qui prend pour première valeur 3 et finira à 5, implicitement par pas de 1 (donc 3 fois les instructions). Pour chacune des valeurs de col, le code entre For et Next sera exécuté.

Maintenant dans notre cas précis : pour déterminer le nombre de pièces rentrées dans le formulaire, je procède de la manière suivante :
1) je regarde dans la colonne B combien il y a de pièces
2) Je vérifie que dans les colonnes C à E, il n'y a pas davantage de pièce que ce que j'avais trouvé en colonne B
Ok, ça c'est la théorie, mais en pratique ? Je me sert des numéro de lignes des dernières cases remplies dans ton tableau formulaire.

La commande Range(B29"). End(xlUp).row fonctionne comme suit : je me "place" en B29, je regarde vers le haut jusqu'à la première case non vide, et je regarde à quelle ligne j'arrive. Quand tu as 0 pièces, c'est la ligne 18, 1 pièce donne la ligne 19 etc. Ca, c'est pour l'étape 1), que l'on peut aussi appeler étape d'initialisation de la variable NombrePièce.

Pour l'étape 2, je balaye des colonnes sur lesquelles je fais la même chose. Au lieu de réécrire à chaque fois les instructions en changeant les indices, il est plus facile d'utiliser une boucle, ici For. A chaque occurrence de la boucle (chaque fois que les instructions "blabla" sont répétées) je regarde le nombre de pièce trouvé dans la colonne de numero col (donc 3 puis 4 puis 5, autrement dit colonne C puis D puis E), et si jamais je trouve un nombre de pièce plus grand, je conserve ce nombre de pièce comme nouvelle référence.

Bon, jusque là, je t'ai un peu entourloupé: quand je dis avoir récupérer un nombre de pièce, ce n'est pas tout à fait vrai, car j'ai récupérer un numéro de ligne. Le lien entre les 2 est une différence de 18 (quand tu as 0 pièce, tu récupère la ligne 18, la ligne 19 pour 1 pièce, ligne 20 pour 2 pièces etc). Je rectifie donc en retranchant 18 à la variable NombrePieces trouvé jusque là.


Enfin, je préfère terminer en te rappelant qu'il n'y a pas de question idiote : tu n'es visiblement pas habituée à la programmation. Et alors? C'est un apprentissage, pas une tare de naissance ! Et la volonté de comprendre ce que l'on utilise est tout à fait louable.

Si tu veux te familiariser avec la programmation, je te conseille d'aller regarder un peu ce cours : Ce lien n'existe plus
Bien qu'il s'agisse d'un langage différent (c'est à dire une syntaxe différente) les concepts de base sont les mêmes. Cela te permettra de comprendre ce que sont les variables, l’utilisation des boucles for, while, des conditions if, case etc.
Ne prends pas peur de la taille du pdf, il est long car justement expliqué de manière assez détaillée pour être comprise par tout à chacun (et un peu d'humour pour alléger).

N'hésites pas si tu as d'autres questions ^^
 
- Navigue sans publicité
- Accède à Cléa, notre assistante IA experte Excel... et pas que...
- Profite de fonctionnalités exclusives
Ton soutien permet à Excel Downloads de rester 100% gratuit et de continuer à rassembler les passionnés d'Excel.
Je deviens Supporter XLD

Discussions similaires

Réponses
10
Affichages
470
  • Question Question
Réponses
7
Affichages
286
Les cookies sont requis pour utiliser ce site. Vous devez les accepter pour continuer à utiliser le site. En savoir plus…