Nous allons revenir sur le sujet traité dans ce billet, à savoir la création de formulaires dans libreoffice base (à l'époque c'était openoffice base).
L'approche sera cette fois différente: nous n'utiliserons pas l'assistant et donnerons un rôle encore plus important au navigateur de formulaires. La base de données utilisée (appelée bd01) est une base de données PostgreSQL concernant comme précédemment la gestion du personnel d'une entreprise.
Création de la structure du formulaire.
Après connexion à cette base de données cliquons sur "Créer un formulaire en mode Ébauche" et ensuite dans la fenêtre qui apparaît cliquons sur l'icône du navigateur de formulaire située dans la barre d'outils horizontale inférieure:
Dans le navigateur, cliquons droit sur "Formulaires" et dans le menu contextuel qui surgit, choisissons "Nouveau Formulaire":
Ce nouveau formulaire s'appelle par défaut "Formulaire". Donnons lui un nom plus parlant. Pour afficher les données qui nous intéressent, nous allons utiliser une table "selection" contenant l'identifiant (matricule) du dossier à sélectionner. nous appellerons donc ce premier formulaire "Sélection".
Recommençons l'opération en cliquant droit sur l'icône du formulaire qui vient d'être créé:
Le nouveau formulaire (qui dépendra de "Sélection") contiendra les données des employés de l'entreprise: nous l’appellerons "Employés".
Continuons de la sorte de manière à arriver à ceci:
"Département" affichera le département du lieu de résidence de l'employé, "Salaire" le salaire pour un mois donné et "Détails" les détails de ce salaire (prime, régularisation, heures sup etc).
Il s'agit d'un exemple.
Autre exemple:
Il s'agit cette fois d'une structure correspondant à l'affichage des données d'un client (d'un magasin) avec date et montant d'une facture et les détails de celle-ci.
Sources de données et liens entre sous-formulaires.
Ouvrons la fenêtre "Propriétés"du formulaire "Sélection". On peut procéder via le menu contextuel de "Sélection" ou en cliquant sur l'icône formulaire de la barre d'outils:
On déclare la source de données comme étant la table selection et on n'autorise ni les ajouts ni les suppressions:
Rappelons que la table selection dont voici la description (ouput de la meta commande psql \dS):
(NB: les tables PostgreSQL dont le contenu est amené à être modifié dans libreoffice base doivent être munies d'une clef primaire)
Passons aux propriétés du sous-formulaire "Employés". La source de données à indiquer est la table que nous avons précédemment appelé entrh.
Elle contient les colonnes:
Le lien entre les formulaires "Employés" et "Sélection" sera basé sur la colonne matricule:
Le nom du département se trouve dans une table nommée frdepartem:
Pour libreoffice, cette vue apparaît comme une table que nous allons désigner comme source de données du sous-formulaire "Département" qui sera lié à "Employé" via code_postal et cp_seq:
Pour le reste nous avons créé la table paie (et donné les droits adéquats):
Nous avons aussi créé la vue salaire:
Enfin pour le sous-formulaire "Détails", on établit les propriétés comme suit:
Mise en place des éléments du formulaire.
Passons à l'étape de la mise en place des différents éléments du formulaire.
Choisissons en premier un arrière-plan en passant par le menu Format -> Page:
soit une couleur, soit une image:
Reste à disposer les différents champs.
Avant de procéder, veillons à ce que "Sélection" soit sélectionné au niveau du navigateur de formulaires.
Dans la barre d'outils verticale de gauche, choisissons "Champ d'étiquette":
Après que nous ayons dimensionné cet élément, cliquons droit pour afficher son menu contextuel:
Modifions le nom en "lblmatricule" et la valeur de l'étiquette en "Matricule".
Sélectionnons maintenant "Champ formaté" (toujours dans la barre d'outils verticale):
Nous plaçons ce champ en dessous du champ d'étiquette précédent et dans la fenêtre des propriétés, après avoir renommer ce champ, nous appuyons sur les 3 petits points qui permettent de lui attribuer le champ d'étiquette (label) précédent:
Notre zone de liste sera basée sur cette vue:
lbxlocalite correspond au nom de la zone de liste "Localité" et txtcode_postal au nom du champ "Code postal":
Pour intégrer ces macros à notre fichier odb, il faut passer par Outils->Macros-> Gérer les macros:
Après avoir valider "Module 1" dans la fenêtre qui surgit, on atterrit dans un éditeur et on y remplace le texte qui y figure:
L'approche sera cette fois différente: nous n'utiliserons pas l'assistant et donnerons un rôle encore plus important au navigateur de formulaires. La base de données utilisée (appelée bd01) est une base de données PostgreSQL concernant comme précédemment la gestion du personnel d'une entreprise.
Création de la structure du formulaire.
Après connexion à cette base de données cliquons sur "Créer un formulaire en mode Ébauche" et ensuite dans la fenêtre qui apparaît cliquons sur l'icône du navigateur de formulaire située dans la barre d'outils horizontale inférieure:
Dans le navigateur, cliquons droit sur "Formulaires" et dans le menu contextuel qui surgit, choisissons "Nouveau Formulaire":
Ce nouveau formulaire s'appelle par défaut "Formulaire". Donnons lui un nom plus parlant. Pour afficher les données qui nous intéressent, nous allons utiliser une table "selection" contenant l'identifiant (matricule) du dossier à sélectionner. nous appellerons donc ce premier formulaire "Sélection".
Recommençons l'opération en cliquant droit sur l'icône du formulaire qui vient d'être créé:
Le nouveau formulaire (qui dépendra de "Sélection") contiendra les données des employés de l'entreprise: nous l’appellerons "Employés".
Continuons de la sorte de manière à arriver à ceci:
"Département" affichera le département du lieu de résidence de l'employé, "Salaire" le salaire pour un mois donné et "Détails" les détails de ce salaire (prime, régularisation, heures sup etc).
Il s'agit d'un exemple.
Autre exemple:
Il s'agit cette fois d'une structure correspondant à l'affichage des données d'un client (d'un magasin) avec date et montant d'une facture et les détails de celle-ci.
Sources de données et liens entre sous-formulaires.
Ouvrons la fenêtre "Propriétés"du formulaire "Sélection". On peut procéder via le menu contextuel de "Sélection" ou en cliquant sur l'icône formulaire de la barre d'outils:
On déclare la source de données comme étant la table selection et on n'autorise ni les ajouts ni les suppressions:
Colonne | Type | Modificateurs
-----------+---------+---------------
id | integer | non NULL
matricule | integer |
Index :
"selection_pkey" PRIMARY KEY, btree (id)
est une table outil dont le seul but est de nous permettre d'afficher aisément le dossier qui nous intéresse.-----------+---------+---------------
id | integer | non NULL
matricule | integer |
Index :
"selection_pkey" PRIMARY KEY, btree (id)
(NB: les tables PostgreSQL dont le contenu est amené à être modifié dans libreoffice base doivent être munies d'une clef primaire)
Passons aux propriétés du sous-formulaire "Employés". La source de données à indiquer est la table que nous avons précédemment appelé entrh.
Elle contient les colonnes:
Colonne | Type | Modificateurs
-------------+---------------+---------------
matricule | integer | non NULL
nom | character(50) |
adresse | character(50) |
code_postal | character(5) |
cp_seq | smallint |
naissance | date |
sexe | character(1) |
service | character(2) |
Les colonnes code_postal et cp_seq constituent une clé étrangère (foreign key) établissant une relation d'intégrité référentielle avec une table des codes postaux (frcp dans notre base de données) contenant le nom des localités:-------------+---------------+---------------
matricule | integer | non NULL
nom | character(50) |
adresse | character(50) |
code_postal | character(5) |
cp_seq | smallint |
naissance | date |
sexe | character(1) |
service | character(2) |
Colonne | Type | Modificateurs
---------------+---------------+---------------
code_postal | character(5) | non NULL
cp_seq | smallint | non NULL
localite_nom | character(50) |
code_departem | character(2) |
De même la colonne service est définie comme une clé étrangère pointant vers une table service contenant le nom du service:---------------+---------------+---------------
code_postal | character(5) | non NULL
cp_seq | smallint | non NULL
localite_nom | character(50) |
code_departem | character(2) |
Colonne | Type | Modificateurs
--------------+---------------+---------------
service_id | character(2) | non NULL
dénomination | character(25) |
--------------+---------------+---------------
service_id | character(2) | non NULL
dénomination | character(25) |
Le lien entre les formulaires "Employés" et "Sélection" sera basé sur la colonne matricule:
Le nom du département se trouve dans une table nommée frdepartem:
Colonne | Type | Modificateurs
--------------+---------------+---------------
departem_id | character(2) | non NULL
departem_nom | character(30) |
code_region | character(2) |
Pour avoir la possibilité de déduire le nom du département sur base du code postal, nous pouvons au niveau de PostgreSQL définir une vue liant les tables frcp et frdepartem:--------------+---------------+---------------
departem_id | character(2) | non NULL
departem_nom | character(30) |
code_region | character(2) |
CREATE VIEW cpdep AS
SELECT
frcp.code_postal,
frcp.cp_seq,
frcp.localite_nom,
frdepartem.departem_nom
FROM frcp frcp, frdepartem frdepartem
WHERE (frcp.code_departem = frdepartem.departem_id)
;
GRANT SELECT ON cpdep TO PUBLIC
On peut aussi créer une requête dans libreoffice base.SELECT
frcp.code_postal,
frcp.cp_seq,
frcp.localite_nom,
frdepartem.departem_nom
FROM frcp frcp, frdepartem frdepartem
WHERE (frcp.code_departem = frdepartem.departem_id)
;
GRANT SELECT ON cpdep TO PUBLIC
Pour libreoffice, cette vue apparaît comme une table que nous allons désigner comme source de données du sous-formulaire "Département" qui sera lié à "Employé" via code_postal et cp_seq:
Pour le reste nous avons créé la table paie (et donné les droits adéquats):
CREATE TABLE paie
(matricule INTEGER,
mois CHAR(6),
seq SMALLINT,
code CHAR(2),
montant NUMERIC(13,2),
PRIMARY KEY (matricule,mois,seq),
FOREIGN KEY (matricule) REFERENCES entrh)
;
GRANT ALL ON paie TO gestionrh
;
Cette table est liée dans une relation d'intégrité référentielle avec entrh, de sorte qu'un employé ne peut pas être supprimé s'il existe un paiement le concernant. (matricule INTEGER,
mois CHAR(6),
seq SMALLINT,
code CHAR(2),
montant NUMERIC(13,2),
PRIMARY KEY (matricule,mois,seq),
FOREIGN KEY (matricule) REFERENCES entrh)
;
GRANT ALL ON paie TO gestionrh
;
Nous avons aussi créé la vue salaire:
CREATE VIEW salaire
AS
SELECT matricule, mois, sum(montant) AS montant
FROM paie
GROUP BY matricule, mois
;
GRANT SELECT ON salaire TO gestionrh
;
Cette vue sera notre source de données ordonnée suivant le mois pour le sous-formulaire "Salaire", la laison avec "Employés" étant basée sur la colonne matricule:AS
SELECT matricule, mois, sum(montant) AS montant
FROM paie
GROUP BY matricule, mois
;
GRANT SELECT ON salaire TO gestionrh
;
Enfin pour le sous-formulaire "Détails", on établit les propriétés comme suit:
Mise en place des éléments du formulaire.
Passons à l'étape de la mise en place des différents éléments du formulaire.
Choisissons en premier un arrière-plan en passant par le menu Format -> Page:
soit une couleur, soit une image:
Reste à disposer les différents champs.
Avant de procéder, veillons à ce que "Sélection" soit sélectionné au niveau du navigateur de formulaires.
Dans la barre d'outils verticale de gauche, choisissons "Champ d'étiquette":
Via l'élément du menu appelé "Contrôle" nous accédons à la fenêtre des propriétés:
Sélectionnons maintenant "Champ formaté" (toujours dans la barre d'outils verticale):
Nous plaçons ce champ en dessous du champ d'étiquette précédent et dans la fenêtre des propriétés, après avoir renommer ce champ, nous appuyons sur les 3 petits points qui permettent de lui attribuer le champ d'étiquette (label) précédent:
Nous mettons également la Séquence d'activation à 1:
Comme champ de données, nous prenons évidemment "matricule":
Le menu contextuel obtenu lorsque les deux éléments sont sélectionnés nous offre la possibilité de les grouper:
Après avoir sélectionné "Employés" dans le navigateur de formulaires, déposons et déployons un bouton issu de la barre d'outils gauche:
à droite du champ formaté fmtmatricule. Dans la fenêtre propriétés, onglet général, étiquette nous remplaçons la valeur standard "Bouton" par "OK":
C'est ce mot qui apparaîtra sur le bouton.
D'autre part, nous attribuons à ce bouton l'action "Rafraîchir le formulaire":
Procédant comme pour le matricule, plaçons sur le formulaire un champ de type zone de texte, surmonté de son étiquette, qui affichera le nom de l'employé.
Rôle du focus.
Après avoir enregistré le formulaire, désactivons le mode ébauche:
Le nom correspondant au matricule qui est inscrit dans la rangée unique de notre table sélection apparaît alors à l'écran:
Dès l'instant où nous modifions le matricule, la petite disquette de la barre d'outils horizontale prend des couleurs:
signe que le matricule à l'écran n'est plus celui de la base de données.
Frappons la touche "Tabulation": le focus se déplace sur le bouton (ce qui est matérialisé par le rectangle en points tillés autour du mot OK) et la petite disquette perd ses couleurs:
il y a eu écriture du matricule 1007 dans la table sélection. Cela ne fonctionne pas si le bouton appartient au formulaire "Sélection". Autrement dit, l'opération d'écriture se déclenche lorsque le focus quitte le formulaire "Sélection" .
Si nous appuyons maintenant sur le bouton (par exemple en frappant la touche "Enter"), le nom correspondant au matricule 1007 s'affiche:
Nous pouvons aussi directement appuyer sur le bouton à l'aide de la souris (sans y amener le focus à l'aide la touche "tabulation"). Dans ce cas, le fait de cliquer met le focus sur le bouton, ce qui provoque l'écriture, celle-ci étant immédiatement suivie du rafraîchissement (action liée au bouton).
(EDIT: voir dans ce billet comment rafraîchir sans utiliser le bouton OK)
Cliquer sur le bouton y met le focus à condition que dans les propriétés du bouton l'option (par défaut) 'Focus sur clic' ait été conservée:
Dans le cas contraire, cliquer sur le bouton sans toucher au clavier après saisie du matricule, ne produit aucun effet. Mais comment alors parvenir à ses fins sans plus toucher au clavier? Simplement il suffit avant de cliquer de déposer le curseur dans le champ nom, déclenchant ainsi l'écriture du matricule. Mais cette manipulation n'est évidemment jamais nécessaire puisque par défaut 'Focus sur clic = Oui'.
Afficher la localité à l'aide de macros.
Continuons maintenant à disposer les différents éléments constitutifs du sous-formulaire "Employés":
champ de date pour la date de naissance, accessible en cliquant sur "Contrôles supplémentaires"
boutons radio pour le sexe
zone de liste pour le service
adresse, code postal ...
(Pour le détail des manipulations voir ce billet.)
Par la magie de la zone de liste "service", le nom du service apparaît en clair à l'écran et le code derrière (qui est la seule information présente dans entrh) est transparent pour l'utilisateur.
Nous aimerions procéder de même pour la localité de résidence de l'employé et rendre transparent le numéro de séquence (cp_seq) qui associé au code postal pointe vers une localité de frcp. Mais nous allons nous heurter à un gros problème: comment limiter la liste aux localités dont le code postal est celui affiché? Pour parvenir à nos fins, nous allons devoir faire appel à une macro.
Mais tout d'abord, afin d'éliminer un problème qui se présentera lors de l'utilisation de la macro, définissons une vue:
CREATE VIEW frcpn AS
SELECT frcp.code_postal::numeric AS code_postal,
frcp.cp_seq,
frcp.localite_nom,
frcp.code_departem
FROM frcp
;
GRANT SELECT ON frcpn TO PUBLIC
;
La seule différence entre la vue frcpn et la table originale est que le code postal est maintenant une grandeur de type numérique.SELECT frcp.code_postal::numeric AS code_postal,
frcp.cp_seq,
frcp.localite_nom,
frcp.code_departem
FROM frcp
;
GRANT SELECT ON frcpn TO PUBLIC
;
Notre zone de liste sera basée sur cette vue:
Le champ affiché est le nom de la localité:
Et les deux champs qui doivent coïncider sont les deux champs cp_seq:
Nous appellerons cette zone de liste lboxlocalite:
Le contenu de la liste est basé sur une instruction sql:
à laquelle on voudrait ajouter une clause WHERE via l'appel à une macro.
Les macros que nous allons utiliser se trouvent dans un fichier dont voici le contenu:
option explicit
dim LstLocalite AS Object
'*******************************
sub MajListe
'*******************************
DIM var_code_postal
LstLocalite = Thiscomponent.DrawPage.Forms.GetByName("Sélection").getByName("Employés").getByName("lboxlocalite")
var_code_postal = Thiscomponent.DrawPage.Forms.GetByName("Sélection").getByName("Employés").getByName("txtcode_postal").TEXT
LstLocalite.ListSource() = array("SELECT localite_nom, cp_seq FROM public.frcpn AS frcpn WHERE code_postal =" & var_code_postal)
LstLocalite.refresh
end sub
'*******************************
sub Actualisation
'*******************************
dim ExoTrav
MajListe
ExoTrav= ExoRechercheDansTableau(LstLocalite.ValueItemList, LstLocalite.boundField.Value)
if ExoTrav <> "#N/A" then
LstLocalite.SelectedItems = array(ExoTrav)
else
LstLocalite.SelectedItems = array(0)
end if
end sub
'**************************************************
Function ExoRechercheDansTableau(ExoTablo, ExoRech)
'**************************************************
dim i as integer
ExoRechercheDansTableau = "#N/A"
for i = lbound(ExoTablo) to ubound(ExoTablo)
if ExoTablo(i)= ExoRech then
ExoRechercheDansTableau = i
exit for
end if
next i
end function
dim LstLocalite AS Object
'*******************************
sub MajListe
'*******************************
DIM var_code_postal
LstLocalite = Thiscomponent.DrawPage.Forms.GetByName("Sélection").getByName("Employés").getByName("lboxlocalite")
var_code_postal = Thiscomponent.DrawPage.Forms.GetByName("Sélection").getByName("Employés").getByName("txtcode_postal").TEXT
LstLocalite.ListSource() = array("SELECT localite_nom, cp_seq FROM public.frcpn AS frcpn WHERE code_postal =" & var_code_postal)
LstLocalite.refresh
end sub
'*******************************
sub Actualisation
'*******************************
dim ExoTrav
MajListe
ExoTrav= ExoRechercheDansTableau(LstLocalite.ValueItemList, LstLocalite.boundField.Value)
if ExoTrav <> "#N/A" then
LstLocalite.SelectedItems = array(ExoTrav)
else
LstLocalite.SelectedItems = array(0)
end if
end sub
'**************************************************
Function ExoRechercheDansTableau(ExoTablo, ExoRech)
'**************************************************
dim i as integer
ExoRechercheDansTableau = "#N/A"
for i = lbound(ExoTablo) to ubound(ExoTablo)
if ExoTablo(i)= ExoRech then
ExoRechercheDansTableau = i
exit for
end if
next i
end function
lbxlocalite correspond au nom de la zone de liste "Localité" et txtcode_postal au nom du champ "Code postal":
Pour intégrer ces macros à notre fichier odb, il faut passer par Outils->Macros-> Gérer les macros:
Sélectionnant bd01.odb (notre fichier odb), on appuie sur "Nouveau":
par celui des 3 macros ci-dessus.
Assignons la macro "MajListe" à l'événement "Modifié" du champ txtcode_postal. Pour ce faire, on procède via la fenêtre des propriétés du champ, onglet Événement:
Un appui sur les 3 petits points de droite, nous permet d'arriver facilement sur le sélecteur de macro:
De même on assigne la macro "Actualisation" à l'événement "Après le changement d'enregistrement" du formulaire "Employés".
Vérifions si tout est OK:
C'est parfait: le numéro de séquence cp_seq est maintenant transparent pour l'utilisateur du formulaire. Le formulaire est donc considérablement simplifié puisqu'on ne doit plus afficher à l'intention de l'utilisateur une liste des numéros de séquence possibles avec les localités correspondantes. De plus, l'utilisateur ne doit plus encoder un numéro de séquence, mais cliquer sur une localité dans une liste déroulante. Pour éviter les avertissements relatifs à l'utilisation de macros, allons dans Outils -> Options -> Sécurité -> Sécurité des macros, onglet "Sources de confiance" et ajoutons le chemin vers notre fichier odb:
Le formulaire final.
Reste à compléter les sous-formulaires Département, Salaire et Détails.
Voici un exemple de ce à quoi on peut arriver:
(Nous avons remplacé la zone de saisie du matricule par une "boite combinée".)
Post a Comment