samedi 6 juillet 2013

Formulaires: rafraîchir sans bouton

Considérons dans libreoffice base un formulaire donnant accès aux données de la table "employés" d'une base de données PostgreSQL à laquelle libreoffice est connecté.
Nous avons détaillé dans ce billet comment constituer un tel formulaire.
Choisissons d'éditer ce formulaire et ouvrons le navigateur de formulaire.
Nous obtenons ceci:


La table "employés" est la source de données du sous-formulaire "Employés".
Cliquer droit dans le navigateur de formulaires sur l'icône "Sélection" :


nous permet d'afficher le panneau des propriétés du formulaire principal "Sélection". Dans notre cas, la source de données de ce formulaire principal "Sélection" est une instruction SQL


Cette instruction fait référence à une table "sélection" dont voici la description:

   Column    |         Type          | Modifiers 
-------------+-----------------------+-----------
 utilisateur | character varying(20) | not null
 matricule   | integer               |

Le sous-formulaire "Employés" est lié à "Sélection" via le champ "matricule" (clef primaire de la table "employés") comme le montre le panneau des propriétés du sous-formulaire "Employés" (accessible bien sûr en cliquant droit sur l'icône "Employés")


Le formulaire contient un bouton 'OK' qui appartient au sous-formulaire "Employés". Quand on clique dessus après avoir encodé un matricule, le focus passe de "Sélection" à "Employés" ce qui provoque l'écriture dans la table "sélection" du matricule encodé. Ensuite l'action attribuée au bouton (à savoir "Rafraîchir le formulaire") est exécutée.
Tout ceci a été expliqué très en détail précédemment et ça fonctionne très bien.
Maintenant nous aimerions nous passer de ce bouton.
"Rafraîchir le formulaire" consiste en fait à recharger (relire) les tables. Afin de pouvoir procéder sans bouton, nous allons assigner la macro

'*************************************
Sub ReloadTableOne
'*************************************
    Dim Frm as object
    Frm=Thiscomponent.DrawPage.Forms.getByIndex(0)
    Frm.reload()
End Sub

à l’événement "Après l'action d’enregistrement"  figurant dans l'onglet "Événement" des propriétés du formulaire "Sélection"
Auparavant nous devons rendre cette macro accessible. Passons par Outils->Macros-> Gérer les macros


et choisissons d'éditer Mes macros->Standard->Modules 1:


Il nous suffit ensuite d'effectuer un copier-coller du texte de la macro:



De cette manière la macro est disponible pour l'utilisateur courant, quelle que soit le fichier .odb ouvert (elle se trouve dans ~/.config/libreoffice/4/user/basic/Standard/Module1.xba).

On peut aussi l'incorporer au document (bd01.odb dans notre exemple): dans ce cas le code ne sera disponible que pour ce document.
Si bd01.odb->Standard->Module1 n'existe pas encore, il faut cliquer sur nouveau pour le créer:



Si le module existe déjà, cliquer sur "Nouveau" nous permet d'ajouter la macro à ce module.
Pour que la macro puisse être utilisée, il faut via Outils->Options->Sécurité->Sécurité des macros


ajouter l'emplacement du fichier aux sources de confiances.

Si tout est en ordre au niveau des macros, un appui sur ENTER après encodage d'un matricule provoquera un rafraîchissement à condition que le focus soit propulsé hors du formulaire principal "Sélection". Pour cela, il faut veiller à faire passer la séquence d'activation du contrôle "fmtmatricule" de 0 à 1.

Qu'en est-il maintenant si à la place du champ formaté permettant de saisir le matricule, le formulaire contient une boite combinée (combobox):


Dans cette boite combinée se trouve une liste ordonnées de matricules issue de la table "employés". La zone de saisie de la boite combinée est liée à la colonne matricule de la table "sélection". Bien sûr si après avoir cliqué sur un élément de la liste, nous appuyons sur ENTER, tout se passe comme dans le cas précédent. L'idéal serait évidemment que l'on ne doive pas appuyer sur ENTER. Il faudrait que le clic propulse le focus quelque part dans le sous-formulaire "employés".
On peut y arriver en assignant une macro (que nous appelons "SetFocusToEmployés") à l'événement "Statut de l'élément modifié" du panneau des propriétés de la boite combinée (onglet "Événement"):


Ce panneau des propriétés est comme d'habitude accessible en cliquant droit sur ce qui convient (ici l'icône combobox1) dans le navigateur de formulaire:


Voici le texte de cette macro:

'*************************************
Sub SetFocusToEmployes
'*************************************
    Dim Champ AS object
    Dim Controleur AS object
    Champ=Thiscomponent.DrawPage.Forms.GetByName("Sélection").getByName("Employés").getByName("txtnom")
    Controleur = Thiscomponent.getCurrentController()
    Controleur.getControl(Champ).setFocus()
End Sub

qui doit être rendue accessible tout comme la macro précédente

Le bouton "OK" est devenu inutile et le formulaire s'emploie maintenant de manière beaucoup plus confortable puisqu'un seul clic sur un matricule permet d'afficher les données concernées.