Traitement (Evènement) d'une plage discontinue

Re-bonjour,

je m'excuse d'avance si le titre de mon sujet n'est pas très clair,

mais je ne savais comment résumer mon problème en une ligne...

Voici le problème :

Je souhaite repérer les lignes modifiées d'un tableau.

J'ai donc utilisé la macro évènementielle "Worksheet_Change",

qui renseigne "1" dans les colonnes de "suivi des modifications du tableau" des lignes modifiées.

Cela fonctionne si la zone modifiée est une plage continue,

mais cela ne fonctionne plus si elle ne l'est pas.

(Par exemple, l'utilisateur sélectionne différentes zone du tableau puis vide leurs contenus)

L'instruction ".Resize" de la plage ne semble pas aimer...

Voici le code utilisé :

Private Sub Worksheet_Change(ByVal Target As Range)

Application.ScreenUpdating = False

Dim Plage As Range
Set Plage = Range("A10:I100")

    If Not Intersect(Target, Plage) Is Nothing Then
        For Each c In Target.Resize(, 1)
            Range(Cells(c.Row, 10), Cells(c.Row, 12)).Value = 1
        Next c
    End If
End Sub

Si vous vous demandez pourquoi je fais un "Resize" de la target, le but était d'optimiser le temps de traitement de la macro,

pour ne traiter qu'une seule fois chaque ligne...

Comme un exemple vaut mieux que de longues explications, je joins le fichier à ce post.

Sauriez-vous comment faire, me donner une piste ?

je pense que je m'y suis mal pris avec le "Resize", mais je ne vois pas bien comment faire autrement...

35piratman.xlsm (20.74 Ko)

Bonjour

Enlèves le Resize

Private Sub Worksheet_Change(ByVal Target As Range)

Application.ScreenUpdating = False

Dim Plage As Range
Set Plage = Range("A10:I100")

    If Not Intersect(Target, Plage) Is Nothing Then
[barrer]'For Each c In Target.Resize(, 1)[/barrer]
        For Each c In Target
            Range(Cells(c.Row, 10), Cells(c.Row, 12)).Value = 1
        Next c
    End If

End Sub

Bonjour Banzai64,

effectivement cela marche sans le Resize,

mais je souhaiterai éviter que la boucle FOR traite toutes les cellules d'une même ligne, puisque cela est complètement inutile dans mon cas.

Par exemple, si on sélectionne tout le tableau, le temps d’exécution de la macro avec le Resize est de 0,05s,

sans le Resize, le temps est de 0,35s.

L'exemple dans mon fichier ne fait que quelques lignes, donc ces temps peuvent paraître insignifiant,

mais dans la pratique mon tableau pourra faire quelques milliers de ligne.

Je n'ai pas trouvé de méthode pour ne traiter qu'une seule fois chaque ligne de la sélection.

une idée

J'ai trouvé la solution à mon problème,

voici le code, si ça peut servir à quelqu'un :

Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)

'--- Déclaration des variables
Dim tableau As Range
Dim Plage_a_traiter As Range
Dim Index_cellule As Variant
Dim Col_traitement As Integer

'--- Initialisation des variables
Col_traitement = 10
Set tableau = Range("A10:I100")
Set Plage_a_traiter = Nothing

'--- Désactive l'actualisation de l'écran
Application.ScreenUpdating = False
'--- Désactive les évènements
Application.EnableEvents = False

'--- Filtre l'évènement sur le tableau définit
If Not Intersect(Target, tableau) Is Nothing Then
'--- Redéfinit les lignes à traiter
    For Each Index_cellule In Target.Rows
        If Plage_a_traiter Is Nothing Then
            Set Plage_a_traiter = Cells(Index_cellule.Row, Col_traitement)
        Else
            Set Plage_a_traiter = Union(Plage_a_traiter, Cells(Index_cellule.Row, Col_traitement))
        End If
    Next
'--- Traitement de chaque ligne
    For Each Index_cellule In Plage_a_traiter
        Index_cellule.Value = "Modifié"
    Next
End If

'--- Active les évènements
Application.EnableEvents = True
'--- Active l'actualisation de l'écran
Application.ScreenUpdating = True

End Sub
Rechercher des sujets similaires à "traitement evenement plage discontinue"