XL 2016 Interdire ou pas la fermeture d'un classeur

vgendron

XLDnaute Barbatruc
Bonjour le forum
me voici avec une question qui vient de se poser à moi...

j'ai deux classeurs xlsm ouverts en meme temps
le premier: GTA.xlsm qui ouvre le second: FVPR.xlsm
le GTA étant l'application principale qui travaille sur le FVPR

il arrive parfois que les gens ferment le FVPR par erreur===> le GTA se trouve ainsi perdu et plante
j'ai donc ajouté dans le "thisworkbook" du FVPR
VB:
Private Sub Workbook_BeforeClose(cancel as boolean)
for each wb in application.workbooks
   if wb.name like "GTA*" then
        msgbox ("Vous ne pouvez pas fermer le FVPR, car il est utilisé par le GTA")
        cancel =true
   end if
next wb
end sub

ca marche très bien: MAIS ca fonctionne tellement bien que.. lorsque le GTA veut fermer le fichier.. et bah.. il ne peut pas non plus...

comment puis je faire pour interdire la fermeture du FVPR SAUF au GTA
y aurait il une option quelque part qui dirait au FVPR d'ou vient l'ordre de fermeture??

merci pour vos idées d'avant week end 🙃
 

dysorthographie

XLDnaute Accro
Bonjour,
il une option quelque part qui dirait au FVPR d'ou vient l'ordre de fermeture??
il sufi que le fichier FVPR dispose d'une variable public CloseOk et que le fichier GTA informe le FVPR qu'il va le clore!
VB:
Public CloseOk As Boolean
Private Sub Workbook_BeforeClose(cancel As Boolean)
   If Me.Name Like "GTA*" And Not CloseOk Then MsgBox ("Vous ne pouvez pas fermer le FVPR, car il est utilisé par le GTA")
        cancel = Not CloseOk
End Sub
pour moi pas besoin de tester le nom du fichier vue que le traitement ce fait dans Workbook_BeforeClose du dit fichier!
VB:
Public CloseOk As Boolean
Private Sub Workbook_BeforeClose(cancel As Boolean)
   If Not CloseOk Then MsgBox ("Vous ne pouvez pas fermer le FVPR, car il est utilisé par le GTA")
        cancel = Not CloseOk
End Sub
et pour fermer le fichier!
Code:
Sub GTA_FVPR()
Set WbFVPRC= Workbooks.open("C:\GTA-2021-06-12.xlsm")
'Traitement GTA
WbFVPRC.CloseOk True
WbFVPR.Close
End Sub
 
Dernière édition:

patricktoulon

XLDnaute Barbatruc
Bonjour
je sais pas j'ai pas testé mais si je suis la logique quand on ferme le classeur secondaire par lui même il est sensé être l'actif et surtout!!!! que cet event (BeforeClose)est sensé être dans le classeur secondaire

parti de là
VB:
Private Sub Workbook_BeforeClose(cancel as boolean)
for each wb in application.workbooks
   if wb.name like "GTA*" and activeworkbook.name=thisworkbook.name then
        msgbox ("Vous ne pouvez pas fermer le FVPR, car il est utilisé par le GTA")
        cancel =true
   end if
next wb
end sub
je dis ça juste en raisonnant logiquement donc (A tester)
pas besoins de variable et tout le tointoin , c'est clair net et logique
 

vgendron

XLDnaute Barbatruc
Hello
je vous fait un petit retour sur vos propositions
@BrunoM45 : ha bah oui.. tout simplement
en gardant mon code dans le thisworkbook du FVPR et en ajoutant un enablevents=false dans le GTA avant le FVPR.Close

@dysorthographie : le coup de la variable CloseOK: pas mal non plus
il a juste fallu que je corrige ton code proposé:
dans le fvpr:
VB:
Public CloseOk As Boolean
Private Sub Workbook_BeforeClose(cancel As Boolean)
   If Not CloseOk Then
    MsgBox ("Vous ne pouvez pas fermer le FVPR, car il est utilisé par le GTA")
    cancel = Not CloseOk
End If
End Sub

et dans le GTA:
VB:
Sub testfermer()
Set wb = Workbooks("FVPRTest.xlsm")
wb.CloseOK = True
Application.EnableEvents = False
wb.Close
Application.EnableEvents = True
End Sub
et du coup je viens d'apprendre qu'un classeur (GTA) pouvait modifier une variable globale (CloseOK d'un autre classeur (WbFVPR) avec la syntaxe:
WbFVPR.CloseOK = true

@patricktoulon
la logique me semblait pas mal non plus, mais à l'utilisation: la condition qui empeche de fermer est toujours vrai
GTA et FVPR sont ouverts
fermeture du FVPR à partir du FVPR:
la boucle va voir que le GTA est ouvert et que le classeur actif est bien le FVPR ===> fermeture impossible

fermeture du FPVR PAR le GTA
wbFVPR.Close donne la main au FVPR qui devient l'actif ==> on retombe dans le cas précédent

la boucle est la pour le cas ou SEUL le FVPR est ouvert

en tout cas, merci à tous et bon week end et go Djoko
 

patricktoulon

XLDnaute Barbatruc
il y a deux events qui ne sont pas implémentés mais qui pourtant sont bien utiles

je vous suggère d'aller faire une recherche sur les procédures :

sub Auto_open et sub Auto_Close​

dans un module standard

elles ont un comportement différent de workbook_open et before_close

et cette différence c'est justement le but de la manœuvre ici
 

vgendron

XLDnaute Barbatruc
Hello @patricktoulon Merci!

y'en a beaucoup des macros comme ca? :D
De ce que j'ai pu lire, ce sont des reliquats des vieilles versions d'excel ! mais qui peuvent etre utiles dans certains cas... je garde ca de côté.. meme si tous les posts lus disent qu'il vaut mieux les abandonner au profil du before close...
en fait.. le before close, c'est super.. mais il manque un élément essentiel: Kikadit de fermer la lumiere !! :D:D

Après un test rapide, effectivement, l'auto_close n'est lancé QUE si l'ordre de fermeture vient du FVPR lui meme
l'ennui, c'est que l'auto_close ne peut pas etre annulé (ou alors, j'ai pas encore tout vu) si le GTA est encore ouvert.

comme je ne suis meme pas sur d'avoir dit le comportement attendu: je remets ici les cas pouvant se présenter
1-point de départ: GTA et FVPR sont ouverts
1-1 fermeture du FVPR à partir du FVPR (auto_close serait ici lancé) ==>teste si le GTA est ouvert: fermeture refusée
1-2 fermeture du FVPR à partir du GTA (auto_close n'est pas lancé) ==> fermeture autorisée

2- point de départ: FVPR ouvert tout seul
2-1 fermeture du FPVR à partir du FVPR ==> teste si le GTA est fermé: fermeture autorisée
 

eriiic

XLDnaute Barbatruc
Bonjour à tous,

autre option, l'évènement d'application.
En plus d'être court et simple, il n'y a pas d'ajout de code dans le classeur dépendant qui peut rester un xlsx.
Dans ThisWorkbook :
VB:
Option Explicit

Private WithEvents App As Application
Private Sub Workbook_Open()
    'récupérer l'application Excel à l'ouverture
    Set App = Application
End Sub

Private Sub App_WorkbookBeforeClose(ByVal Wb As Workbook, Cancel As Boolean)
    If Wb.Name = "Classeur1.xlsx" Then
        Cancel = True
        MsgBox "Annulé, en cours d'utilisation par " & ThisWorkbook.Name
    End If
End Sub
eric

Edit : fichier oublié
 

Pièces jointes

  • Application_Events WorkbookBeforeClose.xlsm
    18.1 KB · Affichages: 10
Dernière édition:

vgendron

XLDnaute Barbatruc
Je trouvais ça intéressant, une erreur sans doute.
Pas suffisamment pour le demandeur apparemment.
Bonjour @eriiic
on a un délai max pour répondre aux propositions?

Donc oui, c'est interressant, d'autant que je ne connaissais pas les event d'application.
mais (sauf erreur d'utilisation), ca ne donne pas ce que je souhaite.
comme tu indiques que le fichier dépendant (mon FVPR) peut rester sans macro, j'ai collé tout ton code dans le thisworkbook de mon GTA et j'ai remplace "classeur1.xlsx" par "FVPR.xlsx"
effectivement, lorsque les deux GTA et FVPR sont ouverts, une fermeture du FVPR A PARTIR du FVPR (par un clic sur la croix par exemple) n'est pas autorisée==>c'est bien ce que je veux
mais une fermeture du FVPR A PARTIR du GTA (avec un workbooks("FVPR.xlsm").close n'est pas autorisée non plus==> je veux que le GTA puisse fermer le FVPR.

Cela dit, avec la proposition de @BrunoM45 j'ai ce qu'il me faut
encore merci à tous
 

eriiic

XLDnaute Barbatruc
Bonjour vgendron,

disons que j'ai été surpris de te voir répondre sur d'autres topics sans lire le tien...
Désolé de mon impatience.

Je dirais que ça devrait pouvoir se faire en mettant une variable booléenne à vrai (dans un module standard) avant de fermer ton fichier par code, et d'ajouter de test dans le If
Mais pas le temps de tester en détail, je dois m'absenter.
eric
 

eriiic

XLDnaute Barbatruc
Bonjour,

ce qui donne, tout dans le classeur principal :
module ThisworkBook :
VB:
Option Explicit

Private WithEvents App As Application

Private Sub Workbook_Open()
    'récupérer l'application Excel à l'ouverture
    Set App = Application
End Sub

Private Sub App_WorkbookBeforeClose(ByVal Wb As Workbook, Cancel As Boolean)
    If Not closeOk Then
        If Wb.Name = "Classeur1.xlsx" Then
            Cancel = True
            MsgBox "Annulé, en cours d'utilisation par " & ThisWorkbook.Name
        End If
    End If
End Sub

Module Standard :
Code:
Option Explicit

Public closeOk As Boolean

Sub test()
    closeOk = True
    Workbooks("Classeur1.xlsx").Close
    closeOk = False
End Sub
Je pense n'avoir rien oublié
eric
 

vgendron

XLDnaute Barbatruc
Bonsoir @eriiic

tu es bien gentil.. mais niveau politesse et respect, je ne pense pas etre en reste.
Si je relis le fil complet, il me semble avoir remercié chacun des intervenants et avoir fait un retour à chacun.
il me semble également avoir clairement indiqué que la solution de Brunom45 répondait à mon besoin..
en ce qui concerne TA proposition puisque tu sembles vouloir une réponse personalisée
ta solution du post 8 ne fonctionne pas telle quelle comme indiqué
et ta réponse du post 12.. et bien.... vu que mon pb est résolu, je n'ai pas poursuivi avec ta solution.. qui..à première vu.. reprend celle de dysorthographie qui déjà. au post #3 avait suggéré cette variable closeOK.
Sur ce bonne soirée
et pour finir. si ce n'est toujours pas assez clair.. mon problème est résolu !
merci
 

Discussions similaires

Statistiques des forums

Discussions
311 730
Messages
2 081 991
Membres
101 856
dernier inscrit
Marina40