Les échanges de données - Import/Export


1 - Introduction               

De plus en plus, les applications échangent des données, et les SGBD n'y font pas exception. 
Il y a bien sûr le fameux "copier-coller", qui marche en de nombreuses occasions. 
Mais dans des cas plus difficiles ou plus spécifiques, il faut recourir à des opérations d'importation ou d'exportation. 
C'est pourquoi, dans les menus des applications, à la rubrique "Fichier", on constate de plus en plus souvent la présence des fonctions "Importer..." et/ou "Exporter...".               
Les BDD sont des réservoirs à données. Ces données ont peut-être été saisies au clavier, mais la saisie manuelle est coûteuse, et le risque d'erreur est toujours présent. 
Chaque fois que cela est possible, on saisit les données à l'aide de capteurs reliées à des ordinateurs (appareils de mesure, lecteurs de codes barres, scanners, etc.), avant de les importer dans une base.            
De plus, on constate une dématérialisation croissante des données échangées entre les entreprises. Pour les opérations commerciales récurrentes, les bons de commande et les factures imprimés vont peu à peu disparaître au profit de transmissions directes via Internet (cela s'appelle le "e-procurement"). 
Toutes les données résultant de ces transactions aboutiront dans des BDD par importation.              
Il est bien rare que, dans une entreprise d'une certaine taille, toutes les données soient stockées dans une seule et même BDD (et ce ne serait peut-être pas judicieux de le faire -- il y a des discussions passionnées sur ce sujet). 
On est donc fatalement amené à transférer des données d'une base à une autre. 
Le cas échéant, il peut être intéressant de transférer des objets (requêtes, formulaires, états, macros, etc.), c'est à dire des structures et non plus des données. 
Enfin, en cas de changement de matériel et/ou de logiciel, on peut être amené à transférer une base entière d'un système informatique à un autre.    
Certains échanges, bien sûr, peuvent être très difficiles à réaliser (entre des systèmes informatiques n'utilisant pas le même système d'exploitation, par exemple), voire même impossibles. 
Les divers SGBD que l'on trouve sur le marché sont plus ou moins ouverts, et l'étude de l'import/export est donc très spécifique du système utilisé. 

2 - L'importation de données de type texte      

Les données que l'on veut importer dans une BDD se trouvent souvent dans de simples fichiers texte. Ces derniers présentent en effet trois avantages déterminants :                      
  1. on les génère très facilement ;
  2. leur poids est modeste, parce que les balises de mise en forme sont absentes ;
  3. les ordinateurs peuvent les lire aisément, par suite de l'absence d'un format propriétaire.

Les tableaux n'existant pas dans les fichiers texte, les données d'un même enregistrement sont rassemblées sur une même ligne (nous supposerons ici que c'est toujours possible). 
Le passage d'un champ à l'autre est repéré par un caractère particulier réservé à cet effet (espace, point virgule, etc.) et appelé caractère de séparation, ou par une tabulation. 
La figure ci-dessous représente un exemple d'une telle disposition, où l'espace sert de caractère de séparation.       

Groupe X - Magasin Y
Date : 28/12/2002
Date Heure Caisse Produit Quant. Prix Total
28/12/2002 9:02:31 03 C-168324 1 24,95 24,95
28/12/2002 9:02:35 02 P-2896 3 13,55 40,65
28/12/2002 9:02:41 02 X-12709 1 6,90 6,90
etc......

A la fermeture du magasin, le fichier texte contenant le détail des ventes de la journée est envoyé (via un réseau de transmission de données ) au centre de traitement informatique du groupe, où il est importé dans une base de données. 
Le lendemain matin, le patron trouvera sur son bureau une synthèse des résultats de la veille, générée de manière entièrement automatique...  
Commençons, plus modestement, par importer manuellement un tel fichier dans Access. 
Mais avant de commencer, il faut que nous décidions si nous importons dans une table existante, ou si nous laissons au système le soin d'en créer une

Nous conseillons vivement la première solution, et ce pour deux raisons :             
  • on règle mieux les propriétés des champs dans la grille de création d'une table que dans l'assistant d'importation ;
  • importer dans une table existante revient à réaliser une requête Ajout (les nouvelles données viennent s'inscrire à la suite des précédentes), et c'est généralement le résultat que l'on recherche.

Donc, avant d'importer, nous créons une table comportant sept champs (Date, Heure, N°_caisse, Code_produit, Quantité, Prix_unitaire, Prix_total), dotés des types de données et des propriétés adéquats, et en évitant les espaces dans leurs noms.          
Nous lançons ensuite l'assistant "Importation de Texte" via "Fichier > Données externes > Importer...". 
Il faut d'abord préciser l'extension du fichier à importer et son chemin. 
On notera au passage la liste des formats qu'Access peut importer (outre le sien propre) : dBase, Excel, HTML, Outlook, Lotus, Paradox, texte, XML et les formats des SGBD respectant l'interface ODBC (Open DataBase Connectivity). Cette interface, créée par Microsoft en 1993, permet à presque tous les SGBD de communiquer lorsqu'ils sont installés sous Windows (il faut cependant que le pilote ODBC correspondant existe).      
L'assistant démarre et nous conseillons de cliquer tout de suite sur le bouton "Avancé...". 
La fenêtre "[Nom du fichier] Spécification d'importation" s'ouvre, qui nous permet de régler tous les détails de l'importation :         
  • Format du fichier : le fichier est-il "délimité" ou de "longueur fixe" ? Le premier cas correspond à l'usage d'un caractère de séparation, le second à une tabulation. Dans le cas présent, la réponse est "délimité" ;
  • Séparateur de champ : il faut indiquer au système quel est le caractère séparateur. Dans le cas présent, la réponse est "space" ;
  • Délimiteur de texte : pour différencier les champs de texte des champs numérique, on place parfois le texte entre des guillemets simples ou doubles. Dans le cas présent, la réponse est "aucun" ;
  • Dates, heures et nombres : dans le cas présent, nous laissons les valeurs par défaut ;
  • Informations sur le champ : ces informations (nom, type de données, indexation) doivent correspondre avec celles de la table dans laquelle nous allons importer. Le système propose de ne pas importer le contenu de certains champs ("sauter"), ce qui rend service dans certains cas.

Avant de quitter cette fenêtre, nous devons enregistrer toutes les informations qu'elle contient en cliquant sur le bouton "Enregistrer sous..." et donner un nom au format d'importation personnalisé que nous venons de créer.       

Nous poursuivons avec l'assistant. Nous ne cochons pas "Première ligne contient les noms des champs" pour deux bonnes raisons : ce n'est pas vrai, et les noms des champs sont déjà déterminés puisque nous importons dans une table existante -- ce que nous indiquons à l'étape suivant, en précisant le nom de la table (liste déroulante). 
Nous cliquons sur "Terminer", et le système nous prévient que toutes les données n'ont pas été importées avec succès. La table que nous avions préparée se trouve ainsi remplie :     

Résultat de l'importation

Les données des trois premières lignes du fichier texte n'ont pas pu être importées, parce que leur type de données était incompatible (seul "Produit" est passé entre les mailles). 

Une table contenant les erreurs d'importation a d'ailleurs été créée, dont voici le contenu :       


Ces erreurs ne se seraient pas produites si nous avions éliminé les trois premières lignes du fichier avant de l'importer. Il faut cependant bien voir que si l'on importe un fichier texte de plusieurs centaines de milliers de lignes, la probabilité de rencontrer quelques lignes erronées n'est pas tout à fait nulle. 
Une coupure de courant, un incident nécessitant le redémarrage de l'ordinateur, une machine débordée qui écrit comme elle peut dans son fichier journal, un petit bug dans le logiciel... et voici créée une ligne qui ne s'importera pas correctement. 
Mais la présence d'une à quelques lignes dans la table des erreurs d'importation ne constitue pas un drame. 
On peut éliminer facilement les enregistrements déficients de la table (dans laquelle s'est faite l'importation) à l'aide d'une requête suppression, le critère étant que l'un des champs au moins n'est pas renseigné (Est Null), alors qu'il devrait normalement l'être.     
Lorsqu'on importe régulièrement des données possédant la même structure, on accélère considérablement la procédure en réutilisant le format d'importation. 
Pour ce faire, il faut se rendre tout de suite dans la fenêtre des spécifications d'importation, cliquer sur le bouton "Paramètres...", et choisir le bon format. 
Toutes les données correspondantes s'inscrivent d'elles mêmes dans la fenêtre.   
On peut encore aller plus vite en automatisant l'importation à l'aide d'une macro, comme nous le verrons au chapitre suivant.         

3 - L'importation de données du web   

On trouve de tout sur le web, y compris des tableaux de données sur les sujets les plus divers. Il peut être utile de récupérer ces données dans un SGBD, ne serait-ce que pour effectuer des requêtes. L'assistant d'importation d'Access reconnaît les tableaux dans une page web, et en dresse la liste. 
La plupart de ces tableaux servent uniquement à la mise en page, et il faut trouver dans la liste quel est le tableau qui contient les informations à importer.                 
A titre d'exemple, nous allons importer une liste d'imprimeries dont le nom commence par un A, et qui se trouve dans les pages de liens imprimerie du CERIG (variante sans cadres). 
Le première opération consiste à télécharger la page en question et à l'enregistrer sur le bureau de l'ordinateur, grâce à la fonction "Enregistrer sous..." du navigateur.       
La seconde opération consiste à lancer l'assistant d'importation, en lui indiquant la page HTML. L'assistant dresse une liste de 11 tableaux, dont seul le huitième contient l'information désirée. 
La suite des opérations se poursuit comme précédemment, mais nous laissons cette fois au système le soin de créer la table correspondante. 

La figure ci-dessous en représente les premières lignes.   

Table importée du web

Si l'on examine les propriétés de la table ainsi créée, on s'aperçoit que, pour les champs de type texte (Ville, Activité) le système réserve automatiquement la place maximale (255 caractères), même si aucune des chaînes de caractères importées n'atteint cette taille. 
On peut toujours corriger après coup, mais on court le risque de tronquer certaines informations. Si l'on importe dans une table existante, et qu'une chaîne est trop longue pour le champ, elle sera là encore tronquée, mais le fait sera signalé dans le fichier des erreurs d'importation.     

4 - L'importation d'objets           

Tous les objets d'une BDD gérée par Access peuvent être importés dans une autre base gérée par le même SGBD : tables, requêtes, formulaires, états, macros, modules
Mais cela ne veut pas dire qu'ils fonctionneront à coup sûr après importation. 
Une requête, par exemple, est basée sur une ou plusieurs tables ou feuilles de données. 
Si nous importons la requête, mais que l'une des tables manque, la requête ne peut pas fonctionner, et le système nous en avertira.                  
Il arrive souvent que l'on ne s'intéresse qu'à une petite partie d'une grande base de donnée, par exemple une semaine dans les opérations d'une année. 
On a alors intérêt à créer des tables réduites à la semaine en question, puis à les importer dans une nouvelle base avec tous les autres objets. 
On pourra effectuer les mêmes opérations que sur la base de départ, mais avec 52 fois moins de données, ce qui va bien accélérer les opérations.            
Pour voir fonctionner l'importation d'objets, nous suivons de nouveau le chemin "Fichier > Données externes > Importer...". 
Nous indiquons au système un fichier Access (.mdb), et la boite de dialogue suivante s'ouvre.   

Importation de données et d'objets dans Access

L'examen détaillé de cette boite révèle que :  
  • tous les objets sont importables (voir les onglets) ;
  • en ce qui concerne les tables, on peut importer la structure seule ("Définition uniquement"), ce qui correspond à une table vide, ou la structure et les données ("Définition et données"). Nous retrouvons là le double aspect de l'objet table, sur lequel nous avons déjà insisté ;
  • le même choix s'applique aux requêtes. Nous pouvons importer la structure seule ("Comme des requêtes"), ou la structure et le résultat ("Comme des tables").

Lorsque tous les objets désirés ont été sélectionnés (en cliquant dessus -- un nouveau clic désélectionne), on valide par "OK", et l'importation s'effectue.   

5 - L'exportation             

Dès qu'un objet de la base (ex : table) est sélectionné, la fonction "Fichier > Exporter..." devient active, et l'on peut se livrer aux opérations inverses de celles décrites ci-dessus.                   

L'exportation d'une table sous forme d'un fichier texte délimité peut servir de dernier recours pour transférer des données d'une base à une autre, lorsque tous les autres moyens ont échoué. L'opération d'exportation est sans douleur, il suffit d'indiquer au système le caractère de séparation que l'on veut utiliser.            
L'exportation d'un objet d'une base Access vers une autre base Access ne pose pas de problème particulier. Si l'objet est une table, le SGBD demande si l'on veut exporter la structure seule, ou la structure et les données ensemble.         
L'échange de données entre Access et Excel est très aisé, et souvent pratiqué. Certains utilisateurs trouvent commode de commencer une recherche d'information dans Access, et de la terminer dans Excel. Il faut dire que la plupart des utilisateurs sont plus à l'aise dans le second logiciel que dans le premier. 
Mais faut également reconnaître que la mise en forme finale des données avant impression est plus facile à réaliser dans une feuille de calcul d'Excel que dans un état d'Access.            
L'exportation des données des BDD vers le web prend de plus en plus d'importance. 
On distingue :   
  • les pages web statiques, c'est à dire générées d'abord depuis une base de données, puis mises en ligne sur un serveur web ;
  • les pages web dynamiques. Elles sont générées à la volée par un script côté serveur à partir de données résidant dans une base de données, juste avant d'être envoyées au client internaute.

Les deux types de pages ont leurs mérites et leurs inconvénients, et leurs applications sont distinctes ; nous n'entrerons pas dans une discussion à ce sujet. 
Précisons qu'Access ne permet pas de créer des pages dynamiques, et que son mode de création de pages statiques est fort médiocre. L'opération n'est pas paramétrable, et le code HTML obtenu n'est pas fameux. 
Pour faire communiquer une BDD (gérée sous Access) et le web, on utilise généralement du logiciel tierce partie.

6 - Conclusion  

Les échanges d'information (données et objets) entre BDD sont plus ou moins faciles suivant les cas envisagés. De ce point de vue, Access est un SGBD relativement ouvert, qui reconnaît plusieurs formats.                
Les échanges de données et d'objets entre bases gérées par Access sont très aisés. L'importation de données en provenance de fichiers texte ou HTML est bien gérée par Access. L'exportation -- en particulier vers le web -- est médiocre, c'est un point faible de ce SGBD.

Maîtriser les Etats chap.01

Les états

1 - Introduction               

Dans une base de données, l'objet état est utilisé pour mettre en forme les données destinées à être imprimées.
Lorsque la matérialisation de données issue d'un SGBD présente un caractère répétitif, et plus encore lorsqu'il est envisagé d'automatiser cette opération, le recours à un état constitue la meilleure solution. A ce titre, l'état constitue donc le troisième objet des SGBD par ordre d'importance décroissante, après les tables et les requêtes.                   
Mais la création d'un état qui présente correctement les données imprimées est souvent une opération longue et quelque peu fastidieuse.
C'est pourquoi l'état n'est pas toujours considéré comme indispensable, et il existe deux façons de s'en passer. 
Première solution.
Nous pouvons imprimer directement une table ou une feuille de données, à condition de limiter considérablement nos ambitions en matière de présentation.
Nous sommes maîtres de la largeur des colonnes (ne pas lésiner sur ce point, sinon l'information risque d'être tronquée), de la couleur de fond de cellule, de la taille et du type de la police, et c'est à peu près tout.
Le SGBD pagine, affiche la date et le nom de la table (ou de la feuille de données), et met en page à sa façon -- c'est à dire qu'il commence en haut et à gauche, tout simplement.
Imprimer directement une table ou une feuille de données est une solution de dépannage, mais ce n'est pas vraiment le moyen de réaliser un document bien présenté.             
Deuxième solution.
Une table créée dans Access et dans d'autres SGBD fonctionnant sous le système d'exploitation Windows peut facilement être exportée vers un tableur, et en particulier vers Excel qui est le plus utilisé.
Dans un tableur, la mise en page avant impression est facile et intuitive, et nous disposons là d'un bon moyen pour obtenir un imprimé correctement présenté.
L'exportation vers Excel des résultats d'une requête constitue une technique de plus en plus utilisée, non seulement pour mettre en forme des données avant impression, mais aussi pour profiter des diverses fonctions qu'offre le tableur.
L'opération est particulièrement facile si nous nous trouvons dans Access : la table à analyser ou à imprimer étant sélectionnée, nous cliquons dans le menu sur "Outils", puis sur "Liaisons Office"et enfin sur "Analyse avec Microsoft Excel".
Le tableur s'ouvre, et la table y est aussitôt exportée. De plus, un fichier au format Excel est enregistré sur le bureau.             

Un état est pratiquement toujours construit sur le résultat d'une requête, et ce pour les raisons suivantes :  

  • les bases de données contiennent souvent des quantités considérables d'information, et il n'est pas question de tout imprimer. Il faut donc commencer par sélectionner l'information particulière que l'on veut reproduire avant d'imprimer ;
  • dans une BDD relationnelle, l'information est répartie dans des tables multiples, et il faut la rassembler avant de l'imprimer. On peut, cependant, introduire dans un même état des champs provenant de plusieurs tables, à condition que ces dernières soient liées par des relations ;
  • on peut désirer que l'information imprimée se présente dans un certain ordre. Il faut donc opérer un tri plus ou moins complexe avant d'imprimer. Ceci dit, on peut également demander un tri complexe (jusqu'à quatre niveaux) lors de la création de l'état.
Bien qu'il ne soit pas question, en général, d'imprimer la totalité du contenu d'une BDD, un état s'étale souvent sur plusieurs pages. C'est le SGBD qui se charge de gérer les sauts de page (si l'utilisateur ne donne pas d'instructions particulières à ce sujet), d'imprimer l'en-tête et le pied de chaque page.
L'en-tête de la première page, et la fin de la dernière page, sont généralement différents de ceux des autres pages.           
  
Signalons au passage que, si vous utilisez Access 2002 comme SGBD, Windows XP comme système d'exploitation, et si vous n'êtes pas administrateur de votre machine, un bug peut faire capoter la création de l'état en fin d'opération.

Si vous vous trouvez dans ce cas, prévenez l'administrateur de votre service informatique, et priez le ciel pour qu'il résolve le problème.

2 - Les préliminaires      

La finalité de l'état étant la réalisation d'une sortie imprimée, il est indispensable d'indiquer au SGBD :              

  • l'imprimante utilisée ;
  • la taille de la zone imprimable, c'est à dire celle du papier, diminuée de celle des marges.
Nous rencontrons ici l'une des différences importantes qui existent entre l'état et le formulaire : le premier opère dans une zone imprimable, le second dans une fenêtre de l'écran du moniteur.           
L'imprimante.
Le SGBD construit l'état en fonction des caractéristiques de l'imprimante par défaut. Si vous utilisez un poste de travail sur lequel aucune imprimante n'a été déclarée, vous allez au-devant de bien des ennuis (lenteur, plantage...). Vérifiez donc ce point avant d'entreprendre la création d'un état.                     
La zone imprimable.
Ensuite, le SGBD tient compte des options que vous avez choisies -- ou, plus généralement, conservées par défaut -- en ce qui concerne la taille du papier (A4, sauf exception) et les marges d'impression.
Si vous manquez de place en largeur -- ce qui est souvent le cas lorsqu'un état est présenté en colonnes -- vous avez intérêt à réduire les marges à gauche et à droite.
Mais attention ! vous devez effectuer cette opération avant de commencer à construire votre état. Une fois ce dernier créé, les changements de marge que vous effectuez sont sans effet sur lui.
      
Dans Access, pour régler les marges, cliquez dans le menu sur "Outils", puis "Options..." : la fenêtre "Options" s'ouvre. Choisissez l'onglet "Général" : les quatre marges sont réglées par défaut à un pouce (2,54 cm).
En pratique, 2 cm à gauche et 1 cm à droite suffisent largement. Quelles que soient les valeurs que vous choisissez, elles resteront valables quelle que soit la BDD dans laquelle vous travaillez, tant que vous ne les modifierez pas à nouveau.           
La sélection des données.
Mettez au point la (ou les) requête(s) qui vous permettent de sélectionner les données à imprimer. Si vous avez besoin d'un tri, incorporez-le à ce stade, car les tris que l'on demande au niveau des états ne fonctionnent pas toujours très bien.
Enfin, vous n'êtes pas obligé de créer une table, un état pouvant être construit directement sur le résultat d'une requête.       
La présentation des données.
Il existe deux modes de présentation d'un état :             

  • la présentation tabulaire : les données sont disposées dans des colonnes verticales, comme dans une table. Le nom des colonnes (l'étiquette) figure une seule fois par page. Cette présentation, qui convient particulièrement bien aux données numériques, économise de la place ;
  • la présentation verticale : les données relatives à chaque champ sont imprimées les unes en dessous des autres, le nom du champ étant rappelé à chaque fois. Cette présentation est la seule possible lorsque le contenu de certains champs est volumineux. Elle peut faire l'objet d'un regroupement sur une colonne donnée, si cette dernière contient de nombreux doublons. Elle présente l'inconvénient de requérir beaucoup de place.
Il est bon de réfléchir à la présentation avant de commencer à créer l'état.      
Les barres d'outils. Il en existe deux qui sont spécifiques des états. Elles s'appellent respectivement "Créer un état" et "Mise en forme (Formulaire/État)", et certaines de leurs icônes nous seront indispensables. Pour faire apparaître ces deux barres, nous cliquons sur "Affichage" dans le menu, puis sur "Barres d'outils", et nous cochons le nom de la barre désirée. Par la même occasion, nous demandons l'affichage de la boîte à outils.

3 - La création de l'état

Ouvrons une BDD contenant au moins une table pourvue de données et, dans la fenêtre "Base de données", sélectionnons l'objet "États". Deux options nous sont présentées :                        

  1. Créer un état en mode Création
  2. Créer un état à l'aide de l'Assistant
Les manuels, en général, conseillent d'utiliser l'assistant en toutes circonstances, car créer un état à partir de rien est assez fastidieux. Mais, dans le cas où l'on choisit la présentation tabulaire, et où il y a de nombreux champs, l'assistant conduit à un mauvais résultat, qu'il est ensuite difficile de corriger complètement.
Dans ce cas, il faut confier à l'assistant le soin de créer une partie des champs seulement (en particulier ceux sur lesquels on envisage un regroupement), et utiliser ensuite la fonction "Modifier" pour introduire les autres champs au fur et à mesure que la mise en forme de l'état progresse.
Obtenir un bon résultat lors de l'impression demande une bonne dose de patience.           
Il existe aussi une icône  "Nouveau", qui redonne le mode création et l'assistant, mais propose de plus des fonctions dont l'intérêt est plutôt mince :            

  • État instantané : Colonnes. Cette fonction crée un état en présentation verticale dès que nous lui fournissons le nom de la table ou de la requête. Nous ne sommes pas maître des paramètres, et le résultat est sommaire ;
  • État instantané : Tableau. Cette fonction opère comme la précédente, mais en présentation tabulaire ;
  • Assistant graphique. Cette fonction permet de créer des graphiques, mais leur qualité est très mauvaise. Pour créer un graphique correct, il faut exporter les données vers un tableur ;
  • Assistant étiquette. Comme son nom l'indique, cette fonction permet d'imprimer des étiquettes. Lançons l'assistant, choisissons une table ("Personnes", avec les champs "Nom" et "Prénom"), sélectionnons ses deux champs, ignorons le regroupement et le tri, adoptons la disposition tabulaire, l'orientation portrait et le style "Informel" (valeurs par défaut), donnons un titre à l'état ("Liste des personnes"), et cliquons sur "Terminer". Nous obtenons un état qu'il est souhaitable d'améliorer.      

4 - La structure de l'état              

L'état que nous venons de créer apparaît dans la fenêtre "Base de données" (l'objet "État" étant sélectionné).
Nous le sélectionnons, puis nous cliquons sur l'icône  "Modifier". Une fenêtre s'ouvre, qui nous permet de modifier l'état.                
Procédons d'abord à une petite vérification. Notre imprimante utilise du papier A4 de 21 cm de large, et  nous avons choisi des marges gauche et droite importantes (5 cm) afin de limiter la taille de la figure ci-dessous.
Nous vérifions que la largeur utile de l'état (la partie claire et quadrillée) mesure effectivement 11 cm, comme le montre la figure. Même si nous modifions par la suite les marges dans la fenêtre "Options", celles de notre nouvel état ne varieront pas.      


Nous observons que l'état est divisé en cinq zones :    

  1. En-tête d'état. Cette zone est imprimée en haut de la première page uniquement ;
  2. En-tête de page. Cette zone est imprimée en haut de toutes les pages (à condition qu'elle contienne de l'information) ;
  3. Détail. Ce terme désigne la zone qui s'étend entre l'en-tête et le pied de page. Cette zone permet d'imprimer le contenu de la table (ou de la feuille de données) sous-jacente ;
  4. Pied de page. Cette zone est imprimée en bas de chaque page ;
  5. Pied d'état. Cette zone s'imprime uniquement sur la dernière page, après le détail et avant le pied de page. Par défaut, l'assistant lui attribue une hauteur nulle.
De manière quelque peu schématique, on peut dire que les diverses zones sont utilisées de la manière suivante :     

  • la première zone (en-tête d'état) contient le titre, de telle sorte qu'il n'apparaisse qu'une seule fois, et qu'il se trouve en tête de l'état ;
  • dans une présentation tabulaire, les noms des champs (on les appelle les "étiquettes") sont placés dans la seconde zone (en-tête de page), de manière à être reproduits en haut de chaque page. Dans une présentation verticale, les étiquettes sont regroupées avec les champs correspondants dans la zone "Détail", et l'assistant ne prévoit pas d'utiliser l'en-tête de page ;
  • les champs (on les appelle "zones de texte", ou parfois "contrôles" comme dans les formulaires) sont placés dans la troisième zone (détail) ; leurs valeurs sont imprimées ligne après ligne, tant qu'il reste de la place entre l'en-tête et le pied de chaque page. Le SGBD passe ensuite à la page suivante, et le processus recommence ;
  • dans la quatrième zone (pied de page), le système pagine et inscrit la date. Ces informations apparaissent donc en bas de chaque page.
  • la cinquième zone (pied d'état) contient les résultats de calculs éventuels, ou un message de fin d'état.
Dans la fenêtre graphique de modification de l'état, les zones de texte et les étiquettes apparaissent comme des rectangles contenant du texte.               
On distingue trois catégories de zone de texte :             

  1. la zone de texte dépendante. Son contenu provient soit d'un champ de la table ou de la requête sous-jacente, soit d'une instruction SQL. Les zones de texte dépendantes se trouvent généralement dans la zone "Détail" de l'état ;
  2. la zone de texte indépendante. Son contenu ne provient pas d'un objet de la BDD. On l'utilise pour afficher un texte informatif (exemple : le titre de l'état), une image (exemple : le logo de l'entreprise), ou des éléments de décoration, principalement dans l'en-tête de l'état ;
  3. la zone de texte calculée. Elle contient le résultat d'un calcul (exemples : somme, moyenne, fonctions statistiques, date, page, etc.). Ce résultat est remis à jour chaque fois que les données utilisées dans le calcul sont modifiées. Les zones de texte calculées se trouvent généralement dans les pieds de page ou dans le pied de l'état.
Tout en haut à gauche de la fenêtre de l'application se trouve une liste déroulante baptisée "État". Elle contient la liste des 15 objets qui se trouvent dans la fenêtre de modification de l'état (tableau ci-dessous). La sélection de l'un de ces objets dans la liste entraîne sa sélection dans la page et vice versa.        


5 - La mise en forme de l'état   

Un état étant ouvert en mode "Modification", les outils qui nous permettent de procéder à sa mise en forme sont dispersés à cinq endroits différents. Nous pouvons en effet utiliser :             

  • les icônes des barres d'outils "Créer un état" et "Mise en forme (Formulaire/État)". Nous avons déjà indiqué au paragraphe 2 comment les faire apparaître ;
  • la feuille de propriétés que possède chaque objet de l'état. Pour la faire apparaître, nous sélectionnons l'objet (ex : le titre), nous cliquons sur l'icône    Propriétés", puis nous sélectionnons l'onglet "Format" ;
  • la fenêtre graphique elle-même, dans laquelle il est possible de modifier l'état en tirant ou en glissant-déplaçant à l'aide de la souris ;
  • le menu, par ses rubriques "Format" et "Insertion" ;
  • la boite à outils. Pour la faire apparaître, nous cliquons sur l'icône    "Boîte à outils". Cette boîte est commune aux états et aux formulaires, mais elle est nettement moins utilisée pour les premiers que pour les seconds.
Les barres d'outils.
Nous noterons d'abord que la barre de mise en forme est active lorsqu'une zone de texte est sélectionnée. Cette barre contient les outils usuels du traitement de texte (propriété de la police, alignement du texte, couleur de fond et de premier plan, bordures). Elle contient en outre (tout à fait à gauche) la liste des objets de l'état, liste dont nous avons déjà parlé au paragraphe 4 précédent.
Lorsque nous modifions la présentation d'un état, il nous faut régulièrement vérifier le résultat obtenu, car ce qui s'affiche est souvent différent de ce qui s'observe en mode "Modifier". Pour cela, nous cliquons sur l'icône  "Aperçu" de la barre d'outils "Créer un état".  
Cette barre contient également deux autres icônes fort utiles. L'icône   "Liste des champs" permet de rajouter de nouveaux champs à l'état, par simple glisser-déplacer (de la liste vers l'état). L'icône   "Propriétés" permet d'afficher la feuille de propriétés de l'objet sélectionné dans l'état.        

Ces feuilles de propriétés nous sont fort utiles, car dans leur onglet "Format" nous pouvons :

  • régler la position des quatre coins du rectangle contenant une zone de texte. L'origine des coordonnées correspond au coin situé en haut et à gauche de la zone dans laquelle se trouve la zone de texte ;
  • régler les marges et l'interligne (à l'intérieur de la zone de texte) ;
  • colorer le fond ou le rendre transparent ;
  • régler la bordure (couleur, épaisseur) et l'apparence (3D, ombré, etc.) ;
  • fixer tous les attributs du texte, comme dans un traitement de texte.
Si nous avons affaire à une zone de l'état, la liste des attributs est évidemment plus réduite. 

La fenêtre graphique nous permet d'effectuer de multiples opérations à l'aide de la souris :   

  • modifier la taille des différentes zones qui constituent l'état, en tirant sur la barre qui les sépare, lorsque le curseur prend la forme  d'une croix. Appliquée à la zone "Détail", cette opération a pour effet de modifier l'interligne à l'impression (dans la présentation tabulaire) ;
  • déplacer les zones de texte et les étiquettes, soit séparément, soit en les regroupant par sélection multiple (touche shift enfoncée). Lorsque le curseur prend la forme d'une main ouverte, toutes les zones sélectionnées sont simultanément déplacées. Lorsque le curseur prend la forme d'un index pointé, seule la zone concernée est déplacée. Attention ! ne positionnez pas une zone de texte contre la limite de la zone imprimable, sinon l'imprimante débitera une page blanche pour chaque page imprimée ;
  • modifier la taille d'une étiquette ou d'une zone de texte, en tirant sur les sommets ou les milieux des côtés du rectangle correspondant ;
  • modifier la largeur de la zone imprimable. Réduisez-la si vous le désirez, mais ne l'élargissez pas au-delà de sa taille initiale, même si vous avez réduit les marges entre temps. Sinon, une page blanche accompagnera chaque page imprimée. Un bon conseil : ne touchez pas à la largeur de la zone imprimable.
Le positionnement à l'aide de la souris ne permet pas d'obtenir un résultat précis. Il est donc recommandé de perfectionner le positionnement en réglant les coordonnées dans les feuilles de propriétés. 
Attention ! Si nous plaçons une zone de texte dépendante dans l'en-tête de l'état, seule la première valeur du champ correspondant sera imprimée (parce que l'en-tête est unique). 
Ceci peut être mis à profit pour imprimer une information qui ne varie pas dans la table sous-jacente (une date par exemple).          
Le menu.
Les fonctions de la rubrique "Format" deviennent actives lorsqu'une étiquette ou une zone de texte est sélectionnée.
Elles nous permettent : 

  • d'aligner (plusieurs étiquettes ou zones de texte) ;
  • de régler la taille (au contenu, par exemple) ;
  • de fixer l'espacement horizontal (plus grand ou plus petit) entre étiquettes et/ou zones de texte ;
  • de placer en premier plan ou en arrière plan (une image par rapport à une zone de texte par exemple).
Les fonctions de la rubrique "Insertion" nous permettent :       

  • de numéroter les pages et d'imprimer la date et l'heure (si nous avons créé l'état sans l'aide de l'assistant) ;
  • d'insérer des graphiques, des images ou des objets divers, que nous pouvons ensuite placer où nous voulons dans l'état.
La boite à outils.
Seuls sont réellement utiles : 

  • l'outil "Sélection", qui est présent par défaut lorsque la boite à outils n'est pas affichée ;
  • l'outil "Étiquette", qui permet en fait de créer une zone de texte indépendante ;
  • l'outil "Zone de texte". Lors de l'affichage ou de l'impression de l'état, le SGBD nous demandera de saisir le contenu de cette zone ;
  • l'outil "Image", qui permet d'insérer une image dans l'état ;
  • l'outil "Saut de page". Dans un état en présentation verticale, l'insertion d'un saut de page en bas de la zone Détail permet de n'afficher qu'un seul enregistrement par page (gare à la consommation de papier !) ;
  • l'outil "Sous-formulaire". Les sous-formulaires seront étudiés au chapitre 24 suivant.
Les autres outils -- en particulier ceux qui permettent d'insérer des boutons, des boutons radio, des cases à cocher, des listes, etc. -- n'ont pas d'utilité pour mettre en forme un état qui est, par vocation, destiné à être imprimé.           

6 - Conclusion  

L'état s'avère être un objet utile dans le cas où l'impression de données issues d'une BDD est une opération récurrente.
La création d'un état bien présenté étant une opération consommatrice de temps, il est préférable d'effectuer les impressions occasionnelles à l'aide d'un tableur.
De plus, l'usage d'un tableur est pratiquement obligatoire lorsqu'on veut présenter les données sous forme d'un graphique.           
Les recommandations qui s'appliquent aux arts graphiques en général sont également valables pour les états en particulier.
Il ne faut pas abuser des images, des fonds colorés, des polices exotiques et des présentations tarabiscotées.
La simplicité, la clarté et la lisibilité priment.

Maitriser le SQL chap.05

Les autres requêtes en SQL

1 - Introduction               

Nous avons déjà consacré quatre chapitres au langage SQL. Il nous reste à traiter trois types de requête :

  1. la suppression
  2. la mise à jour
  3. l'ajout
Pour créer des exemples, nous utiliserons la table suivante, intitulée "Table1" :            
Nom      Prénom
Chose   Jules
Machin Pierre
Truc       Patrick
Pouf      Renée
Attention ! Toutes les requêtes que nous allons utiliser modifient les tables auxquelles elles s'appliquent. Il est donc vivement recommandé de créer une copie de la table avant d'exécuter la requête.    
   

2 - La suppression          

Rappelons qu'une requête de suppression opère sur une table, dont elle supprime les enregistrements (ou lignes) répondant à un ou plusieurs critères.                 
En SQL, c'est la commande DELETE qui permet de supprimer des lignes dans une table. La clause WHERE permet d'exprimer les conditions (critères) de cette suppression.         
Pour supprimer la dernière ligne de la table "Table1", nous créons la requête SQL suivante :   
DELETE Table1
WHERE Nom="Pouf";
Mais le SGBD Access n'accepte pas cette syntaxe. Si nous créons la requête de suppression dans l'interface graphique, sa traduction en SQL donne :            
DELETE Nom
FROM Table1
WHERE Nom="Pouf";
Cette syntaxe fonctionne. L'enregistrement relatif à Renée Pouf disparaît effectivement de la table "Table1" quand nous exécutons la requête SQL ci-dessus, comme le montre la figure suivante :            
Mais cette syntaxe manque de logique. Ce n'est pas dans le seul champ "Nom" que nous opérons une suppression, c'est toute la ligne comportant le nom "Pouf" qui disparait. C'est probablement pour faciliter la correspondance avec l'interface graphique que l'éditeur Microsoft a pris des libertés avec la syntaxe de la requête suppression en SQL, ce qui est regrettable.       
Tout ce que nous avons dit sur l'expression des critères dans les requêtes de sélection s'applique aux requêtes de suppression. En résumé, la syntaxe d'une requête de suppression est :

  
SQL normalisé
DELETE nom de la table
WHERE critères des suppressions;
SQL Access
DELETE nom de champ
FROM nom de table
WHERE critères des suppressions;
Attention ! dans le SGBD Access, l'opération de suppression est irréversible.
La commande ROLLBACK, que l'on trouve dans certains SGBD, et qui annule l'effet d'une requête de mise à jour (tant qu'une commande COMMIT n'a pas rendu cet effet définitif), ne fonctionne pas ici.
Il est donc fortement recommandé de créer une sauvegarde de la table avant de la modifier.    

3 - La mise à jour            

Rappelons qu'une requête de mise à jour modifie le contenu d'une colonne dans une table donnée. Cette modification peut être soumises à des critères, de telle sorte qu'elle ne s'applique pas à toutes les lignes.                   
En SQL, c'est la commande UPDATE qui permet de modifier (ou mettre à jour) les données d'une table.
La clause SET est utilisée pour préciser la modification demandée, et la clause WHERE les conditions d'application (critères) de cette modification.

Supposons par exemple que, dans la table "Table1", nous ayons commis une erreur en saisissant le prénom de M. Chose.
Pour remplacer "Jules" par "Henri", dans la colonne "Prénom", sur la ligne relative à M. Chose, nous utilisons la requête SQL suivante :           
UPDATE Table1
SET Prénom = "Henri"
WHERE Nom="Chose";
L'exécution de cette requête modifie la table "Table1" comme suit :   


Attention ! dans le SGBD Access, l'opération de mise à jour est irréversible. Il est donc fortement recommandé de créer une sauvegarde de la table avant de la modifier.
Tout ce que nous avons dit sur l'expression des critères dans les requêtes de sélection s'applique aux requêtes de mise à jour. La syntaxe générale d'une requête de mise à jour est :     
UPDATE nom de la table
SET nom de la colonne = nouvelle valeur
WHERE critères de la modification;
Exemple : pour augmenter de 20 % tous les prix contenus dans la colonne "Prix" d'une table intitulée "Table2", nous utilisons la requête ci-dessous. 
On notera qu'il n'est pas nécessaire, pour évoquer le contenu du champ "Prix", de placer son nom entre crochets.              
UPDATE Table2
SET Prix = Prix*1.2;
La requête de mise à jour permet aussi d'effacer le contenu d'une ou plusieurs cellules, par utilisation de la valeur Null.
Par exemple, la requête SQL suivante efface le prénom (Patrick) de M. Truc :
UPDATE Table1
SET Prénom = Null
WHERE Nom="Truc";
Remarque : si nous supprimons la clause WHERE dans la requête précédente, et si nous l'exécutons, tous les prénoms sont effacés, et non plus seulement celui de M. Truc.

4 - L'ajout (ou insertion)             

Rappelons qu'une requête ajout permet d'insérer (totalement ou sélectivement) une table dans une autre.
En SQL, c'est la commande INSERT INTO qui est utilisée.               
Pour bâtir un exemple, nous créons la table "Table3" avec les deux champs suivants (du type de données "texte") : 
Col1       Col2
Titi          Noëlle
En SQL, l'insertion de la table "Table1" dans la table "Table3" s'écrit :    
INSERT INTO Table3 ( Col1, Col2 )
SELECT Nom, Prénom
FROM Table1;
Grâce à cette syntaxe, le SGBD sait que les données du champ "Nom" de la table "Table1" vont dans le champ "Col1" de la table "Table3", et les données du champ "Prénom" de la table "Table1" dans le champ "Col2" de la table "Table3".
Il faut bien sûr que les types de données soient compatibles.
Par exemple, on peut introduire une date dans un champ texte, mais l'inverse est généralement impossible.
Il faut aussi faire attention à la façon dont on fait correspondre les champs.
Il n'est pas nécessaire qu'ils se présentent dans le même ordre dans les deux tables, pourvu que la commande SQL indique clairement comment on les met en correspondance.
Il n'est pas nécessaire non plus que les champs qui se correspondent portent le même nom.              
La requête précitée réalise l'opération suivante :           


Si par contre on rédige la commande ainsi :
INSERT INTO Table3 ( Col1, Col2 )
SELECT Prénom, Nom
FROM Table1;
  ou ainsi :
INSERT INTO Table3 ( Col2, Col1)
SELECT Nom, Prénom
FROM Table1;
les prénoms iront dans la colonne "Col1" et les noms dans la colonne "Col2".

On peut rajouter un ou plusieurs critères (via la clause WHERE) permettant de sélectionner les enregistrements à ajouter.
La requête ci-dessous, par exemple, ajoutera seulement Chose Henri à la table "Table3".      
INSERT INTO Table3 ( Col1, Col2 )
SELECT Nom, Prénom
FROM Table1
WHERE Nom<"d";

5 - Conclusion  

Nous avons appris à créer des requêtes de suppression, de mise à jour et d'ajout en SQL. Dans le cas particulier du SGBD Access, la syntaxe de la requête de suppression n'est pas très claire. Les requêtes de mise à jour et d'ajout ont par contre une syntaxe qui respecte le SQL normalisé.           
Certains utilisateurs pourront donc trouver utile de basculer en mode SQL pour vérifier, avant exécution, si la requête de mise à jour ou d'ajout qu'ils viennent de créer dans l'interface graphique répond bien à leurs desiderata.

Maitriser le SQL chap.04


Les opérations ensemblistes en SQL

1 - Introduction               

Le langage SQL permet de réaliser sur un groupe de deux tables les trois opérations de base de la théorie des ensembles, c'est à dire :             
  1. l'union
  2. l'intersection
  3. la différence

De ces trois opérations, seule l'union présente vraiment de l'intérêt. Si, dans les exposés relatifs à SQL, on regroupe généralement les trois opérations ensemblistes, c'est pour se conformer à une logique mathématicienne. 
Comme nous le verrons dans la suite de ce chapitre, l'intersection et la différence sont en fait des requêtes multi-tables particulières, que l'on peut réaliser même si l'on ne dispose pas d'une commande spécifique -- ce qui est effectivement le cas lorsqu'on utilise le SGBD Access. 
La requête union, par contre, est quasi irremplaçable : elle seule permet de mettre deux tables bout à bout en leur faisant jouer des rôles identiques, et en éliminant systématiquement les doublons. Certes, la requête ajout permet d'ajouter une table à une autre, mais dans ce cas les deux tables ne jouent pas le même rôle, et l'élimination des doublons -- si elle s'avère nécessaire -- requiert soit la création d'un index multi-champ, soit un traitement ultérieur (regroupement).           
A ce chapitre nous rajouterons un paragraphe concernant le produit cartésien de deux tables, requête qui n'est utilisée que très rarement et dans des cas très spécifiques.     
        

2 - L'union de deux tables          

L'union de deux tables est une une feuille de données (ou une table) contenant chaque ligne de la première table et chaque ligne de la seconde table. 
Les lignes communes aux deux tables ne sont conservées qu'en un seul exemplaire, c'est à dire que l'opération d'union élimine les doublons
Les champs que l'on fait correspondre dans les deux tables n'ont pas besoin de porter les mêmes noms ni de se présenter dans le même ordre -- ni même de posséder le même type de donnée si la transposition est possible (une date en texte, par exemple).                  
Exemple 1. La figure ci-dessous illustre l'opération d'union dans le cas simple où les champs portent le même nom, possèdent les mêmes propriétés, et sont situés dans le même ordre.

Il n'existe pas dans Access d'interface graphique permettant de créer une requête Union. Il faut donc écrire soi-même le code SQL requis. 
Pour ouvrir l'éditeur de requêtes SQL, nous sélectionnons l'objet "Requêtes" dans la fenêtre "Base de données", nous n'introduisons aucune table dans l'interface graphique de définition des requêtes, et nous basculons en mode SQL.            
Si notre base contient les deux tables précitées, nous pouvons exécuter la requête SQL suivante, contenant l'opérateur UNION :     
SELECT nom, prénom
FROM Table1
UNION
SELECT nom, prénom
FROM Table2;
A l'exécution de la requête, nous constatons qu'une feuille de données est créée, qui rassemble le contenu des deux tables, et en élimine les doublons. Si nous enregistrons la requête (sa structure, pas son contenu), Access fait précéder son nom de l'icône    pour rappeler qu'il s'agit d'une requête de type "Union".            
Exemple 2. Les champs mis en correspondance n'ont pas besoin de porter le même nom, comme le montre l'exemple suivant, dans lequel nous avons modifié les intitulés des champs de la table "Table2" :         


La requête union correspondante est représentée ci-dessous. Le SGBD sait que "last-name" correspond à "nom", et "first-name" à "prénom", parce que les champs sont cités dans cet ordre dans les deux clauses SELECT. 
La feuille de données résultante emprunte les noms de ses champs à la première table. 
La présence des crochets traduit le fait que SQL ne tolère pas le tiret dans les noms des tables ni dans ceux des champs (caractère non autorisé).      
SELECT nom, prénom
FROM Table1
UNION
SELECT [last-name], [first-name]
FROM Table2;
Exemple 3. Nous pouvons faire en sorte d'imposer les noms des champs dans la feuille de données résultante pour obtenir, par exemple, le résultat suivant :         
En SQL, la requête s'écrit ainsi :
SELECT nom AS Col1, prénom AS Col2
FROM Table1
UNION
SELECT nom AS Col1, prénom AS Col2
FROM Table2;
Exemple 4. Nous pouvons appliquer des critères de sélection (clause WHERE) aux enregistrements de chacune des deux tables que nous voulons réunir. .
Il faut cependant que nous fassions bien attention à bien définir le même critère dans les deux clauses SELECT. Ainsi, pour exclure les noms commençant par A, B ou C dans le résultat final :    
nous utilisons la requête union suivante :          
SELECT nom, prénom
FROM Table1
WHERE nom>"D"
UNION
SELECT nom, prénom
FROM Table2
WHERE nom>"D";
Exemple 5. Pour faire en sorte que la requête union n'élimine pas les doublons, nous rajoutons l'opérateur ALL après UNION, comme le montre la requête ci-dessous :            
SELECT nom, prénom
FROM Table1
UNION ALL
SELECT nom, prénom
FROM Table2;
La feuille de données obtenue résulte de la simple mise bout à bout des deux tables, sans tri ni élimination des doublons :


Exemple 6. Comment faire en sorte que la requête Union crée une table ? Une des techniques possibles consiste à emboîter la requête union dans une commande d'insertion. 
Le code SQL suivant :       
INSERT INTO Table3
SELECT *
FROM (SELECT nom, prénom
FROM Table1
UNION SELECT [last-name], [first-name]
FROM Table2);
peut être exécuté à condition que la table "Table3" ait été préalablement créée (vide) -- mais cette condition n'est pas requise pour observer le résultat de la requête en mode feuille de données. 
La requête ci-dessus est reconnue par le SGBD Access comme une requête "Ajout" (à cause de la clause INSERT) et, si nous l'enregistrons, son nom apparaît précédé de l'icône   correspondante. 
Le code ci-dessus nous offre un exemple d'emboîtement en SQL.         

Cet aspect didactique mis à part, il est plus simple, quand on opère dans le SGBD Access, de réaliser d'abord la requête union, puis de réutiliser son résultat dans une requête de sélection simple, à laquelle on demande de créer une table.          
Remarque. Si nous tentons de réaliser l'union de deux tables contenant un champ (nommé "essai") de type Mémo, Objet OLE ou Lien hypertexte, nous obtenons le message suivant (rédigé dans le jargon franglais des informaticiens) :             

Alerte de la requête Union

Cela signifie que, dans le SGBD Access, la requête Union ne fonctionne pas sur les champs de type Mémo, Objet OLE et Lien hypertexte. Pour réunir deux tables comportant des champs de ce type sans les perdre, il faut utiliser la requête Ajout.

La requête Union présente un autre défaut : elle est lente à l'exécution, aussi bien programmée soit-elle. Cela provient du fait qu'elle trie et dédoublonne, alors que la requête Ajout se contente de compléter une table avec les données d'une autre. 
A titre d'exemple, sur un PC de qualité standard, il faut environ plusieurs minutes (3-4) pour réaliser l'union de 10.000 enregistrements avec 300.000 autres.             

3 - L'intersection de deux tables             

L'intersection de deux tables est une une feuille de données (ou une table) contenant seulement les lignes communes aux deux tables. Les conditions sont les mêmes que pour l'union.
La figure ci-dessous illustre l'opération intersection :                     
Le code SQL correspondant dépend de la version utilisée. En SQL1, il s'écrit :   
SELECT nom, prénom
FROM Table1
WHERE Table1.nom IN (SELECT nom FROM Table2) AND Table1.prénom IN (SELECT prénom FROM Table2);
Cette syntaxe, qui fait appel à l'emboîtement autant de fois qu'il y a de colonnes, a été simplifiée par l'introduction de l'opérateur INTERSECT en SQL2. 
Le nouveau code s'écrit :   
SELECT nom, prénom
FROM Table1
INTERSECT
SELECT nom, prénom
FROM Table2;
Mais... le SGBD Access ne reconnaît pas l'opérateur INTERSECT. Il affiche un message d'erreur qui, bien entendu, ne correspond pas à la situation (une habitude bien ancrée en informatique).
Seule reste en lice la première syntaxe, qui apparaît de la manière suivante dans l'interface graphique :             
Intersection de deux tables
Comme on peut le constater, il est possible d'utiliser des critères écrits en code SQL dans l'interface graphique. Ma foi, autant utiliser la fenêtre SQL directement !              
Que l'opérateur INTERSECT ne soit pas reconnu par Access n'est pas un drame. Outre les deux commandes SQL déjà citées, nous en imaginer une troisième, qui résulte directement de la définition de l'intersection :      
SELECT DISTINCT Table1.nom, Table1.prénom
FROM Table1, Table2
WHERE Table1.nom=Table2.nom AND Table1.prénom=Table2.prénom;
La présence de l'opérateur DISTINCT est indispensable, sinon tous les enregistrements de l'intersection figurent en double dans la feuille de données.
Le SGBD les écrit deux fois parce qu'il les trouve une fois dans la première table, et une autre fois dans la seconde.         
Le code ci-dessus est représenté ainsi dans l'interface graphique (on vérifie en outre que la propriété "Valeurs distinctes" de la requête vaut "Oui") :  
Intersection de deux tables
Nous pouvons encore traduire l'intersection en utilisant des relations (ou jointures) entre les champs des deux tables. Rappelons qu'une relation créée dans la fenêtre graphique de définition des requêtes possède une existence éphémère, ce que prouve le fait qu'elle n'apparaît pas dans la fenêtre  "Relations".
Pour traduire qu'un enregistrement de la seconde table est identique à celui de la première table, nous utilisons l'opérateur "Est Pas Null".
Dans l'interface graphique, la requête apparaît comme le montre la figure ci-dessous.  
Intersection : utilisation de jointure(s)
La version SQL de cette requête s'écrit :             
SELECT Table1.nom, Table1.prénom
FROM Table1 INNER JOIN Table2 ON Table1.nom = Table2.nom AND Table1.prénom = Table2.prénom
WHERE Table2.nom Is Not Null AND Table2.prénom Is Not Null;

4 - La différence de deux tables              

La différence de deux tables est une une feuille de données (ou une table) contenant les enregistrements de la première table qu'on ne retrouve pas dans la seconde.
Les conditions sont les mêmes que pour l'union.
La figure ci-dessous illustre l'opération différence :                    
Le code SQL correspondant dépend de la version du langage utilisée.
En SQL1, il s'écrit comme pour l'intersection, à ceci près que IN est remplacé par NOT IN :        
SELECT nom, prénom
FROM Table1
WHERE Table1.nom NOT IN (SELECT nom FROM Table2) AND Table1.prénom NOT IN (SELECT prénom FROM Table2);
(dans l'interface graphique de définition des requêtes, "Not In" devient "Pas In" -- un joyeux mélange de français et d'anglais).          
La syntaxe précédente, qui fait appel à l'emboîtement autant de fois qu'il y a de colonnes, a été simplifiée par l'introduction de l'opérateur EXCEPT dans SQL2 (MINUS dans le SGBD Oracle).
Le nouveau code s'écrit :           
SELECT nom, prénom
FROM Table1
EXCEPT
SELECT nom, prénom
FROM Table2;
Le SGBD Access ne reconnaît ni l'opérateur INTERSECT, ni l'opérateur MINUS, et il affiche un message d'erreur.
On peut bien sûr s'en tirer comme pour l'intersection, mais il faut cette fois utiliser la jointure gauche. Voici comment apparaît la requête dans l'interface graphique (où la jointure gauche est représentée par une flèche allant de la première vers la seconde table) :           
Différence : utilisation de jointure(s)
Le code SQL correspondant s'écrit :       
SELECT Table1.nom, Table1.prénom
FROM Table1 LEFT JOIN Table2 ON Table1.prénom = Table2.prénom AND Table1.nom = Table2.nom
WHERE Table2.nom Is Null AND Table2.prénom Is Null;
La jointure gauche est nécessaire parce qu'il faut que le SGBD, lors de l'exécution de la requête, utilise tous les enregistrements de la première table, qu'ils soient ou non présents dans la seconde.
Si nous utilisions la jointure interne, le SGBD n'examinerait que les enregistrements communs, et n'en retiendrait évidemment aucun.
Si nous utilisions la jointure droite, le SGBD utiliserait tous les enregistrements de la deuxième table, mais seulement ceux de la première table qui sont communs, et le résultat serait de nouveau vide.
Le choix du type de jointure vous pose problème ? Essayez les trois types sur un exemple simple, vous trouverez ainsi quel est celui qui donne la réponse juste.

5 - Le produit cartésien de deux tables

Le produit cartésien de deux tables est une feuille de données (ou une table) obtenue en associant tous les enregistrements de la seconde table à chacun des enregistrements de la première.           
Si chacune des deux tables contient un grand nombre d'enregistrements, le résultat du produit est gigantesque.
De plus, il ne présente généralement pas d'intérêt. En général, le produit cartésien résulte d'une étourderie (oubli d'une relation dans une requête multi-table).
La figure ci-dessous illustre l'opération de produit cartésien :    
Le code SQL correspondant s'écrit :       
SELECT Table1.nom, Table2.prénom
FROM Table1, Table2;
En mode graphique, on introduit les deux tables dans la fenêtre "Requête sélection" en veillant bien à ce qu'il n'y ait pas de relation entre elles.
Puis on introduit dans la grille le champ "nom" de la première table, et le champ "prénom" de la seconde. 
Le produit cartésien rend service quand il faut rassembler dans une même table (à une seule ligne) diverses tables ou feuilles de données comportant une seule ligne.
Le produit cartésien fournit alors une table ne comportant qu'une seule ligne. Les tables à une seule ligne résultent généralement de calculs effectués verticalement, tels que comptage du nombre d'enregistrements ou opérations diverses (somme, moyenne, fonctions statistiques) sur les champs numériques ou monétaires.    

6 - Conclusion  

Il est clair que les concepteurs du SGBD Access n'aimaient pas les ensembles. Car si l'opérateur UNION est reconnu (mais inutilisable dans l'interface graphique) par le logiciel, les opérateurs INTERCEPT et EXCEPT (ou MINUS) sont ignorés.
Pour réaliser une intersection ou une différence dans Access, la solution la plus simple consiste à utiliser les jointures (sans se tromper), associées à des conditions sur le Null.
Il faut cependant reconnaître que, des trois opérations ensemblistes, seule la requête Union a vraiment de l'importance.            
Rappelons pour terminer que, dans une requête Union, les deux tables jouent le même rôle, contrairement à ce qui se passe dans la requête "Ajout".
De plus, aucune des deux tables n'est modifiée par l'exécution de la requête, et les doublons sont automatiquement éliminés, à moins que nous ne demandions à les conserver.
La requête union mérite à elle seule que l'on se familiarise un peu avec le SQL.