Se connecter avec
S'enregistrer | Connectez-vous

Première macro...

Dernière réponse : dans Programmation

Bonjour à toutes et tous,

Je débute dans le développement de macro et malgré les différents sujets que j’ai parcourus et les diverses tentatives de macros réalisées manuellement, je ne parviens pas à développer « la macro de mes rêves »… :love: 

J'ai un fichier qui me permet d'assurer le suivi du matériel. Il y a environ 500 lignes qui listent l’ensemble des matériels. Au niveau des colonnes certaines sont « fixes » car elles reprennent les caractéristiques techniques et une partie variable qui concerne la mise à disposition, elle comprend notamment une date de sortie et une date de retour du matériel.

L'objectif de la macro serait que lorsqu'un matériel est de retour, la ligne correspondante se copie dans une autre feuille du même type (même présentation et située dans le même classeur) afin de procéder à un archivage. La feuille 2 se complèterait donc au fur et à mesure que les matériels reviennent. De plus, l’archivage étant réalisé, je souhaiterai que la macro efface les données dans la feuille initiale, le matériel pouvant de nouveau être prêté.
Dernier point la macro se déclencherait lorsque l’on procède à un enregistrement et l’enregistrement serait automatique lorsque l’on quitte le fichier.

Je vous aurais bien proposé un exemple de macro le problème c’est que je ne parviens pas à la réaliser sans passer par un filtre alors que je préférerais que ma macro copie la ligne à partir du moment ou une cellule précise de cette ligne est non vide. :??:  Si vous pouviez déjà m’indiquer comment copier-coller une ligne dont une cellule précise n’est pas vide, cela me permettrait de vous présenter la suite de ma macro.

Je vous remercie par avance pour votre aide.


GTmacrodeb

Autres pages sur : premiere macro

Lassé par la pub ? Créez un compte

Meilleure solution

Expert Programmation

Et bien voila, probleme résolu.

pour ta sauvegarde automatique, utilse VBA.
Tu peux utliser les fonctions : .AutoUpdateFrequency = x avec x le nombre de minutes (entre 5 et 1440) entre 2 sauvegardes
puis apres : .AutoUpdateSaveChanges = True


---------------------------------------------

n'oublie pas de fermer le sujet quand tuas eu toutes tes réponses en choisissant une "meilleur réponse"
Expert Programmation

salut GTmacrodeb,

C'est domage que tu n'est pas un tout petit début de bout de code a proposé mais bon, tu as le droit après tout, c'est ta première macro !!

avant de commencer:
sous excel sert toi de l'aide (F1) pour apprendre a te servir et a connaitre la syntaxe des fonctions que l'on va te donner, c'est une mine d'or.

alors, pour copier, et bien on utilise tout simplement la fonction .copy (je te laisse te renseigner sur l'utilisation de la fonction grâce a l'aide !!)

pour vérifier que une cellule n'est pas vide on fait un test su la cellule .
As tu connaissance des boucles sous VBA (ou autre langage) ? notamment la boucle IF...then...else....end if
sinon, reporte toi encore une fois a l'aide.

tu devra l'utiliser de cette manière :
  1. IF '//cellule non vide
  2. then
  3. '// tu fais la copie de ta ligne dans une autre feuille
  4. end if


autre question, tes cellules vides sont toutes dans la même colonne matériel rendu non ?

(en espérant que ce début de réponse te permette de rédiger ton premier bout de code)

et des que tu en as un... reviens vite nous voir et poste le (attention à bien utiliser la balise CODE).

a te lire...

Bonjour et tout d'abord merci de ta réponse.

J'avais effectivement commencé à consulter différents sites et tutoriels mais malgré mon réel intérêt, j'ai du mal à appréhender le vba mais je ne désespère pas.

Alors pour procéder par étape, voici le début de ma macro ayant pour objectif de copier la ligne correspondante dans une nouvelle feuille lorsqu'une cellule précise de cette ligne est complétée.

  1. Sub Archivage()
  2.  
  3. Dim DateR As Date
  4.  
  5. For Each DateR In Worksheet("Suivi").Range("I:I")
  6. 'ma colonne I commence en fait en I6 et n'a pas de limite en bas, comment désigner la limite ("I6:I?")
  7. If DateR Is notempty Then
  8. Worksheets("Suivi").Range("I:I").Copy Destination:=Worksheets("Archivage").Range("I:I")
  9. 'Comment désigner la ligne correspondante par rapport à la case non vide ?
  10.  
  11. End If
  12.  
  13. End Sub


"Evidemment", la macro ne fonctionne pas... [:_tom_:13]

Encore merci de prendre du temps pour m'éclairer.
Expert Programmation

salut,

Alors, pour commencer, je dirais que c'est un bon début.
Tu déclare les variables, c'est judicieux mais pourquoi ne pas déclarer aussi la feuille sur laquelle tu travaille comme ceci :

  1. [...]
  2. dim ws_suivi as Worksheet
  3.  
  4. set ws_suivi = Worksheets("Suivi")
  5. [...]

Ainsi tu n'a plus qu'a utiliser la variable ws_suivi pour ta feuille initiale (a faire aussi pour la feuille de destination).

Autre chose : tu peut te passer de certains mots ligne 8 :
  1. Worksheets("Suivi" ).Range("I:I" ).Copy Worksheets("Archivage" ).Range("I:I" )

(c'est la meme chose.. mais ca ne regle pas ton probleme...)

Ensuite met l'option explicit tout en haut de ta feuille vba, avant ton sub, ca t'aidera a régler le probleme des variables non définies.
  1. option Explicit


Ensuite pour ta colonne I qui commence a I6, tout comme pour ton probleme de décalage d'une ligne a chaque fois que tu copie, je te propose de te tourner vers la fonction .Offset() (je et laisse lire l'aide et si tu as des questions ou incompréhension n'hésite pas)

Ensuite il faut que tu penses a supprimer la ligne que tu copie... amoins que tu ne veuilles avoir des trous dans ton tableau... mais chaque chose en son temps, je ne veux pas t'embrouiller, je te montrerai comment faire des que tu aura compris .Offset() qui va régler pas mal de tes problemes.

Je poursuis mon apprentissage grâce à tes précieux conseils, voici le nouveau code non fonctionnel pour le moment :

  1. Sub Archivage()
  2.  
  3. Dim DateR As Date
  4. Dim ws_suivi As Worksheet
  5. Dim ws_archivage As Worksheet
  6.  
  7. Set ws_suivi = Worksheets("Suivi")
  8. Set ws_archivage = Worksheets("Archivage")
  9. Set DateR = ws_suivi.Range("I6").End(xlDown)
  10.  
  11. For Each cell In DateR
  12. If cell Is notempty Then
  13. ' je ne vois pas comment écrire les numéros de ligne où les cellules sont non vides dans la colonne I
  14. ws_suivi.Range("A").Offset(0, 17).Copy ws_archivage.Range("A6").End(xlDown).Offset(1, 0)
  15.  
  16. End If
  17.  
  18. End Sub


Encore merci.

Bonjour,
lorsque qu'on veux supprimer des lignes il faut partir de la derniere ligne vers la premiere.
Ton code pourrais être corrigé comme ceci :
  1. Sub Archivage()
  2.  
  3. Dim ws_suivi As Worksheet
  4. Dim ws_archivage As Worksheet
  5.  
  6. Set ws_suivi = Worksheets("Suivi")
  7. Set ws_archivage = Worksheets("Archivage")
  8.  
  9. 'j'active la feuille suivi
  10. ws_suivi.Activate
  11.  
  12. 'avec la feuille suivi
  13. With ws_suivi
  14. 'Je remonte de la derniere ligne jusqu'a la ligne 7
  15. For x = .Range("I65000").End(xlUp).Row To 7 Step -1
  16. 'si dans la cellule I il y a quelques choses alors
  17. If .Range("I" & x) <> "" Then
  18. 'Je copie la ligne entière dans la feuille archive
  19. .Rows(x).EntireRow.Copy ws_archivage.Range("A65000").End(xlUp).Offset(1, 0)
  20. 'Je supprime la ligne entière
  21. .Rows(x).EntireRow.Delete
  22. End If
  23. Next x
  24. End With
  25.  
  26. End Sub

bon courage ;) 
Expert Programmation

Salut a vous,

Gtmacro, suis le conseil de rvtoulon pour la suppression en partant du bas, si tu veux des explications:
http://www.presence-pc.com/forum/ppc/Programmation/tuto...

sinon, je ne suis aps du tout pour l'emploi des .select et .activate rvtoulon...

Bon commençons par revoir ton code :
  1. Dim DateR As Date
  2. Dim ws_suivi As Worksheet
  3. Dim ws_archivage As Worksheet '// ok
  4.  
  5. Set ws_suivi = Worksheets("Suivi" )
  6. Set ws_archivage = Worksheets("Archivage" ) '// bien jusque là
  7. '// pk date R définie comme date alors que il renvois un numero de ligne, celui de la derniere non vide..
  8.  
  9. For Each cell In DateR '// parfait mais déclare cell as Range.. et renomme ta plage
  10. If cell <> "" Then '//ce que tu cherchait le signe différent :<> et pour dire vide : ""
  11. ws_suivi.Range("A" ).Offset(0, 17).Copy ws_archivage.Range("A6" ).End(xlDown).Offset(1, 0)
  12. End If


bon si on reprends tout ca donnerai; avec modifs et améliorations :
  1. Dim lstrow As range
  2. Dim ws_suivi As Worksheet
  3. Dim plage_destination As Range '// plus judicieux
  4. dim i as long
  5.  
  6. Set ws_suivi = Worksheets("Suivi" )
  7. set plage_destination =Worksheets("Archivage").cells '// compris ?
  8. set lstrow = ws_suivi.Columns(8).offset(6).end(xldown).row '// indique le numero de ligne de la derniere cellule ds I
  9.  
  10. For i = lstrow to 6 '// de la derniere ligne a la premiere
  11. If ws_suivi.cells(i,8).value <> "" Then '//si cellule non vide
  12. ws_suivi.rows(i).Copy plage_destination
  13. plage_destination = plage_destination.offset(1,0) '// on descend d'une ligne pour préparer la prochaine copie
  14. ws_suivi.Rows(i).delete
  15. End If


bon, et si on faisait une fonction maintenant ???
des idées ???

++

bonjour, oozenot, GTmacro,
Citation :
sinon, je ne suis aps du tout pour l'emploi des .select et .activate rvtoulon...

Je te rassure moi non plus ;)  Cela ralenti beaucoup le code.
J'ai mis un .Activate pour être sur que la feuille "suivi" soit la feuille active sinon j'ai une erreur avec le "with".

Une remarque toutefois afin d'éviter une erreur, GTmacro, la cellule I6 est une entête ou non? car si c'est une entête la macro va supprimer la ligne 6 :
  1. For i = lstrow to 6
  2. If ws_suivi.cells(i,8).value <> "" Then

Cela veut dire que si la cellule I(x) contient une donnée : Date,Texte,Nombre etc... alors on continu le code.
donc si I6 = une entête et pas une date, dans la boucle remplace 6 par 7.

Mon code prend forme petit à petit grâce à vous. ;) 

  1. Sub Archivage()
  2.  
  3. Dim lstrow As Range
  4. Dim ws_suivi_m As Worksheet
  5. Dim plage_destination As Range '// plus judicieux
  6. Dim i As Long
  7.  
  8. Set ws_suivi_m = Worksheets("Suivi Matériel")
  9. Set plage_destination = Worksheets("Archivage Matériel").Cells
  10. Set lstrow = ws_suivi_m.Columns(10).Offset(6).End(xlDown).Row '// finalement ce sera en colonne J donc 10
  11.  
  12. For i = lstrow To 6 '// je confirme que mes données commencent en I6, l'en-tête est en I5
  13. If ws_suivi_m.Cells(i, 10).Value <> "" Then
  14. ws_suivi_m.Rows(i).Copy plage_destination
  15. plage_destination = plage_destination.Offset(1, 0)
  16. ws_suivi_m.Rows(i).Delete
  17.  
  18. End If
  19.  
  20. Next i '// il manquait cette ligne
  21.  
  22. End Sub


Par contre lorsque je souhaite exécuter cette macro, j'ai une erreur d'éxécution '1004'.

Je ne sais pas si ce paramère est important mais ma feuille d'archivage est protégé en écriture cela peut-il bloquer l'exécution de la macro ?

oozenot, tu veux dire qu'une fonction pourrait me permettre toutes ces manipulations sans passer par Visual Basic ? [:_set_]

Encore et toujours merci.
Expert Programmation

oups... grosse erreur de ma part pour le next..., pour ma défence je n'a pas d'excel a la maison !! ;) 
par contre tu n'a pas besoin de mettre qqch derriere, on faisait comme ca en 1985 !! mdr

Non, une fonction te permettrait d'alléger encore ton code je te montres comment dans mon prochain post... (le tps de vérifier mes dires avec l'excel du bureau..)

pour l'erreur 1004, erreur d'execution je crois... t sais a quelle ligne ?
Expert Programmation

ah oui, deuxieme grosse erreur de ma par, on défini pas la variable, on lui attribue un chiffre... pas besoin du set...
et par la meme occasion, le lstrow doit etre défini en temps que Long... F1 si tu ne sais pas..

en fait ton code était bourré de fautes... je suis en train de le corriger...
tada... plus d'erreur mais i ne fait pas ce que tu veux... c'est pas grave.. on vas trouver l'erreur :
  1. Option Explicit '// détecte toutes tes variables non définies !!!!
  2.  
  3. Sub linecopy(ByVal line As Range, ByRef target As Range, Optional clear As Boolean) '// la fameuse fonction
  4. line.EntireRow.Copy Destination:=target
  5. If clear Then line.EntireRow.Delete
  6. Set target = target.Offset(1)
  7. End Sub
  8.  
  9. Sub Archivage()
  10.  
  11. Dim lstrow As Long '// derniere ligne du tableau
  12. Dim fstrow As Long '// premiere ligne du tableau
  13.  
  14. Dim ws_suivi_m As Worksheet
  15. Dim plage_destination As Range
  16. Dim i As Long
  17.  
  18. Set ws_suivi_m = Worksheets("Suivi Matériel")
  19. Set plage_destination = Worksheets("Archivage Matériel").Rows(2) '// commence ta copie a la ligne 2
  20. fstrow = ws_suivi_m.Columns(10).End(xlDown).Row + 1 '// plus 1 pour éviter de compter ton entete
  21. lstrow = ws_suivi_m.Range(Cells(fstrow, 10), Cells(65536, 10)).End(xlDown).Row '// défini la derniere ligne
  22.  
  23. For i = lstrow To fstrow step -1
  24. If ws_suivi_m.Cells(i, 10).value <> "" Then
  25. linecopy ws_suivi_m.Rows(i), plage_destination, True
  26. End If
  27. Next
  28.  
  29. End Sub

maintenant, comprend tu pourquoi il ne copie rien ?

premierement, ta colonne J est celles des dates, vrai ? don c'est une colonne qui contient des trous ... d'apres toi quelle est la valeur de lstrow si ta ligne 6 ne contient pas encore de date de retour ? tu vois le preobleme ? essaye d'utiliser pour le début et la fin de ton tableau une colonne que tu remplie a coup sur.. s'iln'y en a pas, on fera autrement en utilisant la méthode que tu proposait au début : for each

ensuite, ne vaudrai t'il pas mieux ne pas supprimer les lignes de ton premier tableau ?
c'est comme tu veux mais je pense qu'i serait plus judicieux de créer une feuille "temporaire" sur laquelle travailler pendant la macro....

pour fstrow, trouve une colonne sans rien avant ton entete..

Merci pour toutes ces précisions, je vais donc compléter mes besoins.

En fait ce tableau recense un ensemble de matériel, la colonne qui est toujours remplie est la A.
Ensuite, j'ai différentes colonnes qui reprennent les caractéristiques par matériel, ces colonnes là ne bougent pas.
Enfin, j'ai une partie qui concerne la sortie et le retour du matériel qui sont comprise entre F et J.
Ce sont ces colonnes que je souhaite effacer automatiquement après archivage.

Pour préciser, lorsque la personne complète une date de retour en J, la ligne correspondante doit venir se copier dans la feuille Suivi Archivage. Le matériel étant de nouveau disponible, les colonnes F à J s'effacent dans la feuille initiale.

Je vais prendre en compte tes remarques et modifications pour voir si je parviens à l'adapter de mon côté.

Dernier point, je mets bien l'Option Explicit au début de chaque macro mais je ne la copiais pas sur le forum. ;) 

Merci.

pour la derniere ligne :
  1. lstrow = ws_suivi_m.Range(Cells(fstrow, 10), Cells(65536, 10)).End(xlDown).Row '// défini la derniere ligne

pourquoi pas ceci :
  1. lstrow = ws_suivi_m.Range("J65000").End(xlup).Row '// défini la derniere ligne
en partant du bas je remonte jusqu'a la derniere ligne utilisée et je met le numéro de ligne dans la variable lstrow
Expert Programmation

bonne idée rvtoulon, ainsi, plus besoin de définir la premiere ligne puisqu'on sait que c'est la 6....
(pour faire encore plus court on pourra utiliser les adresses des cellules directement.... :lol:  )

GTmacrodeb,quand tu dis les colonnes F a J tu parle des cellules situes sur la ligne du matériel retourné étant situés entre la colonne F et J..
Donc tu ne supprime pas toute la ligne... a toi d'adapter le code alors... :D 
utilise un .Range() pour tes suppressions :non: 

hate de voir ton prochain... :sol: 

Je vous remercie de nouveau pour vos réponses et propositions rapides alors voici le nouveau code.

  1. Sub linecopy(ByVal line As Range, ByRef target As Range, Optional clear As Boolean) '// la fameuse fonction
  2.  
  3. line.EntireRow.Copy Destination:=target
  4. If clear Then line.Range("F:J").Delete
  5. Set target = target.Offset(1)
  6.  
  7. End Sub
  8.  
  9. Sub Archivage()
  10.  
  11. Dim lstrow As Long '// derniere ligne du tableau
  12.  
  13. Dim ws_suivi_m As Worksheet
  14. Dim plage_destination As Range
  15. Dim i As Long
  16.  
  17. Set ws_suivi_m = Worksheets("Suivi Matériel")
  18. Set plage_destination = Worksheets("Archivage Matériel").Rows(6)
  19.  
  20. lstrow = ws_suivi_m.Range("J65000").End(xlUp).Row '// défini la derniere ligne
  21.  
  22. For i = lstrow To 6
  23. If ws_suivi_m.Cells(i, 10).Value <> "" Then
  24. linecopy ws_suivi_m.Rows(i), plage_destination, True
  25.  
  26. End If
  27.  
  28. Next
  29.  
  30. End Sub



Malheureusement lorsque je lance la macro, rien ne se passe... Je dois sûrement vouloir aller trop vite... En tout cas encore merci pour votre patience et vos précieux conseils.

J'ai effectué la modif ligne 23, à vérifier tout de même car j'ai toujours des soucis, avec le code suivant :

  1. Sub linecopy(ByVal line As Range, ByRef target As Range, Optional clear As Boolean) '// la fameuse fonction
  2.  
  3. line.EntireRow.Copy Destination:=target
  4. If clear Then line.Range("F:J").Delete
  5. Set target = target.Offset(1)
  6.  
  7. End Sub
  8.  
  9. Sub Archivage()
  10.  
  11. Dim lstrow As Long '// derniere ligne du tableau
  12.  
  13. Dim ws_suivi_m As Worksheet
  14. Dim plage_destination As Range
  15. Dim i As Long
  16.  
  17. Set ws_suivi_m = Worksheets("Suivi Matériel")
  18. Set plage_destination = Worksheets("Archivage Matériel").Rows(6).End(x1Down).Row + 1
  19.  
  20. lstrow = ws_suivi_m.Range("J65000").End(xlUp).Row '// défini la derniere ligne
  21.  
  22. For i = lstrow To 6 Step -1
  23. If ws_suivi_m.Cells(i, 10).Value <> "" Then
  24. linecopy ws_suivi_m.Rows(i), plage_destination, True
  25.  
  26. End If
  27.  
  28. Next
  29.  
  30. End Sub


En effet, ma feuille d'archivage a commencé à être complétée manuellement, il faudrait donc que la ligne que l'on souhaite déplacer, se copie à la 1ère ligne vide de la feuille archivage, d'où ma modification de la ligne 18. Cependant, il me notifie un problème de variable.

Lorsque je fais le test, il a bien déplacé la ligne correspondante dans la ligne 6 de la feuille.
Par contre, il n'a pas effectué l'effacement et a précisé une erreur de débogage pour la ligne 4 de la macro.

Merci pour votre aide, et désolé si ma formulation n'est pas suffisamment claire.
Expert Programmation

salut,

essaye d bien comprendre le fonctionnement de la fonction. la réponse a ta question est dedans. si tu n'es pas certain, formule tout ce que fais la fonction par écris et je te corrigerais.

j'ai fais quelaues modifications sur la partie suppression des cellules dns suivi. ca marche chez moi.
Voici ton dernier code JUSTE :
  1. Sub linecopy(ByVal line As Range, ByRef target As Range, Optional clear As Boolean)
  2. line.EntireRow.Copy Destination:=target
  3. If clear Then Range(Cells(line.Row, 6), Cells(line.Row, 10)).Delete '// tu delete uniquement les cellules F a J ..
  4. Set target = target.Offset(1) '// c'est ca qui te permet d'augmenter tes lignes de 1 sur la feuille archivage..
  5. End Sub
  6.  
  7. Sub Archivage()
  8.  
  9. Dim lstrow As Long '// derniere ligne du tableau
  10.  
  11. Dim ws_suivi_m As Worksheet
  12. Dim plage_destination As Range
  13. Dim i As Long
  14.  
  15. Set ws_suivi_m = Worksheets("Suivi Matériel")
  16. Set plage_destination = Worksheets("Archivage Matériel").Rows(6) '// ca reste tel quel pur l'instant...
  17.  
  18. lstrow = ws_suivi_m.Range("J65000").End(xlUp).Row
  19.  
  20. For i = lstrow To 6 Step -1
  21. If ws_suivi_m.Cells(i, 10).Value <> "" Then
  22. linecopy ws_suivi_m.Rows(i), plage_destination, True
  23. End If
  24. Next
  25.  
  26. End Sub


ta modification ligne 18 est fausse regarde comment est définie la variable plage_destination ...
Et que va renvoye
  1. Worksheets("Archivage Matériel" ).Rows(6).End(x1Down).Row + 1
?

Si tu veux qu'a chaque démarage de la macro, excel vérifie la premiere ligne vide dans arcivage alors on rajoute une variable j qui va prendre le numéro de la premiere ligne disponible et donc définir la plage dans ce sens...

je te laisse chercher un peu avant de te donner la réponse ....
(si tu as bien compris ton code, c'est du tout cuit !!)

Fais attention a comment tu défini tes variables.
Si tu doute, pas de honte, tout le monde est débutant un jour, le forum est la pour ca !!

++

Pas de honte pour moi, je suis très heureux d'apprendre et je trouve très instructif votre manière de procéder même si je suis un peu perdu.

Voici le nouveau code : j'ai défini une variable j mais j'ai un peu de difficultés pour la conclure.


  1. Sub linecopy(ByVal line As Range, ByRef target As Range, Optional clear As Boolean)
  2.  
  3. line.EntireRow.Copy Destination:=target
  4. If clear Then Range(Cells(line.Row, 6), Cells(line.Row, 10)).Delete '// tu delete uniquement les cellules F a J ..
  5. Set target = target.Offset(1) '// c'est ca qui te permet d'augmenter tes lignes de 1 sur la feuille archivage..
  6. End Sub
  7.  
  8. Sub Archivage()
  9.  
  10. Dim lstrow As Long '// derniere ligne du tableau
  11.  
  12. Dim ws_suivi_m As Worksheet
  13. Dim plage_destination As Range
  14. Dim i As Long
  15. Dim j As Long
  16.  
  17. Set ws_suivi_m = Worksheets("Suivi Matériel")
  18. Set plage_destination = Worksheets("Archivage Matériel").Rows(6) '// ca reste tel quel pur l'instant...
  19.  
  20. lstrow = ws_suivi_m.Range("J65000").End(xlUp).Row
  21. fstrow = plage_destination("A6").End(x1Down).Row
  22.  
  23. For i = lstrow To 6 Step -1 '// De la dernière ligne à la ligne 6 en remontant ligne par ligne
  24. If ws_suivi_m.Cells(i, 10).Value <> "" Then '// Si dans la colonne 10 (J), la cellule est non vide
  25. linecopy ws_suivi_m.Rows(i), plage_destination, True '// La ligne correspondante est copiée dans plage_destination
  26. End If
  27. Next
  28.  
  29. For j = fstrow To 65000 Step 1 '// De la première ligne à partir de fstrow jusqu'à la dernière ligne
  30. If plage_destination.Cells(j, 1).Value <> "" Then '// Si dans la plage_destination colonne 1, la cellule est non vide
  31. linecopy ws_suivi_m.Rows(i), plage_destination, True '//Ici je ne vois pas comment rédiger...
  32. End If
  33.  
  34. End Sub


C'est en macrotant qu'on devient macroteur/macrotiste. ;) 

Encore merci.
Expert Programmation

exactement...

Tu as bien défini la variable j
par contre on avait nullement besoin de modifier la fonction ni le code précédent...
il suffisait "juste" de rajouter une ligne et intégrer la variable J comme suis :

  1. Sub linecopy(ByVal line As Range, ByRef target As Range, Optional clear As Boolean)
  2. line.EntireRow.Copy Destination:=target
  3. If clear Then Range(Cells(line.Row, 6), Cells(line.Row, 10)).Delete
  4. Set target = target.Offset(1) '// c'est ca qui te permet d'augmenter tes lignes de 1 sur la feuille archivage..
  5. End Sub '// pas de changement
  6.  
  7. Sub Archivage()
  8.  
  9. Dim lstrow As Long
  10. Dim ws_suivi_m As Worksheet
  11. Dim plage_destination As Range
  12. Dim i As Long
  13. Dim j as Long '// on intègre une nouvelle variable
  14.  
  15. j = Worksheets("Archivage Matériel" ).Range("A65536").End(xlup).Row '// donne la dernière ligne vide de archivage
  16.  
  17. Set ws_suivi_m = Worksheets("Suivi Matériel" )
  18. Set plage_destination = Worksheets("Archivage Matériel" ).Rows(j) '// on intègre j comme début de plage pour la copie
  19.  
  20. lstrow = ws_suivi_m.Range("A65536" ).End(xlUp).Row '// utilisation de la colonne A et pas J (car trous dans J)
  21. For i = lstrow To 6 Step -1
  22. If ws_suivi_m.Cells(i, 10).Value <> "" Then
  23. linecopy ws_suivi_m.Rows(i), plage_destination, True
  24. End If
  25. Next
  26. End Sub


a vérifier sous excel... je ne suis plus au bureau pour corriger les quelques erreurs éventuelles... :D 
Mais normalement... problème réglé, des questions ??
reste plus qu'a créer un bouton et a y assigner la macro !!

Bonjour,

Alors après essai ce matin, je me suis rendu compte que j'avais un souci dans la colonne K. Cette colonne intègre une formule qui calcule la différence entre la colonne J et I. Après recherche, je me suis aperçu qu'au lieu d'effacer les colonnes F à J, il les supprimait.

Je suppose que le problème vient du terme Delete ligne 3.

Je suis en train de chercher le terme correspondant, pour dire effacer au lieu de supprimer.

Merci de me confirmer si c'est possible ou non.

Je vous tiens au courant si je trouve avant.

Bonne journée à tous.

PS : je pense avoir trouvé, il suffisait de mettre ClearContents à la place de Delete.
Je poursuis mes essais et vous tiens informé.

Retour suite aux essais :

Donc pour la partie effacement des lignes cela semble fonctionner donc déjà merci.


Ensuite pour la partie Archivage, j'ai quelques soucis :

1 - Dans Archivage, les données viennent se copier sur la dernière ligne copiée et non sur la première ligne vide.
Je cherche à comprendre le fonctionnement de la ligne 4 du code avec .Offset. En quoi est-ce nécessaire d'ajouter la ligne si on vient copier sur la première ligne vide ?
--> Pour cette partie, je pense avoir trouvé, il suffisait de mettre Row+1 à la fin de la variable J, ligne 15.
Cependant, est-ce que la ligne 4 est nécessaire et faut-il forcément remonter les lignes dans la mesure où il n'y a pas de risque de débordement puisqu'on efface les cellules au lieu de les supprimer ?


2e remarque - Etant donné que dans le tableau de suivi, on remonte les lignes de bas en haut, il les copie dans ce sens sur la feuille archivage, c'est à dire dans le sens inverse de l'ordre alphabétique. Cela ne me dérange pas, dans la mesure où je souhaite qu'à l'avenir, la feuille archivage soit triée à partir des dates de retour dans la macro. Je poursuis mes recherches.

Encore Merci.
Expert Programmation

Salut GTmacrodeb,

Oui c'est tout a fait ca pour la ligne 15, c'est ce que je te disais de vérifier n'ayant plus excel..
et oui la ligne 4 est absolument necessaire puisque la ligne 15 ne s'effectue qu'une seule fois. Quand tu est dans ta boucle for, si il y a plusieurs retours.. il faut bien que la copie descende d'une ligne a chaque fois... ce que fait la ligne 4.
En gros ligne 15 donne la ligne de début, et a chaque utilisation de la fonction(dc a chaque copie dc qd il y a un retour) on incrémente (augmente) de 1 la ligne pour la prochaine copie.

Pour le changement de .delete , Tu pouvais en effet mettre .ClearContents.

Pour la copie dans le sens inverse de celui présenté sur la feuille suivi je me suis dis que ca importait peu étant donné que sous excel il suffit de mettre un filtre une fois sur ta feuille archivage pour trier les données que tu veux vérifier... après tout, une archive sert a ca !!

++

Merci pour tes explications claires et précises sur la fonction .Offset.

En fait, ce tableau ne sera pas utilisé par moi-même mais par un novice c'est pour ça que je souhaite automatiser le maximum de choses.

Je me suis donc attaqué à la macro tri des données à partir des dates de retour colonne J dans la feuille d'archivage. J'ai fait un enregistrement manuel pour voir le principe de la macro.

Par contre je me demande, si cette macro peut-être intégrée au même module ou si je dois en créer un nouveau.

Si c'est dans le même module, faut-il l'insérer avant ou après la macro "Archivage" ? L'ordre a-t-il une importance ?

Merci pour vos précisions.
Expert Programmation

Oui, évidement c'est plus malin de l'intégerer dans le meme module et meme dans le meme code. et apres la boucle for puisqu'il vaut mieux trier les donnees une fois qu'il y en as dans la feuille archivage.

Par contre encore plus simple : mettre un filtre maintenant sur la feuill archivage et de toute facon il se mettra a jour pour chaque copie. meme pas besoin de faire u code pour ca.

De plus le code pour un filtre est mal foutu sous VBA : je m'explique si tu code le fait de mettre un filtre et qu'il y en as déja un, il l'enleve.. il faudrait donc l'enlever et le remettre a chaque fois.... ce qui fait 2 * plus de code et ca ralenti l'execution de la macro.

Le moins contraignant serais donc de mettre le filtre des le début (manuellement) mais par contre de mettre un tri ordre croissant (ou decroissant) sur les dates apres chaque fin d'execution de la macro...

ca te va ?

Exactement ce que je souhaite. Le filtre était déjà mis sur ma feuille d'archivage pour l'ensemble de mes colonnes.

Ci-dessous, le code que j'ai réalisé et légèrement modifié avec l'enregistreur de macro :

  1. Sub Tri_automatique()
  2.  
  3. Range("A6:S65536").Sort Key1:=Range("J6"), Order1:=xlAscending, Header:= _
  4. xlGuess, OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, _
  5. DataOption1:=xlSortNormal
  6. End Sub


Pour l'instant, il est copié dans le même module, mais ne s'éxécute pas en même temps.

J'ai le choix avec 2 macros, "Archivage" et "Tri_automatique", je cherche comment les lier ?

Merci.
Expert Programmation

POurquoi faire 2 sub différents ? :??: 
il suffit tout simplement de copier le contenu a la fin de la macro précédente... :na: 

Et puis il faut me rajouter les variables des feuilles devant les .Range... sinon il va trier nimportequoi !!! :o 

par la meme, republie ton code avec ton intégration pour que les personnes dans ton cas puissent suivre l'avancement de ce sujet sur le forum..
(Partage avant tout :D  )

Juste pour confirmer que je ne fais pas fausse route, je dois donc déclarer une nouvelle variable h ? Car je ne vois pas comment intégrer la variable j à cette fonction. :??: 

Je publierai mon code par la suite sans aucun problème c'est juste que j'attendais de l'avoir avancé un peu plus.

Merci.
Expert Programmation

variable h ? pour quoi faire? :??:  pas besoin de toucher a la variable j non plus !

bien non, si c'est pour mettre devant les .Range, tu utilise les variables déja déclarer de tes feuilles ...

Ah mais je crois que tu n'avais pas déclarer de variable pour la feuille archivage.. donc hop, on déclare une variable pour cette feuille la du meme type que celle pour la feuille suivi..

l'avantage des variables c'est de pouvoir les réutiliser !!!!
(ca na marche que au sein d'un meme (Private) sub...)

bon, publie ton code !! je te montre..

Au temps pour moi, c'était bien ma première idée mais n'ayant pas réussi, j'étais parti sur une autre piste.

Voici le code proposé :

  1. Option Explicit
  2.  
  3. Sub linecopy(ByVal line As Range, ByRef Target As Range, Optional clear As Boolean)
  4. line.EntireRow.Copy Destination:=Target
  5. If clear Then Range(Cells(line.Row, 6), Cells(line.Row, 10)).ClearContents
  6. Set Target = Target.Offset(1) '// c'est ca qui te permet d'augmenter tes lignes de 1 sur la feuille archivage..
  7. End Sub '// pas de changement
  8.  
  9. Sub Archivage()
  10.  
  11. Dim lstrow As Long
  12. Dim ws_suivi_m As Worksheet
  13. Dim ws_archivage_m As Worksheet
  14. Dim plage_destination As Range
  15. Dim i As Long
  16. Dim j As Long '// on intègre une nouvelle variable
  17.  
  18. j = Worksheets("Archivage Matériel").Range("A65536").End(xlUp).Row + 1 '// donne la dernière ligne vide de archivage
  19.  
  20. Set ws_suivi_m = Worksheets("Suivi Matériel")
  21. Set plage_destination = Worksheets("Archivage Matériel").Rows(j) '// on intègre j comme début de plage pour la copie
  22. Set ws_archivage_m = Worksheets("Archivage Matériel")
  23.  
  24. lstrow = ws_suivi_m.Range("A65536").End(xlUp).Row '// utilisation de la colonne A et pas J (car trous dans J)
  25. For i = lstrow To 6 Step -1
  26. If ws_suivi_m.Cells(i, 10).Value <> "" Then
  27. linecopy ws_suivi_m.Rows(i), plage_destination, True
  28. End If
  29.  
  30. Next
  31.  
  32. ws_archivage_m.Range("A6:S65536").Sort Key1:=ws_archivage_m.Range("J6"), Order1:=xlAscending, Header:= _
  33. xlGuess, OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, _
  34. DataOption1:=xlSortNormal '// tri les données dans la colonne J à partir de la ligne 6.
  35.  
  36. End Sub


Il me semble que l'on peut alléger le code pour la partie tri après ("J6") mais j'attends confirmation.

Petit souci quand même, le filtre fonctionne bien. Par contre, selon l'endroit où j'exécute la macro, j'ai des différences. Je précise donc :
Si j'exécute ma macro à partir de la feuille "Suivi Matériel", la copie et le tri dans la feuille "Archivage" et enfin l'effacement des cellules s'effectuent correctement.
Par contre, si j'exécute la macro à partir de la feuille "Archivage", la fonction effacement ne marche pas. Par contre c'est OK pour la copie et le tri. :??: 

Merci d'avance pour votre aide.
Expert Programmation

Le code est bon,

Je ne suis pas sur pour l'allegemnt du code du filtre aussi je ne te dirais pas de toucher ...

pour ton probleme d'effacement c'est parceque sur cette ligne de la fonction on a pas définie la feuille dans laquelle prendre le range pour la suppresson du coup il prend la feuille active..
  1. If clear Then Range(Cells(line.Row, 6), Cells(line.Row, 10)).ClearContents

a transformer en :
  1. If clear Then line.Worksheet.Range(Cells(line.Row, 6), Cells(line.Row, 10)).ClearContents

le line.worksheet indique la feuille sur laquelle est prise le .Range que tu veux copier
(dans la fonction le line est ton Range a copier et le .worksheet ondque la feuille sur laquelle es ce .Range)

Comme je te l'ai dit précédementon ne peut pas simplement mettre ta variable ws_suivi_m parceque on est pa dans le meme sub et que la variable n'est pas définie dans la fonction... donc on compose !! :D 

Je n'ai pas compris car j'ai bien remplacé par ta 2e ligne mais il m'a retourné un message d'erreur, c'est pour ça que je me suis mis à creuser...

Voici le message d'erreur :

Erreur d'exécution '1004' :
La méthode 'Range' de l'objet '_Worksheet' a échoué.

Ce message d'erreur renvoie à la ligne 4.

Je remets le code complet pour la forme.

  1. Sub linecopy(ByVal line As Range, ByRef Target As Range, Optional clear As Boolean)
  2.  
  3. line.EntireRow.Copy Destination:=Target
  4. If clear Then line.Worksheet.Range(Cells(line.Row, 6), Cells(line.Row, 10)).ClearContents
  5. Set Target = Target.Offset(1) '// c'est ca qui te permet d'augmenter tes lignes de 1 sur la feuille archivage..
  6.  
  7. End Sub '// pas de changement
  8.  
  9. Sub Archivage()
  10.  
  11. Dim lstrow As Long
  12. Dim ws_suivi_m As Worksheet
  13. Dim ws_archivage_m As Worksheet
  14. Dim plage_destination As Range
  15. Dim i As Long
  16. Dim j As Long '// on intègre une nouvelle variable
  17.  
  18. j = Worksheets("Archivage Matériel").Range("A65536").End(xlUp).Row + 1 '// donne la dernière ligne vide de archivage
  19.  
  20. Set ws_suivi_m = Worksheets("Suivi Matériel")
  21. Set plage_destination = Worksheets("Archivage Matériel").Rows(j) '// on intègre j comme début de plage pour la copie
  22. Set ws_archivage_m = Worksheets("Archivage Matériel")
  23.  
  24. lstrow = ws_suivi_m.Range("A65536").End(xlUp).Row '// utilisation de la colonne A et pas J (car trous dans J)
  25. For i = lstrow To 6 Step -1
  26. If ws_suivi_m.Cells(i, 10).Value <> "" Then
  27. linecopy ws_suivi_m.Rows(i), plage_destination, True
  28. End If
  29.  
  30. Next
  31.  
  32. ws_archivage_m.Range("A6:S65536").Sort Key1:=ws_archivage_m.Range("J6"), Order1:=xlAscending, Header:= _
  33. xlGuess, OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, _
  34. DataOption1:=xlSortNormal '// tri les données dans la colonne J à partir de la ligne 6.
  35.  
  36. End Sub

Je me permets de revenir car je viens de faire un essai avec le même code que précédemment et j'ai eu un autre message d'erreur.

Erreur d'exécution '1004' :
La méthode Sort de la classe Range a échoué.

Ce message concerne le bloc ligne 32 à 34 du code précédent.

Merci de m'aider à trouver d'où peuvent provenir ces erreurs... :??: 

EDIT : je viens de relancer le code sans aucune protection sur ma feuille et il ne bloque plus.
La protection de la feuille peut-elle être à l'origine de ces blocages ?

EDIT2 : sans protection, j'ai toujours le message suivant lorsque j'exécute la macro à partir de la feuille "Archivage"

Erreur d'exécution '1004' :
La méthode 'Range' de l'objet '_Worksheet' a échoué.

Ce message d'erreur renvoie à la ligne 4.
Expert Programmation

hum, c'est pour ca que j'ai dit qu'il allait falloir composer.. pour la fonction...
Je pense qu'il n'accepte pas le line.worksheet.range... (compréhensible... c'est du bidouillage)

Pur le filtre je pense que c'est en effet la protection de ta feuill qui pose probleme, ce que l'on peut faire c'est déproteger la feuille juste avant de faire le tri puis la reprotéger juste apres..(tout dans la meme macro bien entendu)

ta feuille reste protégée tout le tps ainsi... (je recherche en ce moment le code pour faire cela ....)

pour l'histoire du range je pense qu'il va falloir soit :
1. déclarer une variable pour le nom de ta feuille dans la fonction
2. mettre le bouton auquel est attaché la macro dans la feuille suivi pour que le range soit toujours associé a la feuille suivi.

(le 2. est plus simple mais bien moins sur a long terme... on ne sait jamais ce que va faire le prochain utilisateur..)
Expert Programmation

trouvé,
Utilise les fonctions .Protect() et . Unprotect() pour protéger ta feuille archivage.
Regarde dans l'aide excel toutes les options qui te sont proposées : une sur le mot de passe et une autre sur le filtre notamment ....... :D 

cette derniere te permet justement de laisser la possibilité de faire des filtres sans changer ni cacher les donnees donc tout en protégant la feuille ... exactement ce qu'il te faut !!
quand tu rédigera le code, fais bien attention a la syntaxe (les virgules) et je continue a cherchr une solution pour que la fonction prenne en charge le changement de feuille.

Je nete lache pas, rassure toi...
Expert Programmation

et hop, trouvé...

  1. Sub linecopy(ByVal line As Range, ByRef Target As Range, Optional clear As Boolean)
  2. Dim ws_suivi_m As Worksheet
  3. Set ws_suivi_m = Worksheets("Suivi Matériel") '// declaration classique de ta feuille
  4. line.EntireRow.Copy Destination:=Target
  5. If clear Then ws_suivi_m.Range(Cells(line.Row, 6), Cells(line.Row, 10)).ClearContents '// utilisation de la feuille pour indiquer l'addresse du .Range
  6. Set Target = Target.Offset(1)
  7. End Sub


J'étais sur une atre piste mais, pourquoi faire compliqué qd on peut faire simple... en plus tu as déja compris le fonctionnement de cette déclaration donc pourquoi s'en priver !!

Bonjour,

Après avoir remplacé le code par celui que tu proposes, j'ai toujours le même souci lorsque j'exécute la macro manuellement à partir de la feuille archivage.

Erreur d'exécution '1004' :
La méthode 'Range' de l'objet '_Worksheet' a échoué.

Le débogage se situe ligne 5 de ton précédent code après le terme "Then".

Par contre aucun souci lorsqu'elle est exécutée de la feuille "Suivi".

Je vais faire des tests et vous tiens informé si je trouve avant une proposition.

Merci d'avance.
Expert Programmation

Gtmacrodeb,
bon we ?

le cade marche impec chez moi des 2 feuilles (mais je n'ai aucune feuille protégée). Donc je pense que ton probleme viens de la...

As tu utilisé les fonctions .Unprotect ou .Protect pour déprotéger la feuille le tps de la macro ??

Parce que une fois fais ceci, la protection sur ta feuille ne devrai plus poser probleme (étant donné que tu la désactive avant la macro et réactive a la fin de cette derniere !!!)
Ta solution se trouve dans l'utilisation de ces 2 termes. :D 

Bon week-end pour moi, ;)  , j'espère que pour toi aussi (je n'ai pas osé faire des amabilités sur le forum...)

Concernant la macro, pour l'instant je l'exécute sans aucune protection sur ma feuille donc je me pense pas que ça puisse la bloquer. Me trompe-je ?

J'ai quand même essayé d'avancer une macro avec protect/unprotect :

  1. Option Explicit
  2.  
  3. Sub linecopy(ByVal line As Range, ByRef Target As Range, Optional clear As Boolean)
  4.  
  5. Dim ws_suivi_m As Worksheet
  6. Set ws_suivi_m = Worksheets("Suivi Matériel") '// declaration classique de ta feuille
  7.  
  8. line.EntireRow.Copy Destination:=Target
  9. If clear Then ws_suivi_m.Range(Cells(line.Row, 6), Cells(line.Row, 10)).ClearContents '// utilisation de la feuille pour indiquer l'addresse du .Range
  10. Set Target = Target.Offset(1)
  11.  
  12. End Sub
  13.  
  14. Sub Archivage()
  15.  
  16. Dim lstrow As Long
  17. Dim ws_suivi_m As Worksheet
  18. Dim ws_archivage_m As Worksheet
  19. Dim plage_destination As Range
  20. Dim i As Long
  21. Dim j As Long '// on intègre une nouvelle variable
  22.  
  23. j = Worksheets("Archivage Matériel").Range("A65536").End(xlUp).Row + 1 '// donne la dernière ligne vide de archivage
  24.  
  25. Set ws_suivi_m = Worksheets("Suivi Matériel")
  26. Set plage_destination = Worksheets("Archivage Matériel").Rows(j) '// on intègre j comme début de plage pour la copie
  27. Set ws_archivage_m = Worksheets("Archivage Matériel")
  28.  
  29. ws_archivage_m.Unprotect "mdp" '// Retire la protection de la feuille "mdp"="mot de passe"
  30.  
  31. lstrow = ws_suivi_m.Range("A65536").End(xlUp).Row '// utilisation de la colonne A et pas J (car trous dans J)
  32. For i = lstrow To 6 Step -1
  33. If ws_suivi_m.Cells(i, 10).Value <> "" Then
  34. linecopy ws_suivi_m.Rows(i), plage_destination, True
  35. End If
  36.  
  37. Next
  38.  
  39. ws_archivage_m.Range("A6:S65536").Sort Key1:=ws_archivage_m.Range("J6"), Order1:=xlAscending, Header:= _
  40. xlGuess, OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, _
  41. DataOption1:=xlSortNormal '// tri les données dans la colonne J à partir de la ligne 6.
  42.  
  43. ws_archivage_m.Protect "mdp", True, True, True '// remet la protection
  44.  
  45.  
  46. End Sub


Je ne sais pas si mes fonctions Unprotect et Protect sont bien situées.

J'attends tes remarques et corrections si nécessaires.
Expert Programmation

Tout marche au poil chez moi (j'ai pas encore regarder tes (.Protect et unprotect).
Es tu sur d'avoir bien mis les "." et parentheses sur le .Range de la fonction ?
C'est le Range qui bloque or chez moi ca marche a merveille....
Vérifie ta syntaxe, tes noms de feuilles (accents, espaces et majuscules) ..
Il y a forcément une faute qqpart...
essaye de faire tourner ta macro en enlevant l'option explicit...juste pour voir si ce n'est pas un probleme de déclarations )...

(ton mot de passe est "mdp" ??? c'est pa trop solide ca :p  )
A te lire.

EDIT : ok pour le positionnement de tes Protect et unprotect. Met des parentheses autour des options... c'est juste plus lisible pour qqn qui découvre le code....
Expert Programmation

sans prendre en compte les protect et unprotect, essaye de faire tourner ce code sur ta feuille. (j'ai modifié la syntaxe de la fonction en intégrant une nouvelle variable pour la feuille source. Ce qui permet de préciser le code. et du coup, la modification se fait aussi lors de con utilisation dans le code de ta macro archivage.

dsl si tu était en train de lire l'horrible code que je venais de poster !!!
Ton probleme se situait ds la fonction, il fallait simplement présicer la feuille a l'intérieur du Range.

  1. Sub linecopy(ByVal ws_source as Worksheet, ByVal line As Range, ByRef Target As Range, Optional clear As Boolean) '// nouvelle variable
  2. line.EntireRow.Copy Destination:=Target
  3. If clear Then Range(ws_source.Cells(line.Row, 6), ws_source.Cells(line.Row, 10)).ClearContents '// ici modifs
  4. Set Target = Target.Offset(1)
  5. End Sub
  6. [...]
  7.  
  8. linecopy ws_suivi_m, Rows(i), plage_destination, True '// changement de syntaxe


Ca devrai etre bon mtn !!

Tout d'abord, une nouvelle fois merci pour le temps que tu prends pour m'aider.

Donc j'ai bien essayé ton dernier code et je n'ai effectivement plus d'erreur de débogage.

Cependant, lorsque j'exécute la macro de la feuille "Suivi", toujours aucun problème. Par contre lorsque je l'exécute de la feuille "Archivage", la ligne ne se copie pas... :??:  Par contre, elle s'efface bien au niveau du tableau "Suivi".

Je vais continuer mes tests.

Encore merci.

PS : non je n'utilise pas mdp comme mot de passe, rassure-toi, j'ai rajouté mes initiales :) 

Je viens préciser le problème rencontré suite aux tests effectués.

Lorsque j'exécute la macro à partir de la feuille "Archivage", au lieu de copier la ligne issue de la feuille de suivi. Il me recopie la ligne 7 de la feuille "Archivage" en ligne 9 en insérant une ligne. Si je relance une macro du même endroit, il me recopie la ligne 8 en ligne 10 toujours de la feuille "Archivage". Par contre après ces deux essais, il ne copie plus rien mais continue à effacer les "bonnes" lignes de la fiche "Suivi".

Si cela peut faciliter les recherches... et faire avancer la science...

EDIT 2 : en fait lorsque j'exécute la macro de la feuille d'"Archivage", si la ligne 10 de ma feuille "Suivi" remplit correctement la condition, il me recopie la ligne 10 de la feuille d'"Archivage" au lieu de celle de "Suivi".

En fait problème résolu en partant du 2e code que tu m'avais fourni avec la déclaration de variable ws_suivi_m voir ci-dessous.

  1. Sub linecopy(ByVal line As Range, ByRef Target As Range, Optional clear As Boolean) '// nouvelle variable
  2.  
  3. Dim ws_suivi_m As Worksheet
  4.  
  5. Set ws_suivi_m = Worksheets("Suivi Matériel")
  6.  
  7. line.EntireRow.Copy Destination:=Target
  8. If clear Then Range(ws_suivi_m.Cells(line.Row, 6), ws_suivi_m.Cells(line.Row, 10)).ClearContents '// ici modifs
  9. Set Target = Target.Offset(1)
  10.  
  11.  
  12. End Sub
  13.  
  14. Sub Archivage()
  15.  
  16. Dim lstrow As Long
  17. Dim ws_suivi_m As Worksheet
  18. Dim ws_archivage_m As Worksheet
  19. Dim plage_destination As Range
  20. Dim i As Long
  21. Dim j As Long '// on intègre une nouvelle variable
  22.  
  23. j = Worksheets("Archivage Matériel").Range("A65536").End(xlUp).Row + 1 '// donne la dernière ligne vide de archivage
  24.  
  25. Set ws_suivi_m = Worksheets("Suivi Matériel")
  26. Set plage_destination = Worksheets("Archivage Matériel").Rows(j) '// on intègre j comme début de plage pour la copie
  27. Set ws_archivage_m = Worksheets("Archivage Matériel")
  28.  
  29. lstrow = ws_suivi_m.Range("A65536").End(xlUp).Row '// utilisation de la colonne A et pas J (car trous dans J)
  30. For i = lstrow To 6 Step -1
  31. If ws_suivi_m.Cells(i, 10).Value <> "" Then
  32. linecopy ws_suivi_m.Rows(i), plage_destination, True
  33. End If
  34.  
  35. Next
  36.  
  37. ws_archivage_m.Range("A6:S65536").Sort Key1:=ws_archivage_m.Range("J6"), Order1:=xlAscending, Header:= _
  38. xlGuess, OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, _
  39. DataOption1:=xlSortNormal '// tri les données dans la colonne J à partir de la ligne 6.
  40.  
  41.  
  42. End Sub


Maintenant, je vais confirmer la partie protection/déprotection de la feuille et ensuite déclenchement de la macro à partir de 2 évènements.

Pourrais-tu déjà me confirmer si cela est possible ? Je souhaiterais la déclencher soit par un bouton ou alors si ce n'est pas fait, lorsque la personne quitte le programme sauvegarde automatique et déclenchement de la macro.

Merci d'avance.

EDIT : je viens de faire le test avec le mot de passe et cela fonctionne parfaitement. Merci. J'attends ta confirmation pour savoir s'il est possible de déclencher cette macro des 2 manières.

EDIT 2 : je viens de "concevoir" un bouton, à partir de la barre d'outils "Formulaire", auquel j'ai affecté la macro. Pourrais-tu me confirmer que cette méthode est correcte ? (en tout cas, c'est fonctionnel de mon côté). Je cherche maintenant à exécuter la macro et sauvegarder le fichier de manière automatique lorsque l'on quitte.
Expert Programmation

salut,

Alors, ok pour ta modif..
Tu ne pourra pas automatiquement déclencher la macro lorsque tu ferme Excel. On n'a aucun moyen de pouvoir insrer sous excel du code lorsque tu cliques sur la crois rouge par exemple ou que tu ferme Excel.(A ma connaissance)
La seule solution est donc le bouton que tu crée et auquel tu assigne une macro(clique droit/assigner une macro). Tu peux par contre rajouter une ligne a la fin de la macro pour sauvegarder le fichier :

utilise le code .Save avec le nom de ton fichier excel devant ou bien : ActiveWorkbook.Save (bcp moins joli)
et pour le quitter : .Quit.

A défaut de l'enclencher à la fermeture, est-il possible d'affecter une macro à l'action de "sauvegarder", je précise mon idée.

Est-il possible de déclencher la macro à partir du moment où l'utilisateur effectue une sauvegarde soit manuellement, soit automatiquement lorsqu'il quitte le fichier et que la fenêtre lui propose de sauvegarder, ou alors lorsque la sauvegarde automatique s'effectue toutes le 3, 5 ou 10 minutes ?
Lassé par la pub ? Créez un compte