J'ai une macro dans Thisworkbook qui fonctionne, lancée automatiquement à chaque fois qu'on change de feuilles dans un fichier donné (Cf. là. 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.
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
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.
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.
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 ?
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.
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.
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.