Fonctions worksheet_change avec plusieurs conditions
Bonjour,
J'ai un tableau excel qui me permet à l'heure actuelle de couper un ligne dans une feuille et la coller dans une autre via VBA lorsqu'une condition dans une colonne est remplie.
J'aurais besoin de pouvoir faire la même chose avec une seconde colonne et une troisième par la suite.
Au départ je pensais faire deux fonction worksheet_change dans la même feuille mais cela ne fonctionne pas.
Je vous met le code initial et mon code modifié qui je n'arrive pas à mettre à jour.
D'après ce que j'ai lu sur le forum et d'autre forums, il me faudrait un elseif mais je ne parviens pas à le placer correctement :s
Est-ce que vous pourriez m'aider.
Ci dessous le code initial :
Private Sub WorkSheet_Change(ByVal Target As Range)
Dim LgnS As Range, TblC As Range, lnS%, lnC%, k%
If Target.Count > 1 Or Target.Row < 5 Or Target.Column <> 5 Then Exit Sub
If Target.Value = "Dossier classé" Then
lnS = Target.Row - 4
Set LgnS = Me.ListObjects(1).DataBodyRange.Rows(lnS)
k = LgnS.Columns.Count
With Worksheets("Dossier classés").ListObjects(1)
If .Range.Cells(2, 1) <> "" Then
Set TblC = .DataBodyRange: lnC = TblC.Rows.Count + 1
Else
Set TblC = .Range.Rows(2): lnC = 1
End If
End With
TblC.Cells(lnC, 1).Resize(, k).Value = LgnS.Value
LgnS.EntireRow.Delete
End Ifet ici ma tentative de modification :
Private Sub WorkSheet_Change(ByVal Target As Range)
Dim LgnS As Range, TblC As Range, lnS%, lnC%, k%
If Target.Count > 1 Or Target.Row < 5 Or Target.Column <> 5 Then Exit Sub
If Target.Value = "Dossier classé" Then
lnS = Target.Row - 4
Set LgnS = Me.ListObjects(1).DataBodyRange.Rows(lnS)
k = LgnS.Columns.Count
With Worksheets("Dossier classés").ListObjects(1)
If .Range.Cells(2, 1) <> "" Then
Set TblC = .DataBodyRange: lnC = TblC.Rows.Count + 1
Else
Set TblC = .Range.Rows(2): lnC = 1
End If
End With
TblC.Cells(lnC, 1).Resize(, k).Value = LgnS.Value
LgnS.EntireRow.Delete
End If
If Target.Count > 1 Or Target.Row < 5 Or Target.Column <> 3 Then Exit Sub
If Target.Value = "BH" Then
lnS = Target.Row - 4
Set LgnS = Me.ListObjects(1).DataBodyRange.Rows(lnS)
k = LgnS.Columns.Count
With Worksheets("BH").ListObjects(1)
If .Range.Cells(2, 1) <> "" Then
Set TblC = .DataBodyRange: lnC = TblC.Rows.Count + 1
Else
Set TblC = .Range.Rows(2): lnC = 1
End If
End With
TblC.Cells(lnC, 1).Resize(, k).Value = LgnS.Value
LgnS.EntireRow.Delete
End If
End SubDonc en gros, si dans ma colonne 5 il est indiqué dossier classé, la ligne se coupe et colle dans la feuille appelée dossier classé.
Et je voudrais faire la même chose avec la colonne 3, si la cellule contient BH, la ligne se coupe et se colle dans la feuille BH.
Il doit s'agir d'une bêtise de synthaxe mais je ne trouve pas trop où se situe l'erreur.
Merci d'avance
Bonjour,
Ci-dessous une macro à tester
Private Sub WorkSheet_Change(ByVal Target As Range)
Dim LgnS As Range, TblC As Range, lnS%, lnC%, k%
If Target.Count > 1 Or Target.Row < 5 Or Target.Column <> 3 Or Target.Column <> 5 Then Exit Sub
Select Case Target.Column
Case 3
If Target.Value = "BH" Then
lnS = Target.Row - 4
Set LgnS = Me.ListObjects(1).DataBodyRange.Rows(lnS)
k = LgnS.Columns.Count
With Worksheets("BH").ListObjects(1)
If .Range.Cells(2, 1) <> "" Then
Set TblC = .DataBodyRange: lnC = TblC.Rows.Count + 1
Else
Set TblC = .Range.Rows(2): lnC = 1
End If
End With
TblC.Cells(lnC, 1).Resize(, k).Value = LgnS.Value
LgnS.EntireRow.Delete
End If
Case 5
If Target.Value = "Dossier classé" Then
lnS = Target.Row - 4
Set LgnS = Me.ListObjects(1).DataBodyRange.Rows(lnS)
k = LgnS.Columns.Count
With Worksheets("Dossier classés").ListObjects(1)
If .Range.Cells(2, 1) <> "" Then
Set TblC = .DataBodyRange: lnC = TblC.Rows.Count + 1
Else
Set TblC = .Range.Rows(2): lnC = 1
End If
End With
TblC.Cells(lnC, 1).Resize(, k).Value = LgnS.Value
LgnS.EntireRow.Delete
End If
End Select
End SubEn espèrant que cela t'aide
Bonjour,
Merci pour la réponse, malheureusement la macro ne semble pas fonctionner.
En fait je suis parti du fichier en pièce jointe dans le sujet suivant (voir la réponse de Mferand), j'aurais sans doute du vous le signaler au départ :
https://forum.excel-pratique.com/viewtopic.php?t=109252
c'est juste que j'ai maintenant rajouté des feuilles avec les contrôleurs et que je voudrais que la ligne se coupe automatiquement dans la feuille ad-hoc.
Bonjour,
Quand j'aurai un moment ... je regarderai ton fichier ...
oui pas d'urgence, c'est déjà très gentil de se pencher sur mon problème
Bonjour,
En regardant ton fichier, je voudrais savoir si BH est, en fait, une nouvelle initiale qui s'ajoute aux 8 contrôleurs existants ?
Si la réponse est positive ... faut-il une solution générique pour tous les contrôleurs ...
ou Uniquement ...une solution pour BH ...?
En gros BH correspondra à un nouveau contrôleur, qui remplace MG dans la liste.
Mais le but serait d'appliquer la formule pour tous les contrôleurs qui auraient chacun une feuille avec initiale pour le suivi dans le fichier de base.
Re,
Est-ce-que cela signifie que, dans ton fichier réel .... tu as déjà ajouté tous les onglets pour tous les contrôleurs ...?
Contrairement à la macro existante qui permet l'archivage ... et qui par définition efface totalement la ligne concernée ...
il me semble que, dans le cas des contrôleurs ... il s'agit d'une approche très différente ... une ventilation par personne ...
Est-ce que je me trompe ?
P.S. Félicitations pour le dynamisme de Schaerbeek ...
Je vais te rajouter le fichier tel qu'il est actuellement en supprimant les données (par soucis de confidentialité ^^)
en gros il faudrait conserver la marcro d'archivage (peu importe la feuille où on se trouvera, que ce soit sur une feuille contrôleur ou sur la liste principale) et en prime pouvoir déplacer directement la ligne concernée dans la feuille dont le contrôleur est responsable et que ce changement se fasse automatiquement lorsque les initiales du contrôleur sont choisies (en sachant très bien qu'une fois que c'est couper-coller on ne revient pas en arrière avec ctrl + z)
EDIT : J'ai oublié de préciser que j'ai rajouté une colonne qui indique la date de la dernière action.
P.S : On fait ce qu'on peut et oui j'aurais du éditer les métadonnées ^^
Re,
Je crois que je ne me suis pas exprimé très clairement ...
Autant il parait logique d'utiliser une macro évènementielle pour l'archivage ... car on se trouve en fin de processus ...
autant il parait assez illogique de l'envisager pour l'affectation à un contrôleur ... car, dans ce cas de figure, on se trouve au tout début d'un processus ...
J'espère que cette explication est moins confuse ...
D'accord mais si je n'utilise pas de macro événementielle pour que la ligne se coupe et colle dans la feuille du contrôleur directement quel serait le type de macro à utiliser ?
D'accord mais si je n'utilise pas de macro événementielle pour que la ligne se coupe et colle dans la feuille du contrôleur directement quel serait le type de macro à utiliser ?
Bonjour,
Je ne connais pas ton degré de familiarité avec Excel ....
Mais il n'existe que deux types de macros :
1. Macros Standard
2. Macros Evènementielles
Ben à priori pour moi elle était événementielle, quand on choisit un nom de contrôleur dans la première feuille, la ligne se coupe et colle dans la feuille dédiée à ce contrôleur.
Ben à priori pour moi elle était événementielle, quand on choisit un nom de contrôleur dans la première feuille, la ligne se coupe et colle dans la feuille dédiée à ce contrôleur.
Re,
Est-ce-que le choix du contrôleur est bien la toute dernière cellule renseignée sur chacune des lignes ....
Alors soit on classe la ligne directement sans indiquer de contrôleur, soit effectivement c'est la dernière cellule qui sera remplie sur la ligne de la première feuille
Bon après m'être un peu cassé la tête j'ai finalement trouvé la solution, il fallait que je mette un AND et pas OR dans les conditions du début de fichier.
Du coup problème résolu et le code pour ceux qui chercheraient encore ^^
Private Sub Worksheet_Change(ByVal Target As Range)
Dim LgnS As Range, TblC As Range, lnS%, lnC%, k%
If Target.Count > 1 Or Target.Row < 5 Or Target.Column <> 5 And Target.Column <> 3 Then Exit Sub
If Target.Value = "Dossier classé" Then
lnS = Target.Row - 4
Set LgnS = Me.ListObjects(1).DataBodyRange.Rows(lnS)
k = LgnS.Columns.Count
With Worksheets("Dossier classés").ListObjects(1)
If .Range.Cells(2, 1) <> "" Then
Set TblC = .DataBodyRange: lnC = TblC.Rows.Count + 1
Else
Set TblC = .Range.Rows(2): lnC = 1
End If
End With
TblC.Cells(lnC, 1).Resize(, k).Value = LgnS.Value
LgnS.EntireRow.Delete
ElseIf Target.Value = "BH" Then
lnS = Target.Row - 4
Set LgnS = Me.ListObjects(1).DataBodyRange.Rows(lnS)
k = LgnS.Columns.Count
With Worksheets("BH").ListObjects(1)
If .Range.Cells(2, 1) <> "" Then
Set TblC = .DataBodyRange: lnC = TblC.Rows.Count + 1
Else
Set TblC = .Range.Rows(2): lnC = 1
End If
End With
TblC.Cells(lnC, 1).Resize(, k).Value = LgnS.Value
LgnS.EntireRow.Delete
ElseIf Target.Value = "CG" Then
lnS = Target.Row - 4
Set LgnS = Me.ListObjects(1).DataBodyRange.Rows(lnS)
k = LgnS.Columns.Count
With Worksheets("CG").ListObjects(1)
If .Range.Cells(2, 1) <> "" Then
Set TblC = .DataBodyRange: lnC = TblC.Rows.Count + 1
Else
Set TblC = .Range.Rows(2): lnC = 1
End If
End With
TblC.Cells(lnC, 1).Resize(, k).Value = LgnS.Value
LgnS.EntireRow.Delete
ElseIf Target.Value = "EM" Then
lnS = Target.Row - 4
Set LgnS = Me.ListObjects(1).DataBodyRange.Rows(lnS)
k = LgnS.Columns.Count
With Worksheets("EM").ListObjects(1)
If .Range.Cells(2, 1) <> "" Then
Set TblC = .DataBodyRange: lnC = TblC.Rows.Count + 1
Else
Set TblC = .Range.Rows(2): lnC = 1
End If
End With
TblC.Cells(lnC, 1).Resize(, k).Value = LgnS.Value
LgnS.EntireRow.Delete
ElseIf Target.Value = "JA" Then
lnS = Target.Row - 4
Set LgnS = Me.ListObjects(1).DataBodyRange.Rows(lnS)
k = LgnS.Columns.Count
With Worksheets("JA").ListObjects(1)
If .Range.Cells(2, 1) <> "" Then
Set TblC = .DataBodyRange: lnC = TblC.Rows.Count + 1
Else
Set TblC = .Range.Rows(2): lnC = 1
End If
End With
TblC.Cells(lnC, 1).Resize(, k).Value = LgnS.Value
LgnS.EntireRow.Delete
ElseIf Target.Value = "MV" Then
lnS = Target.Row - 4
Set LgnS = Me.ListObjects(1).DataBodyRange.Rows(lnS)
k = LgnS.Columns.Count
With Worksheets("MV").ListObjects(1)
If .Range.Cells(2, 1) <> "" Then
Set TblC = .DataBodyRange: lnC = TblC.Rows.Count + 1
Else
Set TblC = .Range.Rows(2): lnC = 1
End If
End With
TblC.Cells(lnC, 1).Resize(, k).Value = LgnS.Value
LgnS.EntireRow.Delete
ElseIf Target.Value = "SH" Then
lnS = Target.Row - 4
Set LgnS = Me.ListObjects(1).DataBodyRange.Rows(lnS)
k = LgnS.Columns.Count
With Worksheets("SH").ListObjects(1)
If .Range.Cells(2, 1) <> "" Then
Set TblC = .DataBodyRange: lnC = TblC.Rows.Count + 1
Else
Set TblC = .Range.Rows(2): lnC = 1
End If
End With
TblC.Cells(lnC, 1).Resize(, k).Value = LgnS.Value
LgnS.EntireRow.Delete
ElseIf Target.Value = "YG" Then
lnS = Target.Row - 4
Set LgnS = Me.ListObjects(1).DataBodyRange.Rows(lnS)
k = LgnS.Columns.Count
With Worksheets("YG").ListObjects(1)
If .Range.Cells(2, 1) <> "" Then
Set TblC = .DataBodyRange: lnC = TblC.Rows.Count + 1
Else
Set TblC = .Range.Rows(2): lnC = 1
End If
End With
TblC.Cells(lnC, 1).Resize(, k).Value = LgnS.Value
LgnS.EntireRow.Delete
End If
End Sub
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Target.Column = 5 Then
Cells(Target.Row, 8) = Now
End If
End SubEncore merci pour le temps passé et bonne journée.
Je crois qu'il y a moyen d'optimiser le schmilblick mais voilà, ça fonctionne et ça me va pour le moment
Bonjour,
Content que tu aies pu résoudre ton problème ...