IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

OpenOffice & LibreOffice Discussion :

Ordre des événements et réentrance dans les macro de traitement des évémenents


Sujet :

OpenOffice & LibreOffice

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    66
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 66
    Points : 30
    Points
    30
    Par défaut Ordre des événements et réentrance dans les macro de traitement des évémenents
    Bonjour,

    Sur un formulaire Libre Office base je rencontre deux problèmes :

    1. J'ai une Form avec plusieurs SubForm au premier niveau Au démarrage de ma Form je reçois donc des événements "Après changement d'enregistrement" pour chaque sous formulaire. Mais l'ordre ne me convient pas et je me demande s'il serait possible de le modifier, sans doute au niveau du controler de la Form principale. Quelqu'un a t-il une réponse à cela ?

    2. Les macros commandes que j'ai créé pour traiter certains événements sont problématiques car lorsqu'un appel est en cours d'execution et qu'un second appel déclenche une nouvelle execution avant la fin du premier, cela peut provoquer des erreurs de réentrance, surtout lorsque le corps du traitement de l'évement execute des requêtes en base de donnée. Même lorsque ce sont des requêtes SELECT j'ai déjà observé des plantages sérieux. J'ai lu dejà plusieurs livres sur la programmation OOo Basic et Base mais je n'ai rien trouvé pour traiter ce problème de réentrance dans les gestionnaires d'événements. J'ai essayé avec une variable globale servant de flag singleton, mais cela ne me convient pas vraiment. Existe t-il des fonctions multithread dans OOo Basic que je pourrais mettre en oeuvre ? Est-ce que chaque evenement est seulement dans un thread différents ?

    Merci pour votre aide.

  2. #2
    Rédacteur

    Avatar de zoom61
    Homme Profil pro
    ...
    Inscrit en
    Janvier 2005
    Messages
    9 429
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Vienne (Limousin)

    Informations professionnelles :
    Activité : ...
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2005
    Messages : 9 429
    Points : 58 222
    Points
    58 222
    Billets dans le blog
    11
    Par défaut
    Citation Envoyé par gelinp Voir le message
    1. J'ai une Form avec plusieurs SubForm au premier niveau Au démarrage de ma Form je reçois donc des événements "Après changement d'enregistrement" pour chaque sous formulaire. Mais l'ordre ne me convient pas et je me demande s'il serait possible de le modifier, sans doute au niveau du controler de la Form principale. Quelqu'un a t-il une réponse à cela ?
    Il faut modifier la séquence d'activation.

    Citation Envoyé par gelinp Voir le message
    2. Les macros commandes que j'ai créé pour traiter certains événements sont problématiques car lorsqu'un appel est en cours d'execution et qu'un second appel déclenche une nouvelle execution avant la fin du premier, cela peut provoquer des erreurs de réentrance, surtout lorsque le corps du traitement de l'évement execute des requêtes en base de donnée. Même lorsque ce sont des requêtes SELECT j'ai déjà observé des plantages sérieux. J'ai lu dejà plusieurs livres sur la programmation OOo Basic et Base mais je n'ai rien trouvé pour traiter ce problème de réentrance dans les gestionnaires d'événements. J'ai essayé avec une variable globale servant de flag singleton, mais cela ne me convient pas vraiment. Existe t-il des fonctions multithread dans OOo Basic que je pourrais mettre en oeuvre ? Est-ce que chaque evenement est seulement dans un thread différents ?
    Pourquoi ne pas faire apparaître un affichage d'attente comme sur les pages Web !
    N'oubliez pas le Tag afin de faciliter la recherche, et en votant cela permet de mieux la cibler.

    Je ne réponds pas aux messages privés s'ils sont liés à une question technique

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    66
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 66
    Points : 30
    Points
    30
    Par défaut
    1. J'ai compris que la séquence d'activation change l'ordre d'activation des contrôles dans un formulaire. Ce dont j'ai besoin c'est de changer l'ordre d'activation des formulaires de niveau 1 (tous directement attachés à la collection des formulaires). Et là je n'ai pas compris comment faire car je n'ai pas trouvé comment modifier l'ordre d'activation des formulaires, mais seulement des contrôles...

    2. J'ai essayé une boucle du type while (test) wait 200 Wend. Mais cela ne résout pas mon problème qui est que j'ai des appels venant d'autres formulaires, lesquels sont dans le désordre et répétitifs. Par ailleurs ma condition de test semble ne pas toujours fonctionner correctment, cela peut être parcequ'il y a des cas de réentrance particuliers qui se joueraient sur le fil du rasoir de quelques milisecondes... Enfin bref, j'essaie d'organiser la synchronsitation des évenements de façon heursitique mais je pense qu'il doit bien déjà exister une méthode sinon même des modèles de conception ? J'ai encore peu d'information sur les services du contrôler des forms. Peut être que je pourrais essayer de renvoyer tous les messages des contrôlers vers un contrôler centrale que je pourrais programmer pour qu'il ordonne tous les élèvements... Cela ne me semble pas ce qu'il y aurait de plus simple... Pour l'utilisateur il y aura un délait d'attente, oui. Mais ce qui m'importe surtout c'est d'éviter la réentrance dans ma fonction car cela provoque un crash de mon application sinon une déstabilisation de son contexte d’exécution. J'essaie aussi d'optimiser les requêtes en evitant qu'une même requête soit envoyée deux ou trois fois de suite.

  4. #4
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    66
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 66
    Points : 30
    Points
    30
    Par défaut
    Bonjour,

    J'ai continué mes tests sur la gestion de la réentrance des événements de changement d'enregistrement gérés par un formulaire LibreOffice. J'ai essayé de réaliser un simple mutex avec un wait, mais cela ne peut pas fonctionner car je m'aperçois grace à de nombreuses traces présentées ci-dessous qu'un évènement réentrant est souvent traité en priorité, et pendant ce temps LibreOffice semble bloquer le premier thread entrant ! Ci-dessous un extrait de mon code (Sub ActualiserEtatInterface appelée sur chaque changement d'enregistrement) et ensuite les traces.

    Ce que je cherche à comprendre c'est comment utiliser Uno depuis une macro Basic pour gérer un mutex correctement ...

    Merci pour votre aide.
    Patrick

    Ci-dessous un extrait de mon code, encore très brouillon...

    Note : Le folioteur permet de numéroter chaque évènement, en incrémentant une variable globale de 1 à chaque appel...
    FlagActualiserEtatInterface est une variable globale servant de flag pour définir la réservation de la ressources partagée par le Mutex

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    Sub ActualiserEtatInterface(unoEvent As Object)
     
    	Dim oEvent As Object
    	Dim NumEvent As long
    	Dim ControllerName As String
    	Dim FormName As String
     
    	On Local Error Goto Error_Sub	
     
    	Set oEvent = Application.Events(unoEvent)
     
            Rem impression des traces pour voir le contexte (ordre, horodatage...) de cet évènement
    	NumEvent = Folioteur  ''voir code de la procédure ci-dessous...		
    	gDebug.Trace(Name, "1/6 =================================" & CHR(10) & "ActualiserEtatInterface::DEBUT")
    	FolioteurTrace     'voir code de la procédure ci-dessous...
    	gDEbug.Trace(Name, "2/6 ActualiserEtatInterface::Num Event : " & NumEvent & ", oEvent::Name : " &  oEvent.EventName)
    	gDebug.Trace(Name, "3/6 ActualiserEtatInterface::Flag = " & FlagActualiserEtatInterface & ", ChienDeGarde = " & ChienDeGarde)
     
    	'============= GESTION DU MUTEX AVEC CHIEN DE GARDE - DEBUT
    	While FlagActualiserEtatInterface and ChienDeGarde <= 10
    		ChienDeGarde = ChienDeGarde + 1
    		Wait 200 'millisecondes
    		gDebug.Trace(Name, "*** EN ATTENTE (Num. Event : " & NumEvent &  ", Chien de Garde : " & ChienDeGarde &") ***")
    	Wend
     
    	If ChienDeGarde > 10 Then
    		gDebug.Trace(Name, "CHIEN DE GARDE EXIT POUR L'EXEMPLAIRE (" & NumEvent &")")
    		ChienDeGarde = 0
    		Exit Sub
    	EndIf
     
    	'Pour éviter une actualisation concurrente de l'interface...
     	ThisDatabaseDocument.lockControllers
    	FlagActualiserEtatInterface = true	
    	gDebug.Trace(Name, "4/6 Mutex resérvé par Num Event " & NumEvent)
     
    	'DETECTION DES EVENEMENTS DOUBLES ...
            'En fin de compte ce code ne semble pas fonctionner, il n'y a jamais de doublon de l'évènement provenant de FmXFormController, simplement des évènements doubles envoyés ce qui semble une répétition sur les boutons de l'interface, sinon deux actions utilisateurs trop rapides ...
    	ControllerName = "com.sun.star.form.FmXFormController"
    	FormName = "com.sun.star.comp.forms.ODatabaseForm"
    	If StrComp(unoEvent.Source.ImplementationName, ControllerName, 0) = 0 Then 
    		gDebug.Trace(Name, "*** STOP FORMCONTROLLER EVENT (" & NumEvent & ") ****")
    		Stop
    	EndIf	
    	'============= GESTION DU MUTEX AVEC CHIEN DE GARDE - FIN
     
     
    	_ActualiserFormOnglets(oEvent.Source.Name, NumEvent)	
     
    Exit_Sub:
    	On error resume next	
    	FlagActualiserEtatInterface = false
    	ChienDeGarde = 0
    	gDebug.Trace(Name, "5/6 Mutex relaché par Num Event " & NumEvent)
    	gDebug.Trace(Name, "6/6 ActualiserEtatInterface::FIN" & CHR(10) & "=================================")
    	ThisDatabaseDocument.unlockControllers
    	Exit Sub
    Error_Sub:
    	TraceError("ERROR", Err, Name, Erl)
    	gDebug.Catch(Name)
    	Goto Exit_Sub
    End Sub

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    Global DictFolioteur As Object
    Global _NextUID As Long 'default is 0
    Global t1, t2 As Long
     
    Function Folioteur As Long
    	_NextUID = _NextUID + 1
     
    	t2 = GetSystemTicks
    	If not EstVide(DictFolioteur) Then DictFolioteur.Ajouter(_NextUID, Format(Time, "hh\h mn\mn ss\s\ec") & "   Delta ticks : " & t2 - t1)	
    	t1 = t2
    	Folioteur = _NextUID
    End Function
     
    Sub FolioteurTrace
    	Dim Iterateur As Object
     
    	Iterateur = DictFolioteur.Iterateur	
    	while Iterateur.Suivant
    		gDebug.Trace(Name, Iterateur.ElementCourrant.Key & ", " & Iterateur.ElementCourrant.item)
    	Wend
     
    End Sub
    Le folioteur permet de numéroter chaque évènement, en incrémentant une variable globale de 1 à chaque appel...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
     
     
    REM CHARGEMENT DU FORMULAIRE, C'EST LE PREMIER EVENEMENT 
     
    "**************************
    1/3 LorsDuChargement::DEBUT"
    "16/01/2018 20:16:24 - [FormNoticeBibliographiqueImpl] ASSERTION SUCCESS (2/3 LorsDuChargement::ASSERT(_OngletsManager) (Num Event : 1))"
    "3/3 LorsDuChargement::FIN
    **************************"
     
     
    REM APRES LE CHARGEMENT VIENT LA PREMIERE ACTUALISATION DU FORMULAIRE POUR L'ENREGISTREMENT 
    REM COURRANT, C'EST LE DEUXIEME EVENEMENT, IL ARRIVE 81 MS APRES LE PREMIER (Delta ticks : 81)
     
    "1/6 =================================
    ActualiserEtatInterface::DEBUT"
    "1, 20h 16nmn 24sec   Delta ticks : 6728814"
    "2, 20h 16nmn 24sec   Delta ticks : 81"
    "2/6 ActualiserEtatInterface::Num Event : 2, oEvent::Name : "
    "3/6 ActualiserEtatInterface::Flag = False, ChienDeGarde = 0"
    "ImplementationName = com.sun.star.comp.framework.JobExecutor"
    "4/6 Mutex resérvé par Num Event 2"
    " ------------------------------
    1/3 _ActualiserFormOnglets::DEBUT"
    "2/3 _ActualiserFormOnglets::Num event : 2, oEvent::Name : FORM_NOTICES_BIBLIOGRAPHIQUES"
    "1/3 ////////////////////////
    TFormOnglet::ActualiserEtat::DEBUT"
    "2/3 _SelectedOnglet = "
    "TFormOnglet::ActualiserEtat : Onglet vide, selection du premier onglet par defaut"
    "3/3 TFormOnglet::ActualiserEtat::FIN
    ////////////////////////"
    "3/3 _ActualiserFormOnglets::FIN
    ------------------------------"
    "5/6 Mutex relaché par exemplaire Num Event 2"
    "6/6 ActualiserEtatInterface::FIN
    ================================="
     
    REM ENREGISTREMENT SUIVANT, JUSQUE LA TOUT VA BIEN, SANS COLLISION...
     
    "1/6 =================================
    ActualiserEtatInterface::DEBUT"
    "1, 20h 16nmn 24sec   Delta ticks : 6728814"
    "2, 20h 16nmn 24sec   Delta ticks : 81"
    "3, 20h 16nmn 52sec   Delta ticks : 27702"
    "2/6 ActualiserEtatInterface::Num Event : 3, oEvent::Name : "
    "3/6 ActualiserEtatInterface::Flag = False, ChienDeGarde = 0"
    "ImplementationName = com.sun.star.comp.framework.JobExecutor"
    "4/6 Mutex resérvé par Num Event 3"
    " ------------------------------
    1/3 _ActualiserFormOnglets::DEBUT"
    "2/3 _ActualiserFormOnglets::Num event : 3, oEvent::Name : FORM_NOTICES_BIBLIOGRAPHIQUES"
    "1/3 ////////////////////////
    TFormOnglet::ActualiserEtat::DEBUT"
    "2/3 _SelectedOnglet = btANALYSE"
    "3/3 TFormOnglet::ActualiserEtat::FIN
    ////////////////////////"
    "3/3 _ActualiserFormOnglets::FIN
    ------------------------------"
    "5/6 Mutex relaché par exemplaire Num Event 3"
    "6/6 ActualiserEtatInterface::FIN
    ================================="
     
    REM ENREGISTREMENT SUIVANT, AVEC UN DOUBLE CLIC SUR LE BOUTON. IL Y A COLLISION, MAIS C'EST 
    REM LE DEUXIEME EVENEMENT REENTRANT QUI EST TRAITE EN PRIORITE, LE PREMIER SEMBLE AVOIR ETE 
    REM GELE PAR LIBREOFFICE. MON MUTEX N'ACTIVE PAS L'APPEL WAIT CAR L'APPEL REENTRANT VOIT LE 
    REM FLAG ActualiserEtatInterface= false, COMME POUR LE PREMIER EVENEMENT ! POURQUOI ? JE NE SAIS PAS ...
     
    REM EVENEMENT 1 ENTRANT...
    "1/6 =================================
    ActualiserEtatInterface::DEBUT"
    "1, 20h 16nmn 24sec   Delta ticks : 6728814"
    "2, 20h 16nmn 24sec   Delta ticks : 81"
    "3, 20h 16nmn 52sec   Delta ticks : 27702"
    "4, 20h 16nmn 55sec   Delta ticks : 3790"
    "2/6 ActualiserEtatInterface::Num Event : 4, oEvent::Name : "
    "3/6 ActualiserEtatInterface::Flag = False, ChienDeGarde = 0"
    "ImplementationName = com.sun.star.comp.framework.JobExecutor"
     
    REM INTERRUPTION DE L'EVENEMENT 1 PAR L'EVENEMENT 2 REENTRANT...
        :DEBUT"
        "1, 20h 16nmn 24sec   Delta ticks : 6728814"
        "2, 20h 16nmn 24sec   Delta ticks : 81"
        "3, 20h 16nmn 52sec   Delta ticks : 27702"
        "4, 20h 16nmn 55sec   Delta ticks : 3790"
        "5, 20h 16nmn 56sec   Delta ticks : 482"
        "2/6 ActualiserEtatInterface::Num Event : 5, oEvent::Name : "
        "3/6 ActualiserEtatInterface::Flag = False, ChienDeGarde = 0"
        "ImplementationName = com.sun.star.comp.framework.JobExecutor"
        "4/6 Mutex resérvé par Num Event 5"
        " ------------------------------
        1/3 _ActualiserFormOnglets::DEBUT"
        "2/3 _ActualiserFormOnglets::Num event : 5, oEvent::Name : FORM_NOTICES_BIBLIOGRAPHIQUES"
        "1/3 ////////////////////////
        TFormOnglet::ActualiserEtat::DEBUT"
        "2/3 _SelectedOnglet = btANALYSE"
        "3/3 TFormOnglet::ActualiserEtat::FIN
        ////////////////////////"
        "3/3 _ActualiserFormOnglets::FIN
        ------------------------------"
        "5/6 Mutex relaché par exemplaire Num Event 5"
        "6/6 ActualiserEtatInterface::FIN
        ================================="
     
    REM REPRISE ET FIN DU TRAITEMENT DE L'EVENEMENT 1...
    "4/6 Mutex resérvé par Num Event 4"
    " ------------------------------
    1/3 _ActualiserFormOnglets::DEBUT"
    "2/3 _ActualiserFormOnglets::Num event : 4, oEvent::Name : FORM_NOTICES_BIBLIOGRAPHIQUES"
    "1/3 ////////////////////////
    TFormOnglet::ActualiserEtat::DEBUT"
    "2/3 _SelectedOnglet = btANALYSE"
    "3/3 TFormOnglet::ActualiserEtat::FIN
    ////////////////////////"
    "3/3 _ActualiserFormOnglets::FIN
    ------------------------------"
    "5/6 Mutex relaché par exemplaire Num Event 4"
    "6/6 ActualiserEtatInterface::FIN
    ================================="

Discussions similaires

  1. Réponses: 5
    Dernier message: 23/09/2015, 11h35
  2. [XL-2010] Exécuter une macro seulement dans les feuilles nommées par des nombres.
    Par baptou42 dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 19/05/2014, 16h40
  3. Nouveautés 2010 en vidéo - des paramètres dans les macros
    Par Maxence HUBICHE dans le forum Access
    Réponses: 6
    Dernier message: 16/01/2010, 12h05
  4. Réponses: 28
    Dernier message: 09/01/2007, 16h30
  5. Réponses: 10
    Dernier message: 03/09/2004, 17h26

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo