Macro évènementielle au changement de feuille si une plage a été modifiée

CISCO

XLDnaute Barbatruc
Bonsoir à tous

J'ai une macro dans Thisworkbook qui fonctionne, lancée automatiquement à chaque fois qu'on change de feuilles dans un fichier donné (Cf. . Merci à Robert, Job75, Pierrejean, Dranreb). Ca, c'est OK. Mais j'aimerai qu'elle ne soit lancée que si des modifications ont été faites sur la feuille précédente sur une plage particulière, Range ("B3:G18") par ex.

Autrement dit :
Si sur la feuille X, on effectue un ou des changements dans la plage Range ("B3:G18"), la macro est lancée automatiquement lorsqu'on choisit une autre feuille Y.
Si sur la feuille X, on ne fait pas de changement dans la plage Range ("B3:G18"), la macro n'est pas lancée lorsqu'on choisit une autre feuille du fichier.

D'avance merci.

@ plus
 

mapomme

XLDnaute Barbatruc
Supporter XLD
Bonsoir @CISCO,

Voir le code suivant à mettre dans le module de code de ThisWorkbook :
VB:
Option Explicit
Dim ModifPlage As Boolean

Private Sub Workbook_SheetActivate(ByVal Sh As Object)
   ModifPlage = False
End Sub

Private Sub Workbook_SheetDeactivate(ByVal Sh As Object)
   If ModifPlage Then
      'ici lancer la macro pour la feuille Sh
      MsgBox "Macro à lancer sur la feuille " & Sh.Name
   End If
End Sub

Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
   If Not Intersect(Sh.Range("B3:G18"), Target) Is Nothing Then ModifPlage = True
End Sub
 

CISCO

XLDnaute Barbatruc
Bonsoir à tous, bonsoir Mapomme

Merci, ça fonctionne nickel. J'étais parti sur quelque chose de beaucoup plus compliqué, du style copier toutes les valeurs de la plage concernée dans toutes les feuilles dans un tableau à 3 dimensions, comparer lors du changement de feuille avec les valeurs actuelles de la plage concernée... Et je n'y arrivais pas. Je connaissais Workbook_SheetChange mais je n'arrivais pas à organiser correctement l'imbrication de l'ensemble.

Si je comprends bien, les évènements s'enchainent comme suit
1) Workbook_SheetActivate
2) Workbook_SheetChange
3) Workbook_SheetDeactivate
4) Workbook_SheetActivate
5) Workbook_SheetChange
6) Workbook_SheetDeactivate
7) Workbook_SheetActivate
et ainsi de suite.

Encore une fois merci.

Au plaisir.
 
Dernière édition:

mapomme

XLDnaute Barbatruc
Supporter XLD
Re,


Quand on ouvre le classeur, il n'y a pas pas d'évènement Sheetactivate ni d'évènement SheetDeactivate au sein de ThisWorkbook.
Mais comme on ouvre le classeur, la variable ModifPlage au sein du ThisWorkbook est à sa valeur implicite d'initialisation qui est False.

Il faut faire attention quand on utilise ce type d'évènement (avec l'utilisation de variables de module) de bien vérifier les valeurs initiales de ces variables.

On ouvre le classeur -> la variable ModifPlage est à False
On modifie la feuille active du classeur -> Workbook_SheetChange (si c'est dans la plage alors ModifPlage est passé à True)
On quitte la feuille -> évènement Workbook_SheetDeactivate
si ModifPlage est True alors on exécute la macro
Pour la nouvelle feuille active -> évènement Workbook_SheetActivate -> on remet ModifPlage à False
puis le cas échéant Workbook_SheetChange
puis Workbook_SheetDeactivate
puis Workbook_SheetActivate
puis le cas échéant Workbook_SheetChange
puis Workbook_SheetDeactivate
puis Workbook_SheetActivate...

NB : attention aux effets de bord avec la macro lancée quand la plage est modifiée. Il vaut peut-être mieux bloquer la détection des évènements en début de macro et la rétablir à la fin de la macro.
 

CISCO

XLDnaute Barbatruc
Bonsoir

Merci pour tes explications. C'est à peu près ce que j'avais compris de ta proposition (Mais il faut se méfier des "à peu près" en informatique).

Quelques questions :
1) Pourrais-tu expliquer davantage ton PS ? Qu'est-ce qu'un effet de bord ici ?
2) J'ai l'impression que ta proposition fonctionne avec
Code:
If Not Intersect(Sh.Range("B3:G18"), Target) Is Nothing Then ModifPlage = True
et pas avec
Code:
If Not Intersect(Sh.Range(Cells(3, 2), Cells(18, derncol)), Target) Is Nothing Then ModifPlage = True
avec derncol= 7 donné quelques lignes au-dessus. Ai-je fait une erreur de syntaxe ?

@ plus
 
Dernière édition:

mapomme

XLDnaute Barbatruc
Supporter XLD
Re,

Quand on utilise certains évènements et surtout WorksheetChange, on peut se retrouver dans une boucle mortelle. Ma zone a changée, je lance ma macro. Mais cette macro modifie les valeurs de la zone donc l'évènement Workbook_SheetChange est à nouveau lancé et ainsi de suite...
De même si la macro active une autre feuille que la feuille nouvellement activée, on risque de déclencher en cascade d'autres évènements du type SheetActivate et/ou SheetDeactivate.
 

CISCO

XLDnaute Barbatruc
Bonjour à tous

Merci Mapomme pour ces explications. Effectivement, il faut se méfier de ces effets "boule de neige", soit par modification automatique de la plage, soit par création automatique d'autres évènements relançant certaines des macros, qui, à leur tour...

@ plus

P.S : Est-ce que tu as un lien vers la macro qui colorie la police des codes utilisés ? C'est tellement plus lisible ainsi.
 

CISCO

XLDnaute Barbatruc
Rebonjour

Pour ce qui est de
Code:
If Not Intersect(Sh.Range(Cells(3, 2), Cells(18, derncol)), Target) Is Nothing Then ModifPlage = True
en fait, j'avais un message d'erreur si j'avais fait une modification dans la plage B3:G18 sans la valider avec la touche entrée, et que j'avais tout de suite sélectionné une autre feuille.

@ plus
 

Discussions similaires

Réponses
7
Affichages
312

Membres actuellement en ligne

Statistiques des forums

Discussions
312 084
Messages
2 085 194
Membres
102 810
dernier inscrit
mohammedaminelahbali