I. Où en est-on ?▲
Cet article constitue la suite de Contrôler la production de vaches laitières avec Access.
Les données relatives aux contrôles laitiers sont importées, il nous reste à les exploiter :
II. Préliminaires : construire une table tAnalyse avec une ligne par vache▲
Une table dont chaque enregistrement aura cet aspect :
1er temps : recueillir la date de chaque contrôle
2e temps : numéroter les contrôles : le rang 1 pour le contrôle le plus récent, le rang 2 pour l'avant-dernier, 3 pour l'antépénultième et ainsi de suite.
3e temps : trois requêtes (rRangx, où x=1, 2 ou 3) pour extraire les données relatives à chaque rang
4e temps : une requête qui crée une table (tAnalyse) pour juxtaposer tous les morceaux
Remarquez la syntaxe des colonnes des Rx :
Pour le calcul du rapport entre TPx et TBx, on remplace TPx par zéro si sa valeur est Null
et on remplace TBx par 1 si sa valeur est Null.
Ceci pour éviter qu'une erreur (division par zéro) soit levée si l'un de ces deux opérandes a la valeur Null.
Public
Function
ZeroNullToOne
(
Ceci As
Variant
) As
Double
If
Ceci =
0
Or
IsNull
(
Ceci) Then
ZeroNullToOne =
1
Else
ZeroNullToOne =
Ceci
End
If
End
Function
On aurait pu utiliser une simple requête de type Sélection avec les mêmes colonnes.
Cependant comme ces données seront exploitées plusieurs fois et que l'exécution de cette requête est relativement longue (1 s), nous avons préféré une exécution unique (à l'ouverture du formulaire) avec sauvegarde des données dans une table (tAnalyse).
Le formulaire fAnalyse est une enveloppe qui contient - pour un éleveur choisi - quatre sous-formulaires juxtaposés. Dans un premier temps, nous allons expliquer chaque composante en détail, nous verrons ensuite comment on les a intégrées dans l'enveloppe. |
III. Le formulaire sfAnalyseDonnesGlobales▲
III-A. Sa source▲
C'est la requête rsfAnalyseDonnesGlobales construite au départ de la table tAnalyse décrite plus haut.
Sur la figure, les repères montrent la correspondance entre les colonnes de la requête et les contrôles du formulaire.
IV. Le formulaire sfAnalyseMoins100jrs▲
IV-A. Sa source▲
C'est la requête rsfAnalyseMoins100jrs
Elle ramène toutes les colonnes de la table tAnalyse pour autant que :
- l'éleveur correspond à celui choisi ;
- la durée de lactation était inférieure à 100 jours lors du dernier contrôle.
IV-B. Les mises en forme conditionnelles▲
V. Le formulaire sfAnalyseDuTroupeau▲
V-A. Sa source▲
À l'ouverture, le formulaire aura pour source la requête rsfAnalyseDuTroupeauNumCtl.
C'est le même genre de construction que celle décrite plus haut pour le formulaire sfAnalyseDonnesGlobales.
Pour éviter une division par zéro. |
V-B. Deux présentations en alternance▲
Un clic sur le bouton déclenche ce code :
Option
Compare Database
Option
Explicit
Private
Sub
BtCritere_Click
(
)
If
Me.BtCritere.Caption
=
"Par N° de contrôle"
Then
'Changer le libellé du bouton
Me.BtCritere.Caption
=
"Par N° de lactation"
'Changer la source
Me.RecordSource
=
"rsfAnalyseDuTroupeauNumLacta"
'Ajuster les contrôles du formulaire
Me.txtCritere.ControlSource
=
"NumLacta"
Me.etiCritere.Caption
=
"N°Lacta"
Else
'Changer le libellé du bouton
Me.BtCritere.Caption
=
"Par N° de contrôle"
'Changer la source
Me.RecordSource
=
"rsfAnalyseDuTroupeauNumCtl"
'Ajuster les contrôles du formulaire
Me.txtCritere.ControlSource
=
"NumControle1"
Me.etiCritere.Caption
=
"N°Ctl"
End
If
End
Sub
N.B. La requête rsfAnalyseDuTroupeauNumLacta est identique à rsfAnalyseDuTroupeauNumCtl décrite plus haut, si ce n'est le regroupement qui s'opère sur NumLacta plutôt que sur NumControle1 :
VI. Le formulaire sfAnalyseDetailParVL▲
VI-A. Sa source▲
VI-B. Deux présentations en alternance▲
Un clic sur le bouton déclenche ce code :
Option
Compare Database
Option
Explicit
Private
Sub
BtTri_Click
(
)
Dim
q As
QueryDef
Dim
t
(
) As
String
If
Me.BtTri.Caption
=
"Par N° de contrôle"
Then
'Changer la légende
Me.BtTri.Caption
=
"Par N° de Lactation"
'Changer le tri de la requête source (rsfAnalyseVLparNumCtl)
'On récupère le SQL de la source d'origine
Set
q =
CurrentDb.QueryDefs
(
"rsfAnalyseVLparNumCtl"
)
t =
Split
(
q.SQL
, "Order By"
)
'On modifie l'ordre de tri
Me.RecordSource
=
t
(
0
) &
"ORDER BY tVL.numLacta, tAnalyse.NomBovide;"
'Aménager la présentation du formulaire
Me.txtNumControle1.FontWeight
=
400
Me.txtNumLacta.FontWeight
=
700
Set
q =
Nothing
Else
'Changer la légende
Me.BtTri.Caption
=
"Par N° de contrôle"
'Remettre la requête source d'origine
Me.RecordSource
=
"rsfAnalyseVLparNumCtl"
'Aménager la présentation du formulaire
Me.txtNumControle1.FontWeight
=
700
Me.txtNumLacta.FontWeight
=
400
End
If
End
Sub
VI-C. Quelques explications en plus▲
VII. Tout en un▲
L'idée, on choisit un éleveur dans une liste déroulante et les quatre formulaires s'affichent ensemble :
VII-A. Construction pas à pas▲
VII-A-1. Une zone de liste dans l'entête▲
VII-A-2. Incorporer les quatre sous-formulaires dans la section Détail▲
Afficher la liste des formulaires, sélectionner un des quatre formulaires et le faire glisser vers la section Détail :
Répéter l'opération pour les trois autres, pour obtenir ceci :
VII-A-3. Au chargement du formulaire, créer la table des données tAnalyse▲
Private
Sub
Form_Load
(
)
DoCmd.SetWarnings
False
DoCmd.OpenQuery
"rCreatAnalyse"
DoCmd.SetWarnings
True
End
Sub
VII-A-4. Voyons le résultat▲
À ce stade, si nous tentons d'afficher le formulaire, une erreur est levée :
Si nous cliquons sur Débogage, il vient ceci :
Que se passe-t-il ?
Notre formulaire contient quatre sous-formulaires qui ont chacun une source qui se réfère à tAnalyse. Exécuter la requête rCreatAnalyse revient à d'abord supprimer cette table (pour la recréer ensuite avec des données éventuellement plus récentes). Protestation véhémente d'Access qui stoppe le processus.
VII-A-5. Va falloir ruser !▲
Nous allons tout simplement modifier nos sous-formulaires… en supprimant leur source… et en la restituant en temps opportun.
Si nous supprimons les sources des sous-formulaires, nous aurions ceci à l'ouverture de fAnalyse :
Mieux vaut cacher cette présentation peu sympathique !
Plaçons à « Non » la propriété « Visible » des conteneurs des sous-formulaires :
Cette fois, à l'ouverture, ce code est exécuté :
Private
Sub
Form_Load
(
)
DoCmd.SetWarnings
False
DoCmd.OpenQuery
"rCreatAnalyse"
DoCmd.SetWarnings
True
Me.cboEleveur.SetFocus
Me.cboEleveur.Dropdown
DoCmd.MoveSize
105
, 100
, 18540
, 3000
End
Sub
Et il vient ceci :
Et lorsque l'utilisateur aura choisi l'éleveur qu'il veut analyser, le code suivant se déclenche :
Private
Sub
cboEleveur_AfterUpdate
(
)
Me.CTNRsfAnalyseDonnesGlobales.Form.RecordSource
=
"rsfAnalyseDonnesGlobales"
Me.CTNRsfAnalyseDonnesGlobales.Visible
=
True
Me.CTNRsfAnalyseMoins100jrs.Form.RecordSource
=
"rsfAnalyseMoins100jrs"
Me.CTNRsfAnalyseMoins100jrs.Visible
=
True
Me.CTNRsfAnalyseDuTroupeau.Form.RecordSource
=
"rsfAnalyseDuTroupeauNumCtl"
Me.CTNRsfAnalyseDuTroupeau.Visible
=
True
Me.CTNRsfAnalyseDetailParVL.Form.RecordSource
=
"rsfAnalyseVLparNumCtl"
Me.CTNRsfAnalyseDetailParVL.Visible
=
True
DoCmd.MoveSize
105
, 100
, 18540
, 10515
End
Sub
On restitue sa source à chacun des sous-formulaires et on le rend à nouveau visible.
VIII. Téléchargement▲
La base de données au format Access 2000 est ici.
(Décompressez l'archive dans un répertoire quelconque.)
IX. Remerciements▲
Ma gratitude à Joël50 qui a pris le temps de m'expliquer en détail les aspects métier de ce tutoriel.
Merci aussi à Malick Seck pour les retouches orthographiques.