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

Gérer un troupeau de moutons avec Access

C:\MesDocuments\ForumAccess\TUTORIELS\Moutons\Divers\L2996.jpg1re partie : la collecte des données

Ceci en réponse à une question posée sur le forum : Outil gestion troupeau avec enregistrement des mises-bas.

L'article peut être vu comme un exercice dirigé pour permettre à de faux débutants d'encore progresser dans :

- la construction de requêtes complexes avec l'interface graphique QBE ;

- l'expression des critères pour la mise en forme conditionnelle ;

- les formulaires pères/fils avec recherche multicritère sur les deux sources.10 commentaires Donner une note à l´article (5) 

Article lu   fois.

L'auteur

Profil ProSite personnel

Liens sociaux

Viadeo Twitter Facebook Share on Google+   

I. Prérequis

Ce tutoriel s'adresse à des utilisateurs qui maitrisent déjà les bases du logiciel Access ou qui veulent faire l'effort pour progresser : l'utilisation du VBA décuple le potentiel de solutions !

Image non disponible

Pour vérifier votre niveau, parcourez ces tutoriels : si vous les comprenez facilement, vous êtes OK et si ce n'est pas le cas, insistez :

- pour commencer : Maxence Hubiche Access - Les Bases ;

- pour construire des requêtes : Jean Ballat Créer des requêtes simples ;

- pour construire un formulaire :Jean-Philippe Ambrosino le chapitre 2-1-2 de Mise en surbrillance d'un enregistrement dans un formulaire ;

- pour le VBA : Olivier Lebeau Initiation au VBA Office.

Image non disponible

D'une manière générale, pour vous documenter sur les propriétés d'un formulaire ou d'un état, ou de leurs contrôles :
- affichez l'objet en mode création ;
- cliquez sur la propriété, elle se met alors en surbrillance ;
- enfoncez la touche <F1>.
Pour un problème de code dans un module, placez le curseur sur le mot-clé du VBA et pressez <F1>.

L'aide Access s'ouvre alors à la bonne page.

On peut aussi :
- ouvrir l'aide <F1>, choisir l'onglet « Aide intuitive » et suivre les instructions ;
- ouvrir la fenêtre d'exécution (<Ctrl> + G), saisir un mot-clé, y placer le curseur de la souris et presser <F1>.

II. Quelques notions « métier »

II-A. Les données qui permettent d'identifier un mouton

Le N° d'éleveur

Officiellement appelé « Indicatif de marquage ».

Six chiffres.

Le N° de travail

Cinq chiffres.
Le premier chiffre correspond à l'année de naissance (5 pour la campagne 2015).
Les quatre suivants sont un numéro d'ordre.

N.B. Les campagnes ne sont pas à l'année civile, mais du 1er juillet au 30 juin de l'année suivante.

La combinaison N° d'éleveur/N° de travail est unique : en 2025, on aura 5xxxx, avec xxxx différents de ceux qui avaient été attribués en 2015.

Cette combinaison figure sur la plaque que le mouton porte à l'oreille durant toute sa vie.

Image non disponible

À chaque début de campagne, l'éleveur indique à l'administration - suivant ses prévisions d'agnelages - combien de boucles il veut.

II-B. Les données qui caractérisent un mouton

La race

Charollais, Bleu du Maine, Île-de-France, Suffolk, Romane, Texel…

La généalogie

Pour autant qu'elle soit connue. (C'est rarement le cas pour un mouton acheté.)

Comment il a été allaité

Naturel par sa mère, par une brebis adoptive, au biberon, complémenté…

Comment il est entré dans le troupeau

Naissance dans l'exploitation, achat, prise en pension.

Comment il en est sorti

Vente, consommation propre, sortie de pension, mort, vol.

II-C. La reproduction

Les brebis ont un rythme saisonnier de reproduction dépendant de la variation de la durée du jour au cours de l'année : l'activité sexuelle se manifeste lorsque la durée du jour diminue : du début de l'été à la fin d'automne.Certaines races comme la Romane et l'Île-de-France désaisonnent naturellement (sans hormones !!!), c'est-à-dire qu'elles sont saillies au printemps, pour mettre bas à l'automne et donc proposer des agneaux toute l'année ! Pour stimuler ce désaisonnement, on réalise un flushing avant la lutte (c'est-à-dire qu'on suralimente légèrement les brebis pendant trois semaines) puis « l'effet bélier » fait le reste (l'introduction du bélier dans le troupeau stimule le cycle des brebis).

On constitue une lutte, c'est-à-dire un groupe constitué d'un bélier et de 20 à 40 brebis.

Le bélier porte un harnais avec un bloc marqueur afin que l'arrière-train de la brebis soit marqué d'une couleur lorsqu'elle a été saillie.

La gestation dure de 140 à 150 jours.

On mémorisera les circonstances de mise bas de chaque brebis (seule, aide légère, aide forte, césarienne, embryotomie) afin de ne garder à terme, que les brebis (ou les filles de celles-ci) qui mettent bas facilement.

III. Le modèle de données

Image non disponible

Les chapitres suivants concernent l'encodage des données.

IV. Le formulaire fMenu

Image non disponible

C'est lui qui s'affiche à l'ouverture de l'application.

Image non disponible

Un clic sur les boutons donne l'accès aux principaux formulaires de l'application :

 
Sélectionnez
OOption Compare Database
Option Explicit

Private Sub btInventaire_Click()
  DoCmd.OpenForm "fInventaire"
End Sub

Private Sub btLuttes_Click()
  DoCmd.OpenForm "fLuttes"
End Sub

Private Sub btOvins_Click()
  DoCmd.OpenForm "fOvins"
End Sub

Private Sub BtRepro_Click()
  DoCmd.OpenForm "fRepro"
End Sub

V. Le formulaire fOvins

V-A. Présentation

Image non disponible

Comme dans tout formulaire Access,

Image non disponible

Il s'agit d'un formulaire « tout-en-un » : non seulement il permet de gérer la table tOvins (c'est-à-dire ajouter, supprimer ou modifier des enregistrements), mais il offre la possibilité d'opérer des recherches multicritères. En l'occurrence, suivant les filtres mentionnés dans le pied (le N° d'éleveur, le N° de travail, le sexe, la race, le caractère « fictif »(1)).
Selon les filtres choisis, la source du formulaire est modifiée par exemple :

Image non disponible

N.B. Si aucun ovin ne correspond à la combinaison de filtres, vient ce message :

Image non disponible

La technique de cette méthode est décrite en détail dans ce tutoriel :Formulaire de recherche polyvalent sur la base d'une requête enregistrée.

V-B. La source

Image non disponible
Image non disponible

C:\MesDocuments\PrintScreen\&2.jpg Même principe que C:\MesDocuments\PrintScreen\&1.jpg

C:\MesDocuments\PrintScreen\&3.jpg La comparaison se fait par rapport à la valeur du groupe d'option :

  • si le groupe d'option a une valeur supérieure à zéro (donc si l'utilisateur a choisi Femelles ou Mâles), la requête ramènera les tSexeFK égaux soit à 1 (si « Femelles » est cochée), soit égaux à 2 (si « Mâles » est cochée) ;
  • si le groupe vaut zéro, la requête ramènera les cas où tSexeFK est égal à lui-même, c'est-à-dire tous.
Image non disponible
Image non disponible
 
 

C:\MesDocuments\PrintScreen\15.jpg À l'ouverture du formulaire, le groupe vaut 0, donc « Sans distinction » est cochée.

C:\MesDocuments\PrintScreen\16.jpg Il passe à 1 lorsque l'utilisateur coche « Femelles ».

C:\MesDocuments\PrintScreen\17.jpg Il passe à 2 lorsque l'utilisateur coche «Mâles ».

C:\MesDocuments\PrintScreen\18.jpg Il passe à 0 lorsque l'utilisateur coche « Sans distinction ».

 

C:\MesDocuments\PrintScreen\&4.jpg C'est comme C:\MesDocuments\PrintScreen\&1.jpg et C:\MesDocuments\PrintScreen\&2.jpg. Rappelez-vous que FiltreRace est une zone de liste

Image non disponible

et que, même si elle affiche une race en clair, ce qu'elle contient effectivement, c'est la colonne liée, en l'occurrence tRacePK.

Image non disponible Si la case est grisée Image non disponible (valeur Null), tous les enregistrements seront ramenés,
si la case est cochée Image non disponible (valeur Vrai), seuls les ovins fictifs seront ramenés.

V-C. Quelques fonctionnalités

On utilise la mise en forme conditionnelle :

Image non disponible

Pour la cause de sortie :

Image non disponible

Pour le N° d'éleveur :

Image non disponible

V-C-1. La constante NumElevage

Image non disponible

Nous avons défini une constante NumElevage :

 
Sélectionnez
Option Compare Database
Option Explicit
Public Const NumElevage As String = "102030"    ' <---------À modifier

Ici fixée à 102030. L'utilisateur modifiera une fois pour toutes pour y mentionner son propre numéro.

Cette constante a une portée universelle. C'est-à-dire que l'on peut l'utiliser partout dans l'application (on dit qu'elle est « visible » partout).

Cependant, on ne peut pas utiliser des constantes partout dans Access. Par exemple, dans l'expression d'une mise en forme conditionnelle.

Qu'à cela ne tienne, on contourne en créant une fonction qui renvoie la valeur de la constante :²

 
Sélectionnez
Public Function GetNumElevage() As String
  GetNumElevage = NumElevage
End Function

Là où Access proscrit les constantes, il admet généralement les fonctions.

C'est le cas ici.

V-D. Code du formulaire

 
Sélectionnez
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.
Option Compare Database
Option Explicit

Private Sub Form_Current()
  If Me.coFictif = False Then
      Me.Section("Détail").BackColor = -2147483633  'gris clair
    Else
      Me.Section("Détail").BackColor = 33023  'orange
  End If
End Sub

Public Sub MaJFiltre()
  Me.Requery
  If Me.RecordsetClone.RecordCount = 0 Then
      MsgBox "Pas d'enregistrement avec cette combinaison"
  End If
End Sub

Private Sub BtTout_Click()
  Dim ctl As Control
  For Each ctl In Me.Controls
    If ctl.Name Like "Filtre*" Then
        ctl = Null
    End If
  Next ctl
  Me.FiltreSexe = 0
  Me.Requery
End Sub

Private Sub FiltreNumEleveur_AfterUpdate()
  Call MaJFiltre
End Sub

Private Sub FiltreNumTravail_AfterUpdate()
  Call MaJFiltre
End Sub

Private Sub FiltreRace_AfterUpdate()
  Call MaJFiltre
End Sub

Private Sub FiltreSexe_AfterUpdate()
  Call MaJFiltre
End Sub

Private Sub FiltreFictifs_AfterUpdate()
  If Me.FiltreFictifs = 0 Then Me.FiltreFictifs = Null
  Call MaJFiltre
End Sub

4-9 : on veut afficher la section détail en orange pour attirer l'attention de l'utilisateur sur le fait qu'il s'agit d'un ovin « fictif » (le mâle d'une brebis achetée pleine, ou le mâle d'une brebis inséminée artificiellement). Access n'offre pas la possibilité de mise en forme conditionnelle pour la section « Détail ». Pour pallier ce manque, on recourt à du code : à chaque lecture d'un enregistrement (événement « Sur activation » On current), on modifie la propriété « Couleur de fond » BackColorde la section.

12-49 : ne concerne que la partie « recherche multicritère » décrite dans Formulaire de recherche polyvalent sur la base d'une requête enregistrée.

VI. Le formulaire tLuttes

VI-A. Présentation

Image non disponible

Il s'agit d'un formulaire père/fils :

  • fLuttes, le père avec comme source la table tLuttes ;
  • sfLuttesBrebis, le fils avec comme source la table tLutteBrebis.

Si le concept de formulaire « père/fils » ne vous est pas familier, voyez ce tutoriel : Comment classer les données dans des tables liées et construire un formulaire père/fils.

Lorsque fLuttes affiche un enregistrement de tLuttes, sfLuttesBrebis affiche les enregistrements de tLutteBrebis correspondants.

La clé primaire de tLuttes (tLuttesPK) et la clé étrangère de tLutteBrebis (tLuttesFK) assurent la synchronisation entre les deux composantes :

Image non disponible

VI-B. La source de fLuttes

Tout comme fOvins, ce formulaire est polyvalent : on peut ajouter, modifier ou supprimer les enregistrements de sa source, mais il peut aussi servir de formulaire de recherche multicritère :

Image non disponible

Avec ceci de particulier, que les critères portent sur deux tables :

- la source du formulaire fLuttes (tLuttes) ;

- la source du sous-formulaire sfLuttesBrebis (tLutteBrebis).

Si nous suivons la même logique que pour fOvins, nous créons une requête qui se réfère aux filtres :

Image non disponible

MAIS

voici ce que ramènerait une telle requête :

Image non disponible

c'est-à-dire, pour une lutte, autant de lignes qu'il y a de brebis qui participent à la lutte.

La source de notre formulaire ne doit contenir qu'une seule ligne par lutte !

Qu'à cela ne tienne, transformons la requête de sélection en une requête de regroupement :

Image non disponible

qui, cette fois, ramène une seule ligne par lutte :

Image non disponible

OUI MAIS

une telle requête n'est plus modifiable : vous n'avez plus la possibilité de modifier le contenu d'une colonne, ni supprimer une ligne et encore moins d'en ajouter une !

Donc, ça ne va pas ! Il va falloir ruser !

En fait, il faut dire à Access : « Dans la source, ramenez tous les enregistrements de tLuttes dont le bélier est mentionné dans la requête rfLuttes ! »

Voici les mots qu'il faut pour le dire :

Image non disponible

Dans la foulée, on trie dans l'ordre décroissant de DateDebut. Ainsi, si on fait une recherche selon un bélier ou une brebis, on affichera en premier la dernière lutte à laquelle ils ont participé.

Ce n'est pas beau ça ?

VI-C. Fonctionnalité particulière

VI-C-1. Un carré vert indique qu'une mise bas est déclarée

Image non disponible

Nous verrons dans un chapitre suivant, qu'une mise bas se concrétise par un enregistrement dans la table tLutteBrebis.

Pour faire apparaître un carré vert, nous avons ajouté une zone de texte qui enregistre le nombre (0 ou 1) de mise bas déclarée pour cette femelle dans cette lutte :

Image non disponible

et une mise en forme conditionnelle fait le reste :

Image non disponible
Image non disponible

Remarquez que le 0 ou le 1 n'apparaîtront pas : ils sont de la même couleur que le fond de la zone de texte.

VI-D. Le code de fLuttes

 
Sélectionnez
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.
Option Compare Database
Option Explicit

Private Sub Form_Current()
  Call AmenagerTailleSF(Me.Name, "CTNRsfLuttesBrebis")
  Me.CTNRsfLuttesBrebis.Form!cboBrebis.RowSource = Me.CTNRsfLuttesBrebis.Form!cboBrebis.RowSource
End Sub

Private Sub Form_Close()
  If CurrentProject.AllForms("fMisesBas").IsLoaded Then DoCmd.Close acForm, "fMisesBas"
End Sub

Public Sub MaJFiltre()
  Me.Requery
  If Me.RecordsetClone.RecordCount = 0 Then
      MsgBox "Pas d'enregistrement avec cette combinaison"
  End If
End Sub

Private Sub BtTout_Click()
  Dim ctl As Control
  For Each ctl In Me.Controls
    If ctl.Name Like "Filtre*" Then
        ctl = Null
    End If
  Next ctl
  Me.Requery
End Sub

Private Sub FiltreBelier_AfterUpdate()
  Call MaJFiltre
End Sub

Private Sub FiltreBrebis_AfterUpdate()
  Call MaJFiltre
End Sub

Private Sub txtDateFin_AfterUpdate()
  Me.Refresh
End Sub

Commentaires du code

3-7 : concerne l'ajustement de la hauteur du sous-formulaire (voir § suivant).

9-11 : nous présenterons tout à l'heure le formulaire fMisesBas. Il fonctionne de pair avec fLuttes et cela n'a pas de sens de laisser fMisesBas ouvert si fLuttes est fermé.

13-36 : rien de particulier. Ne concerne que la partie « recherche multicritère » décrite dans Formulaire de recherche polyvalent sur la base d'une requête enregistrée.

VI-E. Le sous-formulaire fils sfLuttesBrebis

 

VI-E-1. La hauteur du sous-formulaire s'adapte au nombre d'enregistrements qu'il contient

Image non disponible

de manière à ce que la section « Pied » qui renseigne le nombre de femelles de la lutte soit « collée » à la fin de la section Détail.

Pour une description détaillée du processus, voir Comment ajuster la taille d'un sous-formulaire en fonction du nombre de ses enregistrements.

VI-E-2. Zone de liste pour le choix des brebis

Image non disponible

Pour être candidate dans une lutte, il faut :

Image non disponible qu'il s'agisse d'une femelle ;

Image non disponible qui est présente dans le troupeau au début de la mise en lutte. En d'autres mots, elle doit avoir une date d'entrée antérieure à celle du début de lutte et sa date de sortie doit être soit nulle, soit postérieure à celle du début de lutte ;

Image non disponible elle doit avoir au moins 300 jours d'âge à la date de début de lutte ;

Image non disponible si elle a déjà mis bas, il faut que la dernière fois remonte à au moins septante-cinq jours (ma belgitude ne résiste pas au plaisir d'écrire 75 en lettres ! Image non disponible) ;

Image non disponible elle ne doit pas déjà faire partie d'une autre lutte encore en cours.

La requête qui ramène les ovins qui satisfont aux cinq critères :

Image non disponible

VI-E-3. Le code de sfLuttesBrebis

 
Sélectionnez
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.
Option Compare Database
Option Explicit

Private Sub Form_Current()
  If CurrentProject.AllForms("fMisesBas").IsLoaded Then DoCmd.Close acForm, "fMisesBas"
  Me.cboBrebis.RowSource = Me.cboBrebis.RowSource
End Sub

Private Sub Form_AfterDelConfirm(Status As Integer)
  Call AmenagerTailleSF(Me.Parent.Name, "ctnr" & Me.Name)
End Sub

Private Sub Form_AfterInsert()
Call AmenagerTailleSF(Me.Parent.Name, "ctnr" & Me.Name)
End Sub

Private Sub btMB_Click()
  If Me.cboBrebis = 0 Then Exit Sub 'clic sur enregistrement encore vierge
  DoCmd.OpenForm "fMisesBas", , , , , acHidden
  PositionForm Forms("fMisesBas"), Me.btMB
End Sub

Private Sub cboBrebis_AfterUpdate()
  On Error GoTo GestionErreurs
  Me.Refresh
GestionErreurs:
  Select Case Err.Number
    Case 0
      Exit Sub
    Case 3022  'doublon
      MsgBox "Cette brebis N° " & Me.cboBrebis.Text & " fait déjà partie de la lutte."
      Me.Undo
  End Select
End Sub

Commentaires du code

4-7 : à chaque changement d'enregistrement :
- (5) on ferme le formulaire fMiseBas, car s'il est encore ouvert, il se rapporte à l'enregistrement qui était actif juste avant ;
- (6) on réactualise la propriété « Contenu » de la zone de liste.

9-15 : ces instructions concernent l'adaptation de la hauteur du sous-formulaire.

17-21 : le clic sur le bouton « Mise bas » sur une ligne d'enregistrement :

Image non disponible

- (18) sera sans effet, s'il s'agit du bouton situé sur la ligne qui propose d'ajouter un enregistrement ;

- (19-20) va provoquer l'ouverture du formulaire fMisesBas juste en dessous du bouton qui a été cliqué (ou à proximité selon la place disponible à l'écran).

Cette technique a été présentée par Arkham46 dans cette contribution.

Image non disponible

Il n'y a pas besoin de comprendre tout ce qu'il y a sous le capot pour savoir conduire une voiture.

Pour utiliser la proposition d'Arkham46 :                                                                          

- vous copiez dans un module le code donné à la fin de cet article ;                                   

- pour commander l'ouverture du formulaire, ces deux lignes de code :                              

 
Sélectionnez
  DoCmd.OpenForm "LeNomDuFormulaire", , , , , acHidden
  PositionForm Forms("LeNomDuFormulaire "), Me.LeNomDuControleRepere

- le formulaire à ouvrir doit être une fenêtre indépendante :                                                 

Image non disponible

23-33 : on vérifie ici que la brebis qui vient d'être désignée ne fait pas déjà partie de la lutte que nous sommes en train de déclarer.
On provoque la sauvegarde de l'enregistrement… et Access fait le reste, car dans la définition de la table tLutteBrebis, nous avons placé un index unique sur la combinaison lutte/brebis :

Image non disponible

Dès lors, en cas de tentative de doublon, Access lève une erreur 3022 que nous récupérons pour afficher ce message :

Image non disponible

VII. Le formulaire fMisesBas

VII-A. Présentation

Lorsqu'une brebis met bas, il faut enregistrer la (les) naissance(s), voici la suite des opérations :

Image non disponible

Image non disponible Un clic dans le menu.

Image non disponible Dans le formulaire fLuttes, filtrer pour afficher la dernière lutte de la brebis.

Image non disponible Un clic sur le bouton « MiseBas ».

Le formulaire fMisesBas s'affiche :

Image non disponible

L'utilisateur complète (ici des jumeaux pour la Saint-Nicolas !) et comptabilise :

Image non disponible

Les deux agneaux ont été automatiquement enregistrés dans la table tOvins.

Remarquez que le bouton « À comptabiliser » a été remplacé par « Déjà enregistré » et les données ne sont plus modifiables (ni ajout, ni suppression) pour cette mise bas.

VII-B. Particularités techniques

Image non disponible

Image non disponible Les contrôles en rouge sont utiles au fonctionnement, mais sans intérêt pour l'utilisateur. Ils ont leur propriété Visible positionnée à Non.

Image non disponible Tout comme fOvins et fLuttes, fMisesBas est du type père/fils.

Image non disponible Le contrôle TXTtLuttesBrebisFK prend comme valeur par défaut le contenu de TXTtLuttesBrebisPK de la brebis courante dans fLuttes :

Image non disponible

Donc, à la création de l'enregistrement - lors de la première ouverture du formulaire fMiseBas pour cette brebis dans cette lutte -, le champ tLutteBrebisFK (la clé étrangère) sera automatiquement mis à jour.

Image non disponible Seulement un des deux boutons aura sa propriété Visible positionnée à Oui, selon le stade de comptabilisation de la mise bas.

VII-B-1. Utilisation (acrobatique) de la mise en forme conditionnelle

Image non disponible

Pour le N° de travail

Image non disponible

Image non disponible situation normale

Image non disponible

Image non disponible cas de la ligne qui propose d'ajouter un enregistrement

Image non disponible

Image non disponible si l'agneau est viable, il doit avoir un N°, par contre il ne peut avoir de N° s'il n'est pas viable

Image non disponible

Image non disponible si l'agneau n'est pas viable et pas de N°, le champ s'affiche en gris

Image non disponible

Image non disponible

Pour l'allaitement

Image non disponible

Image non disponible situation normale

Image non disponible

Image non disponible agneau non viable

Image non disponible

Image non disponible cas de la ligne de l'enregistrement à ajouter

Image non disponible

VII-C. La source de fMisesBas

Image non disponible

En d'autres mots, les enregistrements de tMisesBas qui concernent la brebis dont il est actuellement question dans le formulaire fLuttes.

VII-D. Le code du formulaire fMisesBas

 
Sélectionnez
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.
Option Compare Database
Option Explicit

Private Sub Form_Current()
  With Me
      If Me.txtEnregistreeMB = True Then
          'Afficher le bouton qui convient
          .btComptabiliser.Visible = False
          .btEnregistree.Visible = True
          'Interdire les modif
          .AllowEdits = False
          .AllowDeletions = False
          'Interdire les modif dans le sfLuttesBrebis
          .CTNRsfMisesBasAgneaux.Form.AllowAdditions = False
          .CTNRsfMisesBasAgneaux.Form.AllowDeletions = False
          .CTNRsfMisesBasAgneaux.Form.AllowEdits = False
        Else
          'Afficher le bouton qui convient
          .btComptabiliser.Visible = True
          .btEnregistree.Visible = False
          'Autoriser les modif
          .AllowEdits = True
          .RecordSelectors = True
          'Autoriser les modif dans le sfMisesBasAgneaux
          .CTNRsfMisesBasAgneaux.Form.AllowAdditions = True
          .CTNRsfMisesBasAgneaux.Form.AllowDeletions = True
          .CTNRsfMisesBasAgneaux.Form.AllowEdits = True
       End If
  End With
End Sub

Private Sub btComptabiliser_Click()
  Dim iReponse As Integer
  'Demande de confirmation
  iReponse = MsgBox("Confirmez que vous voulez enregistrer cette mise bas", vbYesNo + vbQuestion + vbDefaultButton2)
  If iReponse = vbNo Then Exit Sub
  With Me
      'MàJ de EnregistreeMB
      .txtEnregistreeMB = True
      'Rendre le formulaire non modifiable
      .AllowEdits = False
      .AllowDeletions = False
      'Rendre le sous-formulaire non modifiable
      .CTNRsfMisesBasAgneaux.Form.AllowAdditions = False
      .CTNRsfMisesBasAgneaux.Form.AllowDeletions = False
      .CTNRsfMisesBasAgneaux.Form.AllowEdits = False
      'Changer de bouton
      .txtEnregistreeMB = True
      .txtDateMB.SetFocus
      .btComptabiliser.Visible = False
      .btEnregistree.Visible = True
      'Enregistrer tMisesBas
      .Refresh
  End With
  'Enregistrer les naissances dans tOvins
  DoCmd.SetWarnings False
  DoCmd.OpenQuery "rComptaMiseBas"
  DoCmd.SetWarnings True
End Sub

Commentaires du code

Pas de difficulté : les explications incluses dans les instructions devraient suffire.

Ligne 57 : la requête rComptaMiseBas est décrite au paragraphe suivant.

VII-E. rComptaMiseBas, la requête qui intègre les nouveau-nés dans tOvins

Image non disponible

Image non disponible Il s'agit d'une requête qui va ajouter un enregistrement dans tOvins pour chaque nouveau-né.

Image non disponible Cet enchevêtrement de tables permet d'accéder à toutes les données nécessaires pour alimenter les colonnes de tOvins. Remarquez que tOvins est assignée deux fois (une première pour se connecter aux données de la brebis et une seconde fois pour se connecter à celles du bélier).

Image non disponible Les enregistrements ramenés par cette requête seront limités à ceux dont le tLutteBrebisPK est celui de la brebis dont on déclare la mise bas…

Image non disponible … pour autant que l'agneau soit viable.

Deux colonnes méritent un mot d'explication.

  • NumEleveur
Image non disponible

Ici par exemple, pour compléter le N° d'éleveur de l'agneau, on indique le N° de l'élevage.

Pour rappel, on utilise une fonction, car une constante n'est pas admise dans une requête.

L'explication a été donnée plus haut ici.

  • tRaceFK
Image non disponible
Image non disponible

En d'autres mots : si les deux parents sont de même race, ce sera la race du nouveau-né, sinon ce dernier sera de race « Indéterminée ».

Des « zinnekes » comme on dit à Bruxelles Image non disponible.

Nous clôturons ici cette première partie de l'article.

Dans une prochaine publication, nous aborderons l'utilisation des données essentiellement à l'aide de deux formulaires :

Image non disponible
Image non disponible

VIII. Annexe : Proposition de Arkham46 pour positionner le formulaire pForm par rapport au contrôle pControl

Voici le code de Arkham46 dont il est question au paragraphe Le code du sous-formulaire fils sfLuttesBrebis.

 
Sélectionnez
Option Compare Database
Option Explicit

 
'***************************************************************************************
'*                                       API                                           *
'***************************************************************************************
Private Declare Function SetWindowPos Lib "User32" (ByVal hwnd As Long, ByVal hWndInsertAfter As Long, ByVal x As Long, ByVal y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long
Private Declare Function GetWindowRect Lib "User32" (ByVal hwnd As Long, lpRect As RectAPI) As Long
Private Declare Function GetDC Lib "User32" (ByVal hwnd As Long) As Long
Private Declare Function ReleaseDC Lib "User32" (ByVal hwnd As Long, ByVal Hdc As Long) As Long
Private Declare Function GetDeviceCaps Lib "gdi32" (ByVal Hdc As Long, ByVal nIndex As Long) As Long
Private Declare Function ClientToScreen Lib "User32" (ByVal hwnd As Long, lpPoint As PointAPI) As Long
Private Declare Function SystemParametersInfo Lib "User32" _
                     Alias "SystemParametersInfoA" (ByVal uAction As Long, _
                     ByVal uParam As Long, ByRef lpvParam As RectAPI, _
                     ByVal fuWinIni As Long) As Long
'***************************************************************************************
'*                                       Types                                         *
'***************************************************************************************
' Type Point pour API
Public Type PointAPI
    x As Long
    y As Long
End Type
Public Type RectAPI
    Left As Long
    Top As Long
    Right As Long
    Bottom As Long
End Type
'***************************************************************************************
'*                                    Constantes                                       *
'***************************************************************************************
Private Const SWP_NOSIZE = &H1
Private Const SWP_NOMOVE As Long = &H2
Private Const SWP_NOZORDER = &H4
Private Const SWP_SHOWWINDOW = &H40
Private Const LOGPIXELSY = 90
Private Const LOGPIXELSX = 88
Private Const SPI_GETWORKAREA = 48
 
'---------------------------------------------------------------------------------------
' Convertit les Twips en Pixels sur l'axe horizontal
'---------------------------------------------------------------------------------------
' pTwipsX : Valeur à convertir en Twips
' Renvoie la valeur convertie en Pixels
'---------------------------------------------------------------------------------------
Public Function TwipsToPixelX(pTwipsX As Long) As Long
    Static Mult As Long
    Dim Hdc As Long
    If Mult = 0 Then
        Hdc = GetDC(0)
        Mult = 1440 / GetDeviceCaps(Hdc, LOGPIXELSX)
        ReleaseDC 0, Hdc
    End If
    TwipsToPixelX = CLng(pTwipsX / Mult)
End Function
 
'---------------------------------------------------------------------------------------
' Convertit les Twips en Pixels sur l'axe vertical
'---------------------------------------------------------------------------------------
' pTwipsY : Valeur à convertir en Twips
' Renvoie la valeur convertie en Pixels
'---------------------------------------------------------------------------------------
Public Function TwipsToPixelY(pTwipsY As Long) As Long
    Static Mult As Long
    Dim Hdc As Long
    If Mult = 0 Then
        Hdc = GetDC(0)
        Mult = 1440 / GetDeviceCaps(Hdc, LOGPIXELSY)
        ReleaseDC 0, Hdc
    End If
    TwipsToPixelY = CLng(pTwipsY / Mult)
End Function
 
'---------------------------------------------------------------------------------------
' Positionne le formulaire pForm par rapport au contrôle pControl
'---------------------------------------------------------------------------------------
Public Sub PositionForm(pForm As Access.Form, pControl As Access.Control)
    Dim lParentForm As Access.Form
    Dim lPt As PointAPI
    Dim lRect As RectAPI
    Dim lScreenRect As RectAPI
    Dim lScrWitdh As Single, lScrHeight As Single
    On Error GoTo Gestion_Erreurs
    ' Vérifie que le formulaire est en fenêtre indépendante
    If Not pForm.PopUp Then
        MsgBox "Le formulaire à positionner doit être en fenêtre indépendante" & _
                    vbCrLf & "(onglet Autre dans les propriétés du formulaire)", vbInformation
        SetWindowPos pForm.hwnd, 0, 0, 0, 0, 0, SWP_NOZORDER Or SWP_NOMOVE Or SWP_NOSIZE Or SWP_SHOWWINDOW
        Exit Sub
    End If
    ' Formulaire parent
    Set lParentForm = pControl.Parent
    ' Remonte jusqu'au formulaire si contrôle dans onglets
    If TypeOf lParentForm Is Page Then
        Do
            Err.Clear
            Set lParentForm = lParentForm.Parent
            If Err.Number <> 0 Then Err.Clear: Exit Do
        Loop
    End If
    ' Lit la taille du formulaire à positionner
    Call GetWindowRect(pForm.hwnd, lRect)
    lRect.Right = lRect.Right - lRect.Left + 1
    lRect.Bottom = lRect.Bottom - lRect.Top + 1
    ' Lit la taille de l'écran
    SystemParametersInfo SPI_GETWORKAREA, 0, lScreenRect, 0
    lScrWitdh = lScreenRect.Right - lScreenRect.Left + 1
    lScrHeight = lScreenRect.Bottom - lScreenRect.Top + 1
    ' Position du contrôle de positionnement
    lPt.x = TwipsToPixelX(pControl.Left + lParentForm.CurrentSectionLeft)
    lPt.y = TwipsToPixelY(pControl.Top + pControl.Height + lParentForm.CurrentSectionTop)
    ClientToScreen lParentForm.hwnd, lPt
    Set lParentForm = Nothing
    lRect.Left = lPt.x
    lRect.Top = lPt.y
    ' Doit tenir dans l'écran
    ' Si déborde à droite => décale le formulaire pour qu'il s'affiche entièrement
    If lRect.Left + lRect.Right > lScrWitdh Then
        lRect.Left = lScrWitdh - lRect.Right
    End If
    ' Si déborde en bas => affiche le formulaire au-dessus du contrôle
    If lRect.Top + lRect.Bottom > lScrHeight Then
        lRect.Top = lRect.Top - TwipsToPixelY(pControl.Height) - lRect.Bottom
    End If
    ' Repositionne le formulaire
    Call SetWindowPos(pForm.hwnd, 0, lRect.Left, lRect.Top, lRect.Right, lRect.Bottom, SWP_NOZORDER Or SWP_NOSIZE Or SWP_SHOWWINDOW)
    On Error GoTo 0
    Exit Sub
Gestion_Erreurs:
    MsgBox "Error " & Err.Number & " (" & Err.Description & ") dans la procédure PositionForm"
 
End Sub

IX. Téléchargement

La base de données au format Access 2000 se trouve ici.

X. Remerciements

Merci à foster53 qui m'a expliqué une partie de l'histoire qui précède l'achat des côtes d'agneau au supermarché.

Merci à Jean-Damien Gayot qui a amélioré la qualité du code.

Merci à Malick Seck (milkoseck) pour la correction orthographique.

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   


Un mâle « fictif » en cas d'insémination artificielle ou lors de l'achat d'une brebis déjà pleine.

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2015 Claude Leloup. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.