OVH Cloud OVH Cloud

Comment gérer Worksheet_Change

6 réponses
Avatar
C'est moi que Vla
Bonjour à tous,

Je suis confronté à une procédure qui boucle sans arrêt et j'aimerais savoir
s'il existe une façon de faire pour eviter ça.

Je teste avec Worksheet_Change si la cellule qui vient de changer de valeur
dans ma feuille fait partie d'une zone particulaire.
Si c'est le cas, je modifie le contenu de certaines autres cellules
réparties ça et là sur cette même feuille ce qui engendre l'exécution de
Worksheet_Change qui reteste si c'est une cellule qui fait partie de la zone
particuliaire ...etc.

Existe-il une façon plus propre pour que, quand je traite déjà un évèvement
Worksheet_Change, rien ne se passe jusqu'à ce que la procédure soit close ?

@+
Paul

6 réponses

Avatar
Yvan
Salut!

Pb classique si il en est!

Essaie çà:

Dim blnOK As Boolean

Private Sub Worksheet_Change(ByVal Target As Range)
If blnOK Then Exit Sub
blnOK = True
.......................................

Ton code
.........................................
blnOK = False
End Sub

Explication: Lorsque tu entres la première fois dans la procédure, blnOK est
false est donc tu passes le test "if blnOK then ". Juste après tu interdis un
nouvel accès jusqu'à avoir fini le travail. Tu débloques par blnOK = false à la
fin.

Attention à bien déclarer ta variable blnOK à l'extérieur de la procédure
worksheet_change (et donc en haut de la page de code). Sinon sa portée n'est pas
suffisante.

@+

Yvan


"C'est moi que Vla" a écrit dans le message de news:

Bonjour à tous,

Je suis confronté à une procédure qui boucle sans arrêt et j'aimerais savoir
s'il existe une façon de faire pour eviter ça.

Je teste avec Worksheet_Change si la cellule qui vient de changer de valeur
dans ma feuille fait partie d'une zone particulaire.
Si c'est le cas, je modifie le contenu de certaines autres cellules réparties
ça et là sur cette même feuille ce qui engendre l'exécution de
Worksheet_Change qui reteste si c'est une cellule qui fait partie de la zone
particuliaire ...etc.

Existe-il une façon plus propre pour que, quand je traite déjà un évèvement
Worksheet_Change, rien ne se passe jusqu'à ce que la procédure soit close ?

@+
Paul



Avatar
jb
Bonjour,

Il faut désactiver les événements pendant le traitement puis les
réactiver

Application.EnableEvents = False ' désactive les
événements
If Not Intersect([A1:B10], Target) Is Nothing Then ' champ A1:B10
seulement
If IsNumeric(Target.Value) Then
If Target.Value > 50 Then
beep
'--- clignote
mémoFond = Target.Interior.ColorIndex
For c = 1 To 100
Target.Interior.ColorIndex = 3
Target.Interior.ColorIndex = mémoFond
Next
'---
End If
End If
End If
Application.EnableEvents = True
End Sub

Si on veut tester seulement les saisies de cellules, on peut travailler
à l'ancienne avec OnEntry qui ne provoque d'évenements endogènes:

Sub auto_open()
ActiveWorkbook.Worksheets("Feuil2").OnEntry = "clignote"
End Sub

Sub clignote()
If Not Intersect([A1:B10], ActiveCell) Is Nothing Then ' champ A1: B10
seulement
If IsNumeric(ActiveCell) Then
If ActiveCell > 50 Then
'--- clignote
mémoFond = ActiveCell.Interior.ColorIndex
For c = 1 To 100
ActiveCell.Interior.ColorIndex = 3
ActiveCell.Interior.ColorIndex = mémoFond
Next
'---
End If
End If
End If
End Sub

Cordialement JB
Avatar
C'est moi que Vla
Merci Yvan, c'est simple et ça fonctionne effectivement :-)

@+
Paul

"Yvan" <yvan.echanges(enlever ceci)@free.fr> a écrit dans le message de
news: efSof$
Salut!

Pb classique si il en est!

Essaie çà:

Dim blnOK As Boolean

Private Sub Worksheet_Change(ByVal Target As Range)
If blnOK Then Exit Sub
blnOK = True
.......................................

Ton code
.........................................
blnOK = False
End Sub

Explication: Lorsque tu entres la première fois dans la procédure, blnOK
est false est donc tu passes le test "if blnOK then ". Juste après tu
interdis un nouvel accès jusqu'à avoir fini le travail. Tu débloques par
blnOK = false à la fin.

Attention à bien déclarer ta variable blnOK à l'extérieur de la procédure
worksheet_change (et donc en haut de la page de code). Sinon sa portée
n'est pas suffisante.

@+

Yvan


"C'est moi que Vla" a écrit dans le message de
news:
Bonjour à tous,

Je suis confronté à une procédure qui boucle sans arrêt et j'aimerais
savoir s'il existe une façon de faire pour eviter ça.

Je teste avec Worksheet_Change si la cellule qui vient de changer de
valeur dans ma feuille fait partie d'une zone particulaire.
Si c'est le cas, je modifie le contenu de certaines autres cellules
réparties ça et là sur cette même feuille ce qui engendre l'exécution de
Worksheet_Change qui reteste si c'est une cellule qui fait partie de la
zone particuliaire ...etc.

Existe-il une façon plus propre pour que, quand je traite déjà un
évèvement Worksheet_Change, rien ne se passe jusqu'à ce que la procédure
soit close ?

@+
Paul







Avatar
C'est moi que Vla
Salut Jb,

J'ai testé la proposition d'Yvan qui est simple à mettre en oeuvre et qui
fonctionne. Mais c'est peut être moins propre que ce que tu me proposes.

Je vais essayer tes 2 autres solutions.
La première, je pense la comprendre....tu stop les évènements donc
effectivement j'exécute mon code sans problème, mais je risque d'être géné
par le fait que tous les évènements seront bloqués et pas seulement
l'évènement changement de valeur dans une série de cellule.

Par contre ta 2em proposition, je ne la comprends pas même si je pense que
ça doit correspondre à ce que je recherche.

Pourais tu me mettre quelques commentaires et me dire à quoi sert la
procédure
Sub auto_open()

Merci de ton aide
@+
Paul



"jb" a écrit dans le message de news:

Bonjour,

Il faut désactiver les événements pendant le traitement puis les
réactiver

Application.EnableEvents = False ' désactive les
événements
If Not Intersect([A1:B10], Target) Is Nothing Then ' champ A1:B10
seulement
If IsNumeric(Target.Value) Then
If Target.Value > 50 Then
beep
'--- clignote
mémoFond = Target.Interior.ColorIndex
For c = 1 To 100
Target.Interior.ColorIndex = 3
Target.Interior.ColorIndex = mémoFond
Next
'---
End If
End If
End If
Application.EnableEvents = True
End Sub

Si on veut tester seulement les saisies de cellules, on peut travailler
à l'ancienne avec OnEntry qui ne provoque d'évenements endogènes:

Sub auto_open()
ActiveWorkbook.Worksheets("Feuil2").OnEntry = "clignote"
End Sub

Sub clignote()
If Not Intersect([A1:B10], ActiveCell) Is Nothing Then ' champ A1: B10
seulement
If IsNumeric(ActiveCell) Then
If ActiveCell > 50 Then
'--- clignote
mémoFond = ActiveCell.Interior.ColorIndex
For c = 1 To 100
ActiveCell.Interior.ColorIndex = 3
ActiveCell.Interior.ColorIndex = mémoFond
Next
'---
End If
End If
End If
End Sub

Cordialement JB
Avatar
jb
-Auto_open est exécuté automatiquement à l'ouverture du classeur
(comme WorkBook_Open)
-ActiveWorkbook.Worksheets("Feuil2").OnEntry = "clignote" i
Spécifie que la proc clignote() sera exécutée à chaque saisie dans
Feuil2.
Les changements de couleur, effacement de cellules ne déclencheront
pas cette procédure.

Prendre le 2e onglet
http://cjoint.com/?lmltaXwkWZ

Cordialement JB
Avatar
jb
-Auto_Open() est une procédure qui est exécutée automatiquement à
l'ouverture du classeur (équivalent de WorkBook_Open).

-ActiveWorkbook.Worksheets("Feuil2").OnEntry = "clignote"
définit la proc (Clignote)qui sera excécutée à chaque saisie dans
Feuil2
-La procédure n'est pas déclenchée par les effacements de cellule,
les changements de couleur,... mais seulement par la saisie de valeurs
dans les cellules.

Prendre onglet Feuil2
http://cjoint.com/?lmliIgEDQ6

Cordialement JB