Leçon 57 : Diviser les données entre 2 tables, utilisation de l'intégrité référentielle, des NuméroAuto et des options de relations, visibilité de 2 tables à la fois avec Access 2000

Temps nécessaire pour suivre cette leçon : Entre une demie-heure et une heure et demie

Pour suivre cette leçon, vous devez avoir suivi les leçons précédentes. Ou plus précisément, vous devez être en possession de la base de données ProFormation.mdb telle qu'elle était à la fin de la leçon précédente. Si vous n'êtes pas certain de l'avoir, vous pouvez la télécharger ici

Aperçu de cette leçon

Dans cette leçon, nous allons voir en détail comment nous sortir de cette situation qui paraît inextricable !

Sommaire

  1. Répartition des données d'une seule table dans deux tables distinctes
  2. Initiation à la problématique de la liaison entre 2 tables
  3. Il est facile de se tromper de champ lors de la liaison entre 2 tables
  4. Ajout d'un champ en NuméroAuto dans la table principale
  5. Rappel de l'intégrité référentielle
  6. Application des options d'intégrité référentielle
  7. Visualisation de deux tables en même temps grâce à Access 2000

Alors, donc, comment fait-on ???

Comme vous avez peut-être fini par le découvrir par vous-même, il est strictement impossible de s'en sortir en créant une seule table : Nous allons devoir séparer les données dans 2 tables. Dans la première table,, nous allons avoir les champs qui n'apparaissent qu'une seule fois par cours : IdentiteProf, DateCours, HeureDebut, HeureFin et Prix. Dans l'autre table, nous allons avoir les identités des élèves.

Vous allez donc mainteannt créer une 2ème table, qui va contenir un seul champ : IdentiteEleve. : . Vous l'appellerez T_Eleve. pas de clé primaire.

Maintenant,, dans l'autre table (T_Cours, vous supprimez le champ IdentiteEleve, car on a suffisamment vu qu'il était impossible à installer dans cette table). Maintenant, nous allons redistribuer les cours suivants :


Répartition des données d'une seule table dans deux tables distinctes

En deux tables, de cette manière, la table T_Cours devient : , et la table T_Eleve se remplit comme ceci :. Et voilà : La table T_cours va se remplir gentiment, et la table T_Eleve se remplira, elle plus rapidement, puisque chaque ligne de cours va générer plusieurs lignes d'élèves. Tout simple, non ?


Initiation à la problématique de la liaison entre 2 tables

Oui, mais là y'a quelque chose qui m'échappe... Comment Access peut-il savoir qui à suivi quel cours ??? Parce que là, dans T_Eleve, il n'y a rien qui nous dit par exemple que les deux élèves que vous avez mis en bleu correspondent au cours Excel donné par M. Hemecépé ?

Ben si, justement puisqu'ils sont bleux, c'est facile à les reconnaître ?

Hè, vous vous fichez de moi, là ! Il sont en couleurs parce que c'est vous qui avez mis de la couleur ! Moi, c'est en noir et blanc que ça apparaît !!!

Ne vous énervez pas, je plaisante. Effectivement, vous avez mille fois raison... Ici c'est facile, on a que quelques enregistrements, mais il FAUT, c'est exact, préciser dans T_Eleve QUEL cours à suivi chacun d'eux. Vous avez une idée de comment on pourrait faire ?

Oui : Dans T_Eleve, je rejoute un champ NomCours, et je le précise, comme ceci : !

Exactement. C'est la bonne réponse !!!

Mais par contre on doit répéter le nom du cours pour chaque élève... Vous qui vouliez éviter la redondance...

Oui, mais maintenant, on a plus vraiment le choix... On n'a rien fait par hasard.


Il est facile de se tromper de champ lors de la liaison entre 2 tables

Et je pense à un truc... Si jamais il a avait un 2ème cours Excel par exemple, avec comme élève Frank Studieux et Carole Zétudes :

...

Eh oui : Y'a un problème : Dans la table T_Eleve, on a l'impression, et Access aussi va le comprendre comme ça, qu'il y a en tout 4 élèves pour les 2 cours Excel, mais rien le permettra de les différencier... QU'est-ce qu'on fait alors ?

Mmmmh... On rajoute dans T_Eleve le nom du prof ! ... Ah non, en plus c'est le même, zut ! Ah voilà, au lieu de mettre le nom du cours, on met la date du cours !

Oui, et si, par exemple, vous organisez un cours de Comptabilité le matin de 9H à 12H et l'après midi un cours de Word de 14H à 17H, ça pourrait très bien arriver !

Bon, ben on met le nom du cours ET la date, et puis voilà !

Non ! Parce que si vous avec un cours Excel le matin et aussi un cours Excel l'après midi du même jour, vous fates quoi ?

Oui mais là vous tirez les situations par les cheveux !

Mais non je ne tire pas les situations par les cheveux, imaginez : Vous organisez un cours Excel par exemple le 15 Novembre au matin, et vous avez 8 places de travail de libre dans la salle de cours, mais 12 élèves se sont inscrits : alors, vous dédoublez le cours : C'est à dire le même cours, avec le même prof, pour le même prix à la même date, avec juste des heures et des élèves différents...

Oh je ne sais plus moi... on rajoute les heures ?

Bon, ça devient compliqué. Nous allons en fait pour simplifier tout ça, ajouter un bon vieux champ NuméroAuto que vous appellerez IDCours. Vous vous rappelez de la leçon 13 ? Nous avions traité un problème ressemblant. Ajoutez donc cette clé primaire comme ceci : , ce qui numérotera automatiquement les cours :


Ajout d'un champ en NuméroAuto dans la table principale

J'ai compris ! C'est ce numéro que nous allons mettre également dans la table T_Eleve !

Oui : Dans T_Eleve, vous allez transformer NomCours en IDCours (Pour que ce soit cohérent au niveau de notre compréhension), et, évidemment ce n'est plus du texte, mais c'est du numérique !

Ce n'est pas du NuméroAuto, comme dans T_Cours ?

MAIS NON ! Réfléchissez une seconde : Le NuméroAuto, c'est pour indiquer un numéro DIFFERENT à chaque ligne, Ici, dans T_Eleve, il va y avoir PLUSIEURS fois le même numéro puisque plusieurs élèves (plusieurs enregistrements) vont suivre le MEME cours (Vont se référer au même numéro de T_Cours). Lancez la table en mode saisie de données.

Aïe, j'ai une erreur : !

Eh oui : Jusque là, le champ NomCours, qui éatit en texte, et contenait du texte, a été transformé en numérique... Il ne supporte pas, alors, il va évidemment tout bousiller... Pas le choix : Répondez Oui : . Maintenant, il n'y a plus qu'à remettre non pas les noms des cours, mais les numéros des cours à la main, allez,. hop, au boulot : :

Mais ce n'est pas pratique du tout !

Non, mais c'est normal, là, c'est parce que nous y allons à tâtons pour bien vous faire comprendre le fonctionnement. Après, vous ferez les choses immédiatement bien.

Mais même ! Si je voulais ajouter un cours ou des élèves, il faudrait jouer avec plusieurs tables, se rappeler des numéros de cours, c'est la galère !

Oui, là, maintenant, oui... C'est comme si vous vouliez habiter dans une maison qui n'a encore ni porte ni toit ni fenêtre... Chaque chose en so temps, nous allons petit à petit rendre cette application tout à fait symtahique avec des états, des sous formulaires, des boutons, etc. mais rien de tout ce luxe n'est possible à implémenter tant que la structure de base, ce que nous sommes en train de faire n'est pas parfaitement conçue et terminée.

OK... vous avez raison, ne mettons pas la charrue avant les boeufs. Je vous écoute, maintenant...

Bien. Maintenant, ajoutez la ligne suivante à votre table T_Eleve : . Y a-t-il quelque chose qui vous choque ?

Ben oui... Il n'y a pas de cours 498 dans la table T_Cours...

Ca vous parait normal ?

Non, pas tellement...

Pas du tout disons plutôt !!!! Qu'est-ce qu'on fait alors ?

On empêche que ce soit possible !

Oui, mais comment ?


Rappel de l'intégrité référentielle

Je ne sais pas...

Z'avez la mémoire courte on dirait : Mais si, rappelez vous : Les relations avec intégrité référentielle, c'était à la leçon 16 : On voulait à tout prix empêcher qu'un client habite un pays qui ne soit pas existant dans la table T_Pays : Eh bien ici, vous allez faire exactement la même chose : Vous allez empêcher que dans la table T_Eleve il y ait un numéro de cours (298 dans notre exemple) qui n'ait pas de correspondance dans T_Cours.

ATTENTION : Pour que l'intégrité référentielle soit possible, il FAUT que le IDCours de T_Eleve soit de MEME type que le IDCours de T_Cours. C'est à dire que si IDCours de T_Cours est en NuméroAuto, il doit en être de même pour IDCours de T_Eleve. Or, comme expliqué plus haut, on a vu que ce n'est pas possible puisque il y a forcément plusieurs IDCours les mêmes dans T_Eleve, c'est logique. Retenez bien ceci : Le NuméroAuto est en fait un Numérique de type ENTIER LONG (C'était à la leçon 4) un peu spécial puisqu'il augmente tout seul. Donc, si dans la table principale (T_Cours) IDCours est NuméroAuto, et que vous vouliez le lier avec intégrité référentielle avec IDCours de la "Sous-table" T_Eleve, IDCours de T_Eleve DOIT être Numérique ENTIER LONG, sinon ça ne marche pas.

Mais si j'avais voulu, dans T_Cours, j'aurais pu donner les numéros de cours moi même plutôt que de laisser faire le NuméroAuto ?

Bien entendu. Et si vous aviez donné des numéros de cours comme WOR01, XL01, CTA02, etc., ce serait donc du texte, et dans T_Eleve, IDCours serait évidemment en texte aussi... Mais bon, quel est l'intérêt de numéroter soi-même les cours... Pusiqu'il y a un NuméroAuto, autant l'utiliser... Mais ceci dit, dans certains cas, vous préférerez réellement utiliser des numéros que vous créerez vous-même.

Compris. Bon, on va créer cette relation avec intégrité référentielle ?

On y va. Attention, parce que c'est toujours le côté laborieux d'Access, c'est qu'il faut que tout soit vraiment nickel-chrome pour qu'il soit possible de la faire. C'est un excellent exercice pour vous, ça ! Allez-y, faites une belle relation comme ceci (La leçon 16 pourra vous aider):

Et si vous n'y arrivez vraiment pas, cliquez ici pour de l'aide.

A partir de maintenant, votre base de données est propre : Il n'est pas possible d'attribuer un cours inexistant à des élèves.

Par contre, il est possible de créar un cours sans élèves, c'est exact ?

Oui, mais ça c'est normal... Le temps d'entrer des élèves dans la T_Eleve, il y aura bien quelques secondes ou les cours existera dans T_Cours, mais sans élèves. Et de toutes façons, rien n'empêche d'avoir un cours prévu, mais auquel personne ne s'est inscrit.

Essayez de créer un enregistreemnt dans T_Eleve concerannt par exemple le cours N° 596. C'est impossible. Il vous donne l'erreur

Ce qui est logique.

Par contre, si vous révisez la leçon 17, vous allez revoir les options des relations. Vous vous rappelez ? Quand on clique 2 fois sur une relation : .

Oui, oui, je me souviens, à l'époque, on avait mis une coche dans "Mettre à jour en cascade les champs correspondants" quand on avait la table T_Pays qui était liée à la table T_Client, et qu'on voulait pouvoir changer l'orthographe d'un pays, qu'il aie automatiquement changer l'orthographe des tous les clients qui venaient de ce pays. Une option très cool d'ailleurs !

Eh bien ici, c'est le même principe. On va se poser la même question : Est-ce qu'on veut, quand on change l'orthographe d'un numéro de cours dans T_Cours, il change automatiquemet l'orthographe de ce numéro de cours dans tous les élèves correspondants. Par exemple, si vous avez un cours Numéro 13, et que vous avez 4 personnes inscrites dans ce cours numéro 13, et que finalement, vous n'aimez pas le 13 parce que c'est un nombre qui porte malheur, alors vous le transformez en 14, est-ce que vous voulez qu'automatiquement, dans T_Eleve, tous ceux qui étaient inscrits au cours 13 voient automatiquement leur numéro de cours transformés en 14 ?

Ah ben oui ! Evidemment ! Sinon, les IDcours ne correspondraient plus !

Ha haaaaaa... C'est quoi déjà, le type de données de IDEleve dans T_Cours ?

Ah ben c'est un NuméroAuto !

Oui, et est-ce que vous pouvez changer la valeur d'un NuméroAuto (leçon 13) ?

Non...

Bon ben voilà... Donc, si vous avez un cours Numéro 13 dans T_Cours, vous ne pouvez de toute façons pas le changer... Donc cette option de relation "Mettre à jour en cascade les champs correspondants" est parfaitement inutile : Que vous la mettiez ou pas, cette coche n'aura aucune incidence dans votre base de données... Autant ne pas la mettre pour éviter les confusions.

Par contre, la 3ème option (Effacer en cascade les enregistrements correspondants) est ici terriblement utile. En effet, lorsque vous désirez effacer un cours, par exemple le cours Excel, numéro 2 , penseriez-vous qu'il serait bien d'effacer en même temps tous les élèves qui en font partie ?


Application des options d'intégrité référentielle

Ah dans ce cas, oui !

Donc, vous mettez la petite coche :

Vous voyez ? ça dépend des cas. Dans la leçon 17, lorsqu'il s'agissait de lier T_Pays à T_Client, nous avons demandé "Mettre à jour en cascade les champs correspondants", mais pas "Effacer en cascade". Cette fois, nous faisons exactement l'inverse. Les options d'intégrités référentielles se définissent donc de cas en cas. Il y a même certains cas plus exceptionnels ou l'intégrité référentielle elle-même n'est pas souhaitée, mais c'est une autre histoire.


Visualisation de deux tables en même temps grâce à Access 2000

Maintenant que les relations sont créées, je vais vous montrer une petite particularité d'Access 2000 seulement. Quittez les relations, et allez dans T_Cours en mode saisie de données : Vous voyez une série de petits + sur la gauche : . Ils vont vous permettre de visualiser directement les élèves inscrits pour chaque cours : Cliquez sur le + du cours N° 2 : Vous avez les 2 élèves de T_Eleve qui sont inscrits à ce cours qui apparaissent (). Bien entendu, si vous cliquez sur le petit -, ça se referme. Vous pouvez même visualiser plusieurs cours. Voici développés le cours 1 et 3 : . Et le plus sympa, c'est que vous allez pouvoir DIRECTEMENT DANS LA TABLE T_COURS, ajouter des nouveaux élèves dans T_Eleve. Je m'explique : admettons que pour le cours Excel Numéro 2, vous voulez ajouter Sabine Concours : Vous développez le cours 2 , et vous écrivez son nom : ... C'est aussi simple que ça. Et quand vous fermez T_Cours pour aller voir ce qui se passe dans T_Eleve, vous constatez que Sabine Concours est maintenant correctement inscrite au cours 2 :

Remarque : Il est possible que suivant la configuration de la structure de votre base de données, Access ne sache pas quelle sous-table vous montrer avec les petits +. Si vous ne comprenez pas bien ce que je veux dire par là, attendez de vous être cassé la tête sur le 2ème exercice de cette leçon, et ça vous sautera aux yeux. Quand vous aurez eu "l'illumination", vous pourrez alors utiliser le menu Insertion/Sous-feuille de données

Oui, mais moi j'ai Access 97... comment dois-je faire ?

Alors, vous, vous allez directement dans T_Eleve, et vous ajoutez à la main 2 - Concours Sabine, tout simplement.

Nous allons nous arrêter là pour cette fois.

Bon... Hem... On peut résumer ?

Dès que nous sommes en présence d'une modélisation du style "Un objet comporte un certain nombre de sous-objets", il n'y a pas de miracle, il est indispensable de séparer les choses en 2 tables : La table "Principale" qui va contenir toutes les information de l'objet principal (Ici, toutes les infos générales concernant le cours : Le prof, la matière enseignée, la date, l'heure de début et de fin, et le prix), et la "sous-table" qui va contenir les infos relatives aux sous-objets de la table principale : Ici, il s'agit d'élèves : Nous metttons dans cette table le nom et le prénom de l'élève. Pour faire le lien entre la table principale et la table de correspondance, nous avons été obligé d'ajouter un champ IDCours dans la table T_Cours, en NuméroAuto, et un IDCours dans T_Eleve, qui lui, sera en numérique Entier long, afin qu'Access puisse savoir quel élève suit quel cours. Pour consolider cette structure, nous avons alors créé une relation avec intégrité référentielle entre IDCours de T_Cours et IDCours de T_Eleve, principalement afin d'éviter que des élèves soient inscrits à un numéro de cours inexistant dans T_Cours. Cette relation possède l'option de suppression en cascade, afin de pouvoir sans problème supprimer un cours entier : Tous les élèves inscrits seront alors également supprimés de la table T_Eleve.

Avez-vous bien compris ?

  1. Lorsqu'on utilise deux tables comme dans cette leçon, l'intégrité référentielle entre ces deux tables est :
    a. Obligatoire
    b. Très recommandée ***
    c. Interdite

  2. Si nous avions eu besoin d'un champ "ElevePresent", en Oui/Non, qui détermine si tel ou tel élève qui s'est inscrit, s'est effectivement présenté au cours, ce champ aurait été placé :
    a. Dans T_Cours
    b. Dans T_Eleve ***

  3. Si nous avions eu besoin d'un champ "PauseMidi", en Oui/Non, qui détermine si ce cours est coupé en deux dans la journée pour laisser le temps aux élèves pour manger, ce champ aurait été placé
    a. Dans T_Cours ***
    b. Dans T_Eleve

  4. Admettons que vous n'ayez pas une salle, mais 3, et qu'il faille déterminer pour chaque cours dans quelle salle il se passe :
    a. Je crée une liste déroulante locale avec comme valeurs "Salle 1", "Salle 2", "Salle 3" dans la table T_Cours ***
    b. Je crée une liste déroulante locale avec comme valeurs "Salle 1", "Salle 2", "Salle 3" dans la table T_Eleve
    c. Je dois absolument créer une 3ème table sur le même principe que ce qu'on a vu dans cette leçon, car en faut, ce serait une salle qui comprend un nombre indéterminé de cours

  5. Si vous vouliez que les élèves puissent ajouter une annotation personnelle sur le cours, de style "Cours très bien structuré", "Je n'ai pas vraiment appris ce que je voulais"... :
    a. Vous créez un champ Mémo dans la table T_Cours
    b. Vous créez un champ Mémo dans la table T_Eleve ***
    c. Vous créez un champ Texte dans la table T_Cours
    d. Vous créez un champ Texte dans la table T_Eleve

Pour voir les solutions, il vous suffit de sélectionner le questionnaire ci-dessus : 3 petites étoiles *** apparaîtront en face des bonnes réponses.

Exercice

2 exercices vous sont proposés. Dans les 2 cas, le nom et le prénom peuvent être réunis en 1 seul champ pour des questions de facilité, le problème n'étant pas à ce niveau. Votre travail se limitera à créer les tables et les relations AVEC intégrité référentielle, ainsi que les données de test proposées.

EXERCICE 1
Vous êtes critique littéraire. Votre travail consiste à critiquer les textes qu'on vous envoie. Pour chaque texte que vous recevez, vous devez avoir le nom et le prénom de l'auteur, le titre du texte en question, l'année ou le texte a été écrit, et vous allez ajouter un certain nombre de commentaires pour chacun d'entre eux. Vous allez donc créer une base de données qui s'appellera Critique.mdb, dans laquelle vous allez stocker les données de test suivantes :

Nom et prénom : Durand Agathe. Titre : "Valse funèbre", Année : 1988
Commentaires :
- Excellente introduction
- Nombreuses fautes de frappe
- Figures de style originales
- Ponctuation parfois incorrecte
- Conclusion en queue de poisson

Nom et prénom : Martins Karl. Titre : "Les oiseaux rouges", Année : 1992
Commentaires :
- Grande richesse de vocabulaire
- Chapitrage bâclé

Attention : Dans ces données de test, les auteurs sont différents, mais il est très possible d'avoir à critiquer plusieurs textes d'un même auteur, ou même, pourquoi pas, 2 auteurs différentes peuvent pondre un texte dont le titre est identique

EXERCICE 2 : attention : Moins simple qu'il n'y parait, réfléchissez bien !!!
Vous êtes responsable d'une agence matrimoniale. Vous créez une base de données ViveLamour.MDB dans laquelle vous allez installer les données suivantes dans une ou deux tables que vous nommerez vous mêmes comme vous voulez. : Le nom et le prénom du candidat, son numéro de téléphone, ses qualités et ses défauts. Voici les données de test que je vous propose d'injecter dans votre exercice :

Nom et prénom : Toubeau Louis, Tél : 11.22.33
Qualités :
- Généreux
- Gentil
- Courtois
- Poli
Défauts :
- Perfectionniste
- Défaitiste

Nom et prénom : Lahargne Marie, Tél : 99.99.99
Qualités :
Elle n'en a pas... Elle est pas près de trouver quelqu'un, celle-ci, avec un nom pareil en plus !
Défauts :
- Egoïste
- Jalouse
- N'aime pas les animaux
- Fumeuse

Attention : Rien n'empêche à ce que si la base de données devient assez grande que des homonymes apparaissent (2 Jean Dupont sont très possibles). Tenez en compte.

Solution de l'exercice 1   |   Solution de l'exercice 2

Si vous n'êtes pas tout à fait certain d'avoir suivi correctement toutes les étapes de cette leçon, vous avez la possibilité de télécharger ici la version de ProFormation.mdb exactement dans l'état ou elle devrait être à la fin de cette leçon.

Avez-vous une question technique concernant cette leçon ? Cliquez ici !
Une remarque sur cette leçon ? Un problème ? Une erreur ? une ambiguité ? Soyez gentil de m'en informer

Et maintenant un petit exercice plus complet : cliquez ici