Anomalie dans l'évènement BeforeClose
En écrivant une procédure de sortie dans une application je me suis rendu compte que l'évènement ne se déclenche pas dans un cas particulier ce qui entraîne une erreur à la réouverture de mon application.
Voici un petit bout de code à placer dans le module ThisWorkbook si vous souhaitez constater l'anomalie :
VB:
Private Sub Workbook_BeforeClose(Cancel As Boolean)
MsgBox "Event BeforeClose"
End Sub
Il faut avoir ce seul classeur ouvert au préalable.
Modifiez la grille sans sauvegarder et fermez le classeur.
Le message 'Event BeforeClose' s'affiche et ensuite la question "Voulez-vous enregistrez ...", choisissez 'Cancel' pour annuler.
Fermez à nouveau le classeur et là le message 'Event BeforeClose' ne s'affiche plus.
Je travaille sur la version XLS2016 et je ne sais pas si cette anomalie a lieu sur toutes les versions. J'ai aussi testé sur la version XLS2003 et il n'y avait pas cette anomalie.
Je pense que c'est une sécurité qui a été ajoutée afin de ne pas pouvoir écrire un code qui empêche la fermeture d'Excel.
Voici comment on pouvait le faire sous Excel2003 :
VB:
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Cancel = True
End Sub
Après tests, je n'ai pas réussi à trouver de solution en utilisant cet évènement pour contourner l'anomalie et m'assurer que ma procédure de sortie soit toujours exécutée. Après tests l'évènement 'BeforeSave' même s'il ne réagit pas sur le même évènement est une bonne alternative car ce qui compte c'est l'état enregistré au moment de la sortie de l'application.
De plus il existe aussi l'évènement 'AfterSave' si on veut rétablir le contexte en cas de sauvegarde sans sortir de l'application. Noté que toute modification effectuée par AfterSave n'est pas sauvé au moment de la fermeture de l'appli.
Dites-moi si vous aviez constaté cette spécificité et sur quelle version vous travaillez.
(Pas de Bonjour même à Noël ?)
Non, je ne constate pas ça et j'ai aussi Excel 2016.
Le message est affiché chaque fois que je demande la fermeture.
Et puisque vous parlez d'un autre évènement, il y a aussi Workbook_Deactivate et Workbook_WindowDeactivate.
Il pourrait permettre de détecter une fermeture effective après sauvegarde consentie lors d'une séquence de fermeture engagée. Combinaisons à essayer :
VB:
Option Explicit
Private FermetureDemandée As Boolean
Private Sub Workbook_BeforeClose(Cancel As Boolean)
FermetureDemandée = True
End Sub
Private Sub Workbook_Deactivate()
If FermetureDemandée And Not Me.Saved Then Me.Save
End Sub
Private Sub Workbook_Activate()
FermetureDemandée = False
End Sub
Il faut avoir ce seul classeur ouvert au préalable.
Modifiez la grille sans sauvegarder et fermez le classeur.
Le message 'Event BeforeClose' s'affiche et ensuite la question "Voulez-vous enregistrez ...", choisissez 'Cancel' pour annuler.
Fermez à nouveau le classeur et là le message 'Event BeforeClose' ne s'affiche plus.
(Pas de Bonjour même à Noël ?)
Non, je ne constate pas ça et j'ai aussi Excel 2016.
Le message est affiché chaque fois que je demande la fermeture.
Et puisque vous parlez d'un autre évènement, il y a aussi Workbook_Deactivate et Workbook_WindowDeactivate.
Il pourrait permettre de détecter une fermeture effective après sauvegarde consentie lors d'une séquence de fermeture engagée. Combinaisons à essayer :
VB:
Option Explicit
Private FermetureDemandée As Boolean
Private Sub Workbook_BeforeClose(Cancel As Boolean)
FermetureDemandée = True
End Sub
Private Sub Workbook_Deactivate()
If FermetureDemandée And Not Me.Saved Then Me.Save
End Sub
Private Sub Workbook_Activate()
FermetureDemandée = False
End Sub
Bonsoir et bien-sûr de bonnes fêtes de Noël Dranreb !
Petite vérification, en faisant le test vous aviez bien ce seul classeur ouvert ?
Je vais tester cet événement aussi mais je suis surpris qu'on est pas le même résultat ... Et il faut aussi utiliser la croix (en haut à droite), comme m'a fait remarquer TooFatBoy.
En faite comme je l'expliquai je pense que c'est une sécurité qui n'ai active que si il y a un seul classeur ouvert pour qu'on puisse toujours fermer Excel...
re
Bonsoir
juste en passant
je n'ai pas bien saisi le problème mais
aurais tu essayé en sub classant
pour bénificier de l'object workbook implémenté
dans l'event original l'object est implicite ce qui peut peut être être le problème en cas de plusieur classeur ouvert )
ci dessous les deux events de substitution
VB:
Public WithEvents app As Application
'event de substitution
Private Sub app_WorkbookBeforeClose(ByVal Wb As Workbook, Cancel As Boolean)
If Wb.Name = ThisWorkbook.Name Then
'ton code ici
End If
End Sub
Private Sub app_WorkbookBeforeSave(ByVal Wb As Workbook, ByVal SaveAsUI As Boolean, Cancel As Boolean)
If Wb.Name = ThisWorkbook.Name Then
'ton code ici
End If
End Sub
'event original
Private Sub Workbook_BeforeClose(Cancel As Boolean)
End Sub
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
End Sub
re
Bonsoir
juste en passant
je n'ai pas bien saisi le problème mais
aurais tu essayé en sub classant
pour bénificier de l'object workbook implémenté
dans l'event original l'object est implicite ce qui peut peut être être le problème en cas de plusieur classeur ouvert )
ci dessous les deux events de substitution
VB:
Public WithEvents app As Application
'event de substitution
Private Sub app_WorkbookBeforeClose(ByVal Wb As Workbook, Cancel As Boolean)
If Wb.Name = ThisWorkbook.Name Then
'ton code ici
End If
End Sub
Private Sub app_WorkbookBeforeSave(ByVal Wb As Workbook, ByVal SaveAsUI As Boolean, Cancel As Boolean)
If Wb.Name = ThisWorkbook.Name Then
'ton code ici
End If
End Sub
'event original
Private Sub Workbook_BeforeClose(Cancel As Boolean)
End Sub
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
End Sub
J'ai juste simplifié pour montrer l'anomalie de comportement. Dans mon cas j'ai écrit une interface et je dois changer le contexte avant de quitter l'application pour qu'il n'y ait pas d'anomalie à sa réouverture.
Du coup j'expliquai qu'il fallait mieux éviter d'utiliser cet événement pour faire cela et préférer BeforeSave ou peut-être Workbook_Deactivate comme Dranreb me le suggère : #2