Macro

Bonjour,
Je ne connais pas le langage VBA, j’ai réussi à faire une macro dans Excel pour archiver sur un feuillet 2 les ligne en jaune du feuillet 1, mais ma condition est fausse je sélectionne toujours le ligne A3 à Q3 ou toutes les lignes si je mets (“A:Q”).
Je n’arrive pas à m’en sortir !!!
Merci de me donner le solution pour sélectionner la ligne de A à Q si Cellule A est Jaune.

Sub SOLDEE()
’ Macro enregistrée le 23/04/2009 par Benoit

For Each C In Range(“A2:A40”)
If C.Interior.ColorIndex = 6 Then Range(“A3:Q3”).Select
If Range(“A:Q”).End(xlDown).Row < 0 Then Range(“A:Q”).Select
Selection.Copy
Application.CutCopyMode = False
Selection.Delete Shift:=xlUp
Sheets(“SOLDEE”).Select
Range(“A1”).Select
If Range(“b2”).Value <> “” Then
maxi2 = Range(“b1”).End(xlDown).Row + 1
Else
maxi2 = 2
End If

Range("a" & maxi2).Select
  ActiveSheet.Paste

Next C

End Sub

Au lieu de sélectionner à chaque fois la même zone(A3:Q3), il faut que tu fasses dépendre celle-ci de la cellule sur laquelle porte le test (la cellule C)
If C.Interior.ColorIndex = 6 Then Range(C, C.offset(0,16)).Select
ou si tu préfères
If C.Interior.ColorIndex = 6 Then Range(C, “Q”&C.row)).Select

et pour te positionner dans ta feuille archive :
Range(“B1000”).End(xlUp).offset(0,-1).Paste
on suppose ici que ta feuille a moins de 1000 lignes utilisables, sinon tu adaptes

Pourquoi testes-tu sur la colonne B ? la colonne A est préremplie ?
PasteSpecial ne serait-il pas mieux que Paste ?

Bonjour,
Et merci beaucoup d’avoir répondu ! Je reviens sur mon problème, que tu résous partiellement , car il sélectionne bien la première ligne qui est en jaune (ligne 3 sur mon fichier) l’efface et la copie sur archive, mais quand tu reviens sur le feuillet 1, la ligne 3 est toujours sélectionnée et donc il la recopie alors qu’elle n’est pas en jaune.
J’ai essayé tes 2 codes :
If C.Interior.ColorIndex = 6 Then Range(C, C.offset(0,16)).Select
ou
If C.Interior.ColorIndex = 6 Then Range(C, “Q”&C.row).Select
mais il manque quelque chose !

Je ne sais pas le déboguer, il bloque sur ??Range(C, C.Offset(0, 16)).Select

Merci de ton aide précise…

Effectivement, tu fais ta boucle principale avec un foreach, mais foreach et delete n’ont jamais fait bon menage …
Il faudrait que tu modifies ton programme à ce niveau.
Par exemple, on peut utiliser le fait que après A40 (ou B40 …) il y a une cellule vide alors qu’avant la colonne est remplie.
Et donc tu fais un test du genre
set C = range(“A2”)
while C <> “”

set C=C.offset(1)
wend

j’espère que tu vois ce que je veux dire ?

Bonjour,

Merci de m’éclairer de tes lumières car je suis vraiment nul en Macro…

If C.Interior.ColorIndex = 6 Then Range(C, C.Offset(0, 16)).Select
A quoi correspond C.Offset(0, 16)
car à la fin on met Set C = C.Offset(1) et cela bogue.
J’ai essayé Set C = C.Offset(0, 16) mais dans ce cas rien ne se passe !

Heureusement que je ne suis pas bloqué par cette macro, car j’ai bien du mal à m’en sortir, en manuel ça va…

Merci @+ Ben

C.offset(a,b), c’est la cellule qui se situe a lignes plus bas que C, et b colonnes plus à droite.
Note bien que a et/ou b peuvent être négatifs, ce qui couvre les quatre directions
donc C.offset(0,16), par rapport la la cellule A3 (ton 1er exemple) c’est une cellule sur la même ligne, 16 colonnes plus loin, donc Q3

C.offset(1), c’est équivalent à C.offset(1,0), donc cellule juste en dessous.
Et avec le set, tu déplaces la référence C vers la cellule dessous

Si tu as un problème à la ligne set=C=C.offset(1), tu ne dois pas avoir eu qu’un message du genre “ça bogue”, il devait y avoir un numéro d’erreur et un texte bien précis.
Et ce serait certainement très utile pour bien cerner la cause.
Mais sans faire dans la divination, je pense que le problème doit venir de plus haut.
Tu n’a pas dû être assez rigoureux dans l’écriture des lignes de suppression proprement dites, et tu as dû effacer la ligne qui contenait la cellule C ; l’erreur vient alors du fait que fais référence à une entité inconnue.

En principe, quand on fait des suppressions, on commence toujours par la dernière ligne.
Ce n’est pas beaucoup plus compliqué à mettre en place et ça évite bien des ennuis dûs au redimensionnement permanent de la zone de référence du fait de la suppression des lignes.

Mais comme on n’a aucune idée de la manière dont se présentent tes données par rapport à l’ensemble de ta feuille, impossible de faire d’emblée une proposition en ce sens.

Edit :
Essaie de faire une copie d’écran, par ex, pour donner un aperçu
Edité le 08/06/2009 à 17:18

Bonjour,

Tes explications sont très intéressantes. J’ai effectivement un code erreur : Erreur d’exécusion ‘1004’ la méthode “Select” de l’objet “Range” a échoué.
Tu me parles de cellule C ! Mais je n’ai pas créé de cellule C ! Il me manque les bases pour bien comprendre comment cela fonctionne…
On peut commencer par le bas sans problème à partir de la ligne 50 cela devrait aller.
Je ne trouve pas comment te joindre ma copie d’écran dans cette fenêtre !
Je te joins mon code qui mérite d’être repris complètement…

Sub SOLDEE()

Set C = Range(“A2”)
While C <> “”
If C.Interior.ColorIndex = 6 Then Range(C, C.Offset(0, 16)).Select

If Range(“A:Q”).End(xlDown).Row < 0 Then Range(“A:Q”).Select

Selection.Copy
Application.CutCopyMode = False
Selection.Delete Shift:=xlUp
Sheets("SOLDEE").Select
Range("A1").Select

If Range(“b2”).Value <> “” Then
maxi2 = Range(“b1”).End(xlDown).Row + 1
Else
maxi2 = 2
End If

Range("a" & maxi2).Select
  ActiveSheet.Paste
  
  Set C = C.Offset(1)

Wend
End Sub

Voici la copie d’écran…
Sur cette adresse : dl.free.fr…

Merci

C’est un abus de langage. J’aurais dû écrire “la cellule à laquelle on a affecté la référence C”
Et c’est bien toi qui l’as créée :
For Each C In Range(“A2:A40”)
C’est vrai que maintenant elle a dû se transformer en
Set C = Range(“A2”), mais le résultat est le même

En plus de la ligne de départ, il faut savoir sur quelle colonne de reference on va travailler.
Il est important de choisir une colonne dans laquelle toutes les lignes seront remplies (donc de 50 à 2 pour toi).

Au vu de ta copie d’écran, la colonne E devrait convenir.
Je regarderai les modifications à apporter au code dès que j’aurai un excel sous la main
Edité le 09/06/2009 à 11:31

Tu n’as pas donné une vue complète de ta page, mais je pense que tu n’as pas intérêt à supprimer uniquement les cellules utilisées de la ligne, donc les colonnes de A à Q, mais la ligne complète.

Le principe est le suivant : tu positionnes en haut du tableau (cellule A1)
Tu délimites l’étendue complète du tableau (l’équivalent de Ctrl+*)
Tu identifgies le numero de la dernière ligne (égal au nombre de lignes sélectionnées, puisqu’on est parti de la ligne 1)
Ensuite, dans la colonne A, tu remontes cellule par cellule en supprimant la ligne complète lorsque la couleur correspond


Sub Soldee()
    Set R = Range("A1").CurrentRegion
    For L = R.Rows.Count   To 2 Step -1
        If Cells(L, 1).Interior.ColorIndex = 6 Then
            Cells(L, 1).EntireRow.Delete
        End If
    Next
End Sub

Bon, ton code fonctionne, sauf que je copie sur soldée au lieu de supprimer.
J’ai donc remplacer Cells(L, 1).EntireRow.Delete par Cells(L, 1).EntireRow.Select
et j’ai gardé la suite de mon code, mais il manque quelque chose pour qu’il revienne au feuillet 1, car une fois copié la première ligne en jaune sur Soldée il reste sur Soldée et s’arrête .
Je te joins mon fichier Excel al’adresse : dl.free.fr…
Tu pourras faire un essai pour trouver le maillon manquant.
Merci d’avance.

Tu as deux problèmes :

  • d’abord tu copies, et tout de suite derrière tu vides le presse papiers et tu supprimes la source ; ce qui fait que tu n’as plus grand chose à coller quand tu arrives dans l’autre feuille
  • ensuite, à partir du moment où tu as activé la feuille SOLDEE pour y coller les données, il faut que tu reviennes dans Feuil1 avant de boucler sur la valeur suivante.
    Il te faut donc une ligne sheets(“Feuil1”).Select juste avant le Next

Tu peux aussi optimiser ton code en tenant compte des différences de comportement de VBA par rapport à ce qu’on fait en manuel sur excel.
1- tu n’es pas obligé de sélectionner pour copier
Cells(L, 1).EntireRow.Copy
est correct.
2- de la même manière, tu n’est pas obligé de sélectionner la feuille cible pour coller tes valeurs.
3- pour trouver la première cellule vide, plutôt que de faire des acrobaties depuis le début du fichier, tu peux partir du bas (j’ai choisi la ligne 1000, mais tu peux aller plus bas si ton tableau est plus grand). Et tu passes la commande équivalente à Maj+Fléche Haut, qui va te positionner juste en dessous de la dernière cellule occupée :
Range(“A1000”).End(xlUp)

exemple de code final :


Sub SOLDEE()
 Set R = Range("A1").CurrentRegion
   For L = R.Rows.Count To 2 Step -1
     If Cells(L, 1).Interior.ColorIndex = 6 Then
        Cells(L, 1).EntireRow.Copy
        Sheets("SOLDEE").Range("A1000").End(xlUp).PasteSpecial
        Application.CutCopyMode = False
        Cells(L, 1).EntireRow.Delete
    End If
  Next
End Sub

NB : je n’ai pas trouvé de raison pour laquelle tu faisais référence à la colonne B plutôt qu’à la colonne A. Il faudra peut être être vigilant sur ce point.

Edit : pour la ligne de collage, la syntaxe exacte est
Sheets(“SOLDEE”).Range(“A1000”).End(xlUp).offset(1).PasteSpecial
Edité le 09/06/2009 à 18:02

Avec sheets(“Feuil1”).Select, ça marche, ça pédale un peu mais on a le résultat espéré.
J’ai essayé avec ton code simplifié, c’est beaucoup plus rapide, mais il copie les 3 lignes en jaune les unes sur les autres donc il ne reste que la dernière copie ?
Je suis sur MAC, il interprète peut-être le code d’une manière différente.

La première solution même un peu lente me convient tout-à-fait, merci beaucoup de ton aide.

Non ce n’est pas normal ; j’ai dû rater une ligne en recopiant.
Je vais revoir ça quand je changerai de machine

Effectivement, j’en avais oublié un morceau
Sheets(“SOLDEE”).Range(“A1000”).End(xlUp).Offset(1).PasteSpecial

Merci beaucoup, à une prochaine fois…