[Résolu][Calc] Erreur si fermeture classeur par bouton

Discussions et questions sur tout ce qui concerne la programmation tous langages et tous modules confondus.

Modérateur : Vilains modOOs

Règles du forum
:alerte: Balisage obligatoire dans cette section !
Aidez-nous à vous aider au mieux en balisant correctement votre question : reportez-vous sur les règles de cette section avant de poster !
Avatar de l’utilisateur
marhra
NOOuvel adepte
NOOuvel adepte
Messages : 17
Inscription : 06 janv. 2010 17:53
Localisation : Ardennes

[Résolu][Calc] Erreur si fermeture classeur par bouton

Message par marhra »

Bonjour,
Je fais appel à vos compétences pour m'aider à déterminer la source de ce message d'erreur
Erreur d'exécution BASIC.
Une exception s'est produite :
Type: com.sun.star.lang.DisposedException
Message: .
qui apparaît à la fermeture (par macro) du fichier, mais pas toujours.
Évidemment, le "message: ." ne m'aide pas beaucoup pour identifier la source du problème.
Après de multiples essais et recherches, il semblerait que ce soit lié à l'utilisation des boutons de changement de mot de passe de la feuille ''Tables'' et/ou peu-être à une boucle qui continue de tourner...
Ou pas... :fou: C'est la que je bloque, aux limites de mes connaissances balbutiantes.

Il n'y a pas de conséquences visibles pour moi sur le fonctionnement du tableau, qui fonctionne normalement à la réouverture. Aussi ma préoccupation est-elle, outre le ''mais pourquoi ?'', d'ordre esthétique. Le fichier est à usage pro et il faut reconnaître que ça ne fait pas très pro, justement, d'avoir un message d'erreur à la fermeture d'un fichier de travail...

Je joint un fichier anonymisé, qui a encore toutes les protections anti beu-beu qui ruine toute la base à grands coups de clics hasardeux.
Aussi faut-il aller à la feuille "Tables" et cliquer sur OFF dans le cadre Mode Concepteur, histoire de tout débloquer. Tous les mots de passe sont "" (vide) et le mot de passe du module Secure est "0000".

Ceux qui iront jeter un œil le constateront : bon nombre des macros sont largement inspirées de ce forum, voire carrément pompées en intégralité. C'est en construisant lentement au fil du temps ce fichier (plusieurs années) que je finis par commencer à lever l'épais brouillard qui couvrait pour moi le domaine de la programmation...

En vous remerciant d'avance.
Vous ne pouvez pas consulter les pièces jointes insérées à ce message.
Dernière modification par marhra le 22 août 2019 10:42, modifié 2 fois.
LibreOffice 6.0.3.2 sur Ubuntu 16.04 LTS ou Windows 10 Pro au travail
LibreOffice 6.3.0 sur MacOS Mojave à la maison
Avatar de l’utilisateur
OOotremer971
ManitOOu
ManitOOu
Messages : 2744
Inscription : 16 avr. 2010 13:31

Re: [Calc] Erreur BASIC à la fermeture DisposedException

Message par OOotremer971 »

Bonjour,

En attendant de trouver l'origine aléatoire du dysfonctionnement, est-ce que tu peux tester dans ta Sub FermerBase :

Code : Tout sélectionner

on Error Resume Next
Thiscomponent.close(True)
On Error GoTo 0
au lieu de simplement :

Code : Tout sélectionner

Thiscomponent.close(True)
A+
 Ajout : Pour info, dans la bible, on peut lire ceci :
La méthode close signale à d’autres programmes utilisateurs que ce document va
être fermé. Un de ces programmes peut manifester son mécontentement en déclen-
chant une erreur,
que nous ignorerons. L’argument True dans la méthode close
signale à ces autres programmes que, s’ils souhaitent continuer quand même, ils doi-
vent en assumer la responsabilité (en ce qui concerne la libération des ressources).
Vous pourrez lire dans le Developer’s Guide, chapitre Office Development>Handling
Documents>Closing Documents, une discussion très technique sur ce sujet.
 
En principe, toujours à jour des dernières versions dites stables
AOO
LibreOffice
Debian 10 et 11
Avatar de l’utilisateur
marhra
NOOuvel adepte
NOOuvel adepte
Messages : 17
Inscription : 06 janv. 2010 17:53
Localisation : Ardennes

Re: [Calc] Erreur BASIC à la fermeture DisposedException

Message par marhra »

Bonjour,

Le pansement fonctionne, semble-t-il, donc résultat satisfaisant. Quoique... un peu frustrant, car je ne trouve pas le pourquoi !
Si j'ai bien compris ta citation de la bible, c'est bien la piste d'une routine encore en cours et "pas contente" de la fermeture, qui pourrait être à l'origine de l'erreur, mais "on s'en fout", puisqu'on ferme le fichier...

J'avais bien trouvé cette solution avec on Error, mais comme je suis un peu buté, je me refusais à l'employer, préférant essayer de résoudre le souci à sa source. Je suis désolé si cela te donne l'impression d'avoir perdu ton temps, mais c'est tout de même satisfaisant de voir confirmer mes soupçons par un utilisateur nettement plus aguerri que moi...

Merci, donc. :super:

Je considère la question comme résolue, maisje vais attendre un tout petit peu avant de fermer le sujet (je l'ai dit, je suis buté), histoire de voir si un autre gourou de la chose me fera voir la lumière...
Lorsque je clôturerai le fil, Le fil sera clôturé dans la journée, mais je serai obligé de retirer le fichier joint (document "sensible", même sous forme anonymisée). Je laisse le code de la macro, à toutes fins utiles.

Code : Tout sélectionner

Sub FermerBase
'Xray ThisComponent
Dim Svar as Integer
rem-------Demande de confirmation de fermeture-------------------
Svar = MsgBox ("Vous fermez la base",1+32+128,"FERMETURE")
	if Svar = 2 then     'si on clique sur le bouton Annuler -> sortie de la macro
     exit sub
   end if
rem----------Raccourci------------   
'   goto Suite
rem ----Bloque les modifications des saisies de données de la feuille DONNEES si elles sont débloquées------------------------------------------------------------------
	rem----Teste l'état d'une cellule cachée qui détermine le formet conditionnel des cellules de la feuille DONNEES-----
	If ThisComponent.Sheets.getByName("Tables").getCellRangeByName("OK").Value=0 then    'Si la valeur de OK est 0 (saisies débloquées)
		ThisComponent.Sheets.getByName("Tables").getCellRangeByName("OK").Value=1        ' -> valeur mise à 1 (bloquées)
		rem ----Bascule le bouton OFF/ON de protection des données--------------------------------
		ThisComponent.Sheets.getByName("DOSSIERS").DrawPage.Forms(0).getByName("BtnBlocSais").Label = "ON"    'Change le label du bouton
		ThisComponent.Sheets.getByName("DOSSIERS").DrawPage.Forms(0).getByName("BtnBlocSais").BackgroundColor = RGB(255,128,128)      'Colorie le bouton en rouge
	Else
	End If	
rem ----Bloque les modifications des saisies de dates de clôture-----Même processus qiue ci-dessus-------------------------------------------------------------
	If ThisComponent.Sheets.getByName("Tables").getCellRangeByName("OK_2").Value=0 then
		ThisComponent.Sheets.getByName("Tables").getCellRangeByName("OK_2").Value=1
		rem ----Bascule le bouton OFF/ON--------------------------------
		ThisComponent.Sheets.getByName("DOSSIERS").DrawPage.Forms(0).getByName("BtnBlocDat").Label = "ON"
		ThisComponent.Sheets.getByName("DOSSIERS").DrawPage.Forms(0).getByName("BtnBlocDat").BackgroundColor = RGB(255,128,128)
	Else
	End If	
rem ----Bloque les modifications des saisies de scellés---------Même processus qiue ci-dessus---------------------------------------------------------
	If ThisComponent.Sheets.getByName("Tables").getCellRangeByName("OK_3").Value=0 then
		ThisComponent.Sheets.getByName("Tables").getCellRangeByName("OK_3").Value=1
		rem ----Bascule le bouton OFF/ON--------------------------------
		ThisComponent.Sheets.getByName("SCELLES").DrawPage.Forms(0).getByName("BtnBlocSaisScel").Label = "ON"   'change l'étiquette du bouton
		ThisComponent.Sheets.getByName("SCELLES").DrawPage.Forms(0).getByName("BtnBlocSaisScel").BackgroundColor = RGB(255,128,128)    'change la couleur du bouton aui devient vert
	Else
	End If	
rem------ Masque les filtres----------------------
	Dim Var1 as Boolean, Var2 as String, MonBouton as Object, cacher as string
	rem--------Teste une cellule cachée dont la valeur détermine si les filtres sont affichés ou non---------------
	If ThisComponent.Sheets.getByName("Tables").getCellRangeByName("OK_11").Value=1 Then
	rem--------Change la valeur de cette cellule (0= masqués)
	ThisComponent.Sheets.getByName("Tables").getCellRangeByName("OK_11").Value=0
	rem--------Boucle sur les 9 boutons de filtres afin de les rendre invisibles-------------	
		For I = 1 to 9
		MonBouton = "BoutonFiltre"+I
		ThisComponent.Sheets.getByName("DOSSIERS").DrawPage.Forms(0).getByName(MonBouton).EnableVisible = False
		Next
	MasqueFiltres     'Macro qui masque les lignes où se trouvent les boutons des filtres
	Else
	End If
rem------Cible du raccourci
'Suite:
rem--------Apelle une macro séparée qui affiche les barres de menus et les en-tête de lignes/Colonnes-------------
	AfficheToutesBarresOutils
rem-----Appelle les macros pour modifier l'affichege 
	RemiseAZeroFORMULAIRES					'Vide la feuille FORMULAIRES si elle est remplie
	AllProtec					'Protection de toutes les feuilles par mot de passe
rem-----Enregistre et Ferme le tableur---------------------
	ThisComponent.Store(True)
	on Error Resume Next           '
	Thiscomponent.close(True)      'Solution donnée par OOotremer971 sur le forum openoffice.org pour supprimer une erreur aléatoire à la fermeture (merci)
	On Error GoTo 0                '
'	Print "C'est bon, la macro est allée au bout !" '---Pour éviter de fermer le fichier à chaque essai
End Sub
Ajout du 17/08 :
Ben en fait, non, l'erreur aléatoire est réapparue, je ne sais comment.... :marto: En même temps, j'ai produit une telle usine à gaz que maintenant, il devient compliqué de tout éplucher pour voir où ça pèche !
LibreOffice 6.0.3.2 sur Ubuntu 16.04 LTS ou Windows 10 Pro au travail
LibreOffice 6.3.0 sur MacOS Mojave à la maison
Avatar de l’utilisateur
Dude
IdOOle de la suite
IdOOle de la suite
Messages : 25181
Inscription : 03 mars 2006 07:45
Localisation : 127.0.0.1

Re: [Calc] Erreur BASIC à la fermeture DisposedException

Message par Dude »

Salut,

Fermer un document avec une macro intégrée a toujours été erratique.

Outre le fait que je n'en vois pas l'intérêt, le plus simple est donc :
  1. de s'en remettre à l'utilisateur
  2. de placer la macro à hauteur du logiciel ou dans une extension
Avatar de l’utilisateur
marhra
NOOuvel adepte
NOOuvel adepte
Messages : 17
Inscription : 06 janv. 2010 17:53
Localisation : Ardennes

Re: [Calc] Erreur BASIC à la fermeture DisposedException

Message par marhra »

Bonjour Dude,

Merci de ta réponse.

J'ai alors deux soucis (entre autres)
- Je ne peux me permettre la solution 1. En effet, le fichier est destiné à des utilisateurs parfois, disons, maladroits... et j'ai des contraintes externes de protection des données saisies (Cofrac, etc...), ce qui m'a conduit, petit à petit, à supprimer les barres d'outils et à imposer le passage par la macro lors de la fermeture, des petits malins persistant à vouloir absolument quitter le fichier à l'aide de la maudite petite croix en haut à gauche (ou à droite), ne pas cliquer sur "Enregistrer" en quittant, et de manière plus générale, à ne pas faire ce qu'on leur demande... D'où mon machin très verrouillé et contraignant.
Il aurait sans doute été plus simple et sécurisé de passer par une vraie Bdd avec formulaires, mais la dernière fois que j'ai essayé de comprendre, j'ai fini comme cà : :fou: :aie: ...

- Mes connaissances en la matière étant modestes, je ne vois pas clairement ce que signifie ta solution 2. Dis-moi si je me trompe : il s'agit soit de copier la macro FermerBase dans la bibliothèque Mes Macros et Boîtes de dialogue, sur chaque machine utilisant le fichier en question, soit de créer une extension à installer, là aussi sur chaque machine, qui ferait le boulot ?
Outre que me lancer la conception du truc revient pour moi à me jeter dans la brume les yeux bandés, je me vois mal expliquer la marche à suivre à une population qui pense majoritairement que quand on appuie sur un bouton, "y-a un truc magique qui fait machiner les choses dans le bidule, et voilà !". :shock:

Mais tout de même, pour ma culture personnelle, pourrais-tu m'éclairer ?

Merci d'avance.

PS : (je me cite)
Il n'y a pas de conséquences visibles pour moi sur le fonctionnement du tableau, qui fonctionne normalement à la réouverture. Aussi ma préoccupation est-elle, outre le ''mais pourquoi ?'', d'ordre esthétique. Le fichier est à usage pro et il faut reconnaître que ça ne fait pas très pro, justement, d'avoir un message d'erreur à la fermeture d'un fichier de travail...
Donc, une piste pour simplement ne pas avoir le message me satisferait quand même...
LibreOffice 6.0.3.2 sur Ubuntu 16.04 LTS ou Windows 10 Pro au travail
LibreOffice 6.3.0 sur MacOS Mojave à la maison
Avatar de l’utilisateur
OOotremer971
ManitOOu
ManitOOu
Messages : 2744
Inscription : 16 avr. 2010 13:31

Re: [Calc] Erreur BASIC à la fermeture DisposedException

Message par OOotremer971 »

Bonjour,

Je remarque que ta sub FermerBase est appelée par un clic sur un des boutons Fermer la base, jusque là tout va bien, mais en plus tu demandes à l’événement "Le document va être fermé", d'appeler cette même Sub elle même à l’origine de la fermeture du document :? :
marhra.png
C'est un peu l'histoire du serpent qui s'avale la queue... à un moment ça coince.

Je te suggère de tester par quel événement la fermeture du document a été demandée :

Code : Tout sélectionner

Sub FermerBase(optional oEvt)
[...ici tout ton code jusqu'à ...]
ThisComponent.Store(True)
if IsMissing(oEvt) then
    on Error Resume Next
    Thiscomponent.close(True)
    On Error GoTo 0   	
ElseIf oEvt.EventName = "OnPrepareUnload" Then
    Exit sub	
End If
'Print "C'est bon, la macro est allée au bout !" '---Pour éviter de fermer le fichier à chaque essai
End Sub
Si la Sub est appelée par l’événement Le document va être fermé on sort de la Sub sans demander de fermer le document puisque c'est déjà fait. :marto: :tesfou:

Je te laisse tester ton fichier modifié :
Vous ne pouvez pas consulter les pièces jointes insérées à ce message.
En principe, toujours à jour des dernières versions dites stables
AOO
LibreOffice
Debian 10 et 11
Avatar de l’utilisateur
marhra
NOOuvel adepte
NOOuvel adepte
Messages : 17
Inscription : 06 janv. 2010 17:53
Localisation : Ardennes

Re: [Calc] Erreur BASIC à la fermeture DisposedException

Message par marhra »

Bonjour,
Ça me semble être une excellente suggestion ! J’avais oublié cette double affectation...
Malheureusement, en raison d’une panne du réseau au niveau national, je n’ai plus accès au fichier… Je ne vais pas pouvoir tester immédiatement. Je me suis rabattu sur mon téléphone pour répondre...
Dès que c’est possible, je teste.

Par ailleurs, pourrait-on simplement affecter tout le code uniquement à l’événement, et transformer la macro FermerBase en ne laissant que la commande close ?
Edit :
En fait, non. Ça ferme juste brutalement le fichier...
Par contre, je pense obtenir le même résultat (utiliser close une seule fois), en modifiant deux-trois choses :
- la fin de la macro FermerBase, qui perd ses dernières lignes après

Code : Tout sélectionner

ThisComponent.Store(True)
mais qu’on laisse affectée à l’événement Le document va être fermé
- le cas Quitter du select de la macro Bouton avec :

Code : Tout sélectionner

FermerBase
on Error Resume Next
Thiscomponent.close(True)
On Error GoTo 0
Si je ne me plante pas, il n’y a qu’avec les boutons Fermer la Base que close est utilisé...
 Ajout : Sinon, j’ai testé le fichier modifié avec ta méthode, OOotremer971.
L’erreur aléatoire... m’est revenue dans la figure... :aie:
Avec ma méthode aussi...
Il semble qu’il n’y ait pas de solution, mais je ne désespère pas ! :wink: 
LibreOffice 6.0.3.2 sur Ubuntu 16.04 LTS ou Windows 10 Pro au travail
LibreOffice 6.3.0 sur MacOS Mojave à la maison
Avatar de l’utilisateur
OOotremer971
ManitOOu
ManitOOu
Messages : 2744
Inscription : 16 avr. 2010 13:31

Re: [Calc] Erreur BASIC à la fermeture DisposedException

Message par OOotremer971 »

marhra a écrit :Si je ne me plante pas, il n’y a qu’avec les boutons Fermer la Base que close est utilisé...
Exact !
marhra a écrit :Sinon, j’ai testé le fichier modifié avec ta méthode, OOotremer971.
L’erreur aléatoire... m’est revenue dans la figure... :aie:
Si tu pouvais nous fournir une méthode pas à pas qui conduit au message d'erreur, on pourrait alors tester pour tenter de reproduire et éventuellement conclure que le soucis ne vient pas du fichier mais de l'environnement dans lequel il fonctionne.
Quelles sont les autres applications qui tournent en parallèle avec ce fichier lorsqu'il génère l'erreur ?

Quelles est la version du JRE utilisée pour LO : menu Outils>>Options>Avancé pour le découvrir.

A+
En principe, toujours à jour des dernières versions dites stables
AOO
LibreOffice
Debian 10 et 11
Avatar de l’utilisateur
marhra
NOOuvel adepte
NOOuvel adepte
Messages : 17
Inscription : 06 janv. 2010 17:53
Localisation : Ardennes

Re: [Calc] Erreur BASIC à la fermeture DisposedException

Message par marhra »

Bon alors,

On a deux versions de postes de travail : Ubuntu 16.07 LTS ou Win 10 Pro 16299.1087
Le fichier est enregistré sur un serveur (lui-même sous Linux, mais je ne sais pas quelle version. A noter que je travaille sur une version en local sur mon poste.
Tous les postes (serveurs compris) sont loggés via un proxy situé à ....
En général, il y a Firefox et Thunderbird qui tournent en permanence.
Le JRE est Oracle Corporation 1.8.0_162 (pour les postes Ubuntu et Win10 Pro)
LibreOffice en détail, c'est Version: 6.0.3.2 Build ID: 1:6.0.3~rc2-0ubuntu0.16.04.1~lo2 (c'est un release spécifique à ma boutique)

Après moult essais et ouvertures/fermetures, de toutes les façons possibles (sur poste Ubuntu ou Win10 Pro, avec ou sans application qui tourne en parallèle, ouverture-fermeture, ouverture-saisies-fermeture, ouverture-boutons-saisies-fermeture, etc....), l'erreur apparaît toujours. De plus, tous ces essais m'ont permis de constater qu'en fait, c'est la non-apparition de l'erreur qui est aléatoire, en plus d'être rare. Il semblerait que seule la fermeture sans rien avoir modifié ne la fasse pas apparaître...

Il ne reste que deux hypothèses :
1- Fermer un fichier avec ThisComponent.close(True) est définitivement incompatible avec la bonne marche de l'ensemble... Mais alors, pourquoi existe-t-elle ?
2- Ça vient du fichier et il y a des scories de vieilles macros ou de codes plus ou moins compatibles avec la version actuelle... Pour en avoir le cœur net, j'ai fait un tout petit fichier avec juste les macros Quitter et FermerBase, l'une affectée à un bouton, l'autre à l'événement Le document va être fermé

Code : Tout sélectionner

sub Quitter
sVar = MsgBox ("Fermer la base ?",1+32+128,"FERMETURE")
	If sVar = 1 Then
		FermerBase
		on Error Resume Next
		ThisComponent.close(True)
		On Error GoTo 0
	Else
	Exit Sub
	End If

end sub

Sub FermerBase
 MsgBox ("Juste un essai pour que la macro fasse quelque chose de visible",0,"Boîte")
 ThisComponent.store(True)
End Sub
Et ça marche, les deux font leur job, pas de message d'erreur...

Je vais donc gratter dans mon code et simplifier/supprimer tout ce qui me paraît bizarre, inutile, trop exotique... Et regarder ce que ça donne.
Le sujet pourrait être considéré comme résolu, mais je voudrais le laisser ouvert encore un petit peu, au cas où...

Merci à vous deux !

Ajout du 22/08/2019 11:41

C'est bon, je crois que c'est fini ! :super:

En faisant le ménage dans mes macros, j'ai vu que TitreDoc tournait en boucle, ce qui pouvait contrarier LibO à la fermeture...
Je l'ai donc supprimée, après avoir constaté qu'elle tournait toujours alors même que j'avais enlevé le lien à l'événement de feuille. :?: (Une cellule continuait à être remplie, à chaque modification de la feuille ...???!??)
puis j'ai enfin compris qu'en plus de déclencher un .close(True), les boutons Fermer la Base envoyaient dans une macro avec Select... Case, au contraire du passage par la petite croix de fermeture en haut à gauche (ou a droite, c'est selon) qui ne provoquent pas l'apparition du message d'erreur, tout comme l''utilisation du bouton Fermer la fenêtre ajouté à la barre d'outils ou l'utilisation des touches Ctrl+W.

Bref, la source du problème est je pense :
- Soit une macro en boucle qui n'est pas fermée au moment du .close(True)
- Soit un .close(True) avant la sortie du Select
- Soit les deux.

J'ai donc sorti la routine Quitter du select et je l'ai mise dans une macro bien isolée toute seule, loin de toute boucle ou Select, et je l'ai affectée à un bouton Fermer la base ...
Au passage, j'ai utilisé

Code : Tout sélectionner

	ThisComponent.CurrentController.Frame.close(True)
au lieu de

Code : Tout sélectionner

	ThisComponent.close(True)
au cas ou il y aurait une histoire de fermeture de fenêtre versus fermeture de fichier...

Résultat :
- Utilisation de ce bouton particulier -> Pas d'erreur
- Utilisation des autres boutons avec passage par le Select -> Erreur...

:super: :bravo:

Je place donc le sujet en résolu et résume la solution :
 Ajout : Lorsqu'on veut fermer un tableau par un bouton, il faut
- veiller à ce qu'aucune boucle ne tourne
- Passer par une macro isolée :

Code : Tout sélectionner

Sub Quitter
rem-------Demande de confirmation de fermeture-------------------
sVar = MsgBox ("Fermer la base ?",1+32+128,"FERMETURE")
If sVar = 1 Then
	FermerBase
	on Error Resume Next
	ThisComponent.CurrentController.Frame.close(True)
	On Error GoTo 0
Else
	Exit Sub
End If
End Sub
Et en principe, tout se passe bien. 
J'ai aussi édité le titre du fil pour le rendre un peu plus explicite...
Merci à vous deux pour m'avoir poussé à me triturer un peu les méninges et à avancer.... :super:
Vous ne pouvez pas consulter les pièces jointes insérées à ce message.
LibreOffice 6.0.3.2 sur Ubuntu 16.04 LTS ou Windows 10 Pro au travail
LibreOffice 6.3.0 sur MacOS Mojave à la maison