VBA - Copier/coller d'une ligne dont une cellule a été modifiée

Fermé
einahpets31 Messages postés 4 Date d'inscription mercredi 12 avril 2017 Statut Membre Dernière intervention 12 avril 2017 - 12 avril 2017 à 10:09
einahpets31 Messages postés 4 Date d'inscription mercredi 12 avril 2017 Statut Membre Dernière intervention 12 avril 2017 - 12 avril 2017 à 17:34
Bonjour à tous,

J'ai un fichier excel qui me sert de BDD et je cherche à faire passer des lignes automatiquement d'un onglet actif à un onglet d'archives lorsque l'action de cette ligne est faite ou annulée pour rendre mon fichier plus ergonomique.

DG1 est mon onglet "actif"
DG1 archives, mon onglet d'archivage
Dans ma colonne S de DG1, on met le statut de l'action: "closed", "cancelled", "on going".
Je souhaite dans un premier temps, que dès qu'un utilisateur entre cancelled dans cette colonne, la ligne concernée disparaisse de DG1 et soit copiée dans DG1 archives.

J'ai fait une macro avec mes connaissances basiques et en recherchant sur le forum, mais je bloque: Ma macro marche pour la 1ere fois qu'on passe une action cancelled, mais ensuite me dit que la méthode Range a échoué. En fait, ma ligne DG1 reste copiée et j'arrive à refaire tourner la macro seulement si je "désélectionne" la copie.
La ligne modifiée (quand ça marche!) est bien copiée dans l'onglet DG1 archives dans la 1ere ligne vide mais si j'arrive à faire tourner ma macro deux fois, ça recopie toujours dans la même ligne sans passer à la suivante.

Voilà mon code, ne vous fachez pas je suis débutante ;-)

Private Sub Worksheet_Change(ByVal Target As Range)

Dim KeyCells As Range

Set KeyCells = Range("S3:S65536")

If Not Application.Intersect(KeyCells, Range(Target.Address)) Is Nothing Then
If Range(Target.Address) = "Cancelled" Then
Range(Cells(Target.Row, 1), Cells(Target.Row, 22)).Select
Selection.Copy
Sheets("DG1 archives").Activate
Worksheets("DG1 archives").Range("A" & Rows.Count).End(xlUp).Offset(1).Select '
Worksheets("DG1 archives").Paste
End If
End If

End Sub


Merci à ceux qui auront le temps de m'apporter leur soutien !
A voir également:

1 réponse

thev Messages postés 1853 Date d'inscription lundi 7 avril 2008 Statut Membre Dernière intervention 27 avril 2024 681
12 avril 2017 à 12:53
Bonjour,

Ce code devrait fonctionner

 
Private Sub Worksheet_Change(ByVal Target As Range)
Dim keycells As Range, cell As Range

Set keycells = Columns("S")
If Not Intersect(Target, keycells) Is Nothing Then
If Target.Value = "Cancelled" Then
Set cell = Sheets("DG1 archives").Columns("A").Find(Null, SearchDirection:=xlPrevious)
Target.EntireRow.Resize(, keycells.Column - 1).Copy cell
Application.EnableEvents = False
Target.EntireRow.Delete
Application.EnableEvents = True
End If
End If
End Sub

--
 
1
einahpets31 Messages postés 4 Date d'inscription mercredi 12 avril 2017 Statut Membre Dernière intervention 12 avril 2017
12 avril 2017 à 15:33
Super, merci de ta réponse!
La macro fonctionne dans le sens où :
- ça copie la ligne
- ça supprime la ligne de DG1 (c'est parfait!!)
Par contre, en "DG1 archives" la macro colle la ligne à partir de la ligne 37 et je n'ai rien d'autre sur cet onglet, je ne vois pas où ça va pas :-(
0
thev Messages postés 1853 Date d'inscription lundi 7 avril 2008 Statut Membre Dernière intervention 27 avril 2024 681 > einahpets31 Messages postés 4 Date d'inscription mercredi 12 avril 2017 Statut Membre Dernière intervention 12 avril 2017
Modifié le 12 avril 2017 à 16:25
Par contre, en "DG1 archives" la macro colle la ligne à partir de la ligne 37
Les lignes 1 à 36 ont dû être utilisées. Supprime-les même si elles sont vides et enregistre à nouveau ton classeur.

Et pour ma compréhension, comment fonctionne la ligne suivante?
"Target.EntireRow.Resize(, keycells.Column - 1).Copy cell"

Target.EntireRow correspond à toute la ligne de la cellule où a été opéré le changement.
La méthode .Resize(nb_lignes, nb_colonnes) retaille le nombre de colonnes de cette ligne à keycells.Column - 1, (c'est à dire à 18) , le nombre de lignes n'étant pas modifié car non mentionné (donc égal à zéro par défaut).
Si par exemple, la ligne est égale à 3, Target.EntireRow.Resize(, keycells.Column - 1) correspond à Range("$A3:$R3").

"cell" correspond à la cellule de la colonne A relative à la première ligne non utilisée de la feuille. Ce n'est pas forcément la première cellule non utilisée de la colonne A si d'autres colonnes utilisent des lignes en dessous de cette cellule.
0
einahpets31 Messages postés 4 Date d'inscription mercredi 12 avril 2017 Statut Membre Dernière intervention 12 avril 2017
12 avril 2017 à 15:39
Et pour ma compréhension, comment fonctionne la ligne suivante?
"Target.EntireRow.Resize(, keycells.Column - 1).Copy cell"
0
einahpets31 Messages postés 4 Date d'inscription mercredi 12 avril 2017 Statut Membre Dernière intervention 12 avril 2017
12 avril 2017 à 17:34
Merci beaucoup pour les explications! Et effectivement en supprimant les lignes "utilisées" ça fonctionne!
0