Vous êtes sur la page 1sur 22

Access : les macros de donnes

http://www.info-3000.com/access/macrodonnee/

Access
Les macros de donnes - Partie 1 : bases
Sommaire

Dans la premire partie de ce didacticiel, nous allons aborder les macros de donnes (Nouveaut d'Access 2010, galement appeles "Macros de table" ou "Triggers"). Bien qu'il ne faut pas les confondre avec les macros traditionnelles (qui existent toujours), j'utiliserai parfois le terme Macro la place de Macro de table dans ce didacticiel. Cette leon ncessite une bonne connaissance d'Access (Tables, champs, relations, macros, requtes, et mme un peu de VBA dans les formulaires) Nous aborderons sommairement la possibilit de crer une historisation des changements effectues dans nos tables, puis, dans la 2me partie, nous crerons un vritable systme d'historisation.

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.

Base de donnes de base Requtes et calculs Trop de mises jour dans les calculs de requtes Historique perdu Programmation VBA dans les formulaires Avantages des macros de table Macro Avant Modification Fonction Si Variables locales Fixation des prix dans les commandes Eviter les mises jour excessives Mises jour slectives Interactions entre les relations et les macros de mise jour Ignorer les erreurs Historisation des suppressions Macro Aprs Suppression Bug dans les champs Mmo Interaction historisation/valeur par dfaut Suivi des modifications Format XML Exemple XML Dlais d'enregistrement Macro Aprs Insertion Journalisation des erreurs USYSApplicationLog Affichage des objets-systme Parcours de tous les enregistrements Instruction PourChaqueEnregistrement Ractions en chane Rcursivit accidentelle Concatnation Liste des macros de table Macros nommes Actions possibles Avant et Aprs les vnements Table ddie aux macros de table

Base de donnes de base


Commencez par tlcharger cette base de donnes. Elle ressemble ceci :

Elle contient deux tables, relies entre elles par IDArticle. Nous disposons d'une part de la liste des articles disponibles la vente ( T_Article) et, d'autre part, des diffrentes commandes passes par les clients (T_Commande.) Il n'y a pas de date de commande, ni de possibilit de commander plusieurs articles dans la mme commande, ni mme de liste droulante pour choisir l'article dans T_Commande, car je voulais une situation simplifie l'extrme pour illustrer le fonctionnement de ces fameuses macros de table..

1 of 22

2/14/2013 09:59

Access : les macros de donnes

http://www.info-3000.com/access/macrodonnee/

Requtes et calculs
Avant d'voquer les macros de table, comparons-les d'autres techniques. Concentrons-nous sur T_Commande : il y a la quantit, mais pas le prix - et donc pas le prix total de la commande (Qte X Prix). Pour obtenir ces informations, une requte s'avre ncessaire. Crez une requte base sur les deux tables T_Commande et T_Article, et disposez les champs comme ceci : Inscrivez le calcul de la commande :

Appuyez sur ENTER - Ca corrige la syntaxe : Remplacez Expr1 par PrixTotal. Excutez la requte :

Trop de mises jour dans les calculs de requte Enregistrez cette requte sous R_CalculPrixCommande, et fermez-l (la requte Bien. Le temps passe, les choses voluent. Augmentons le prix des crayons de couleur ! Dans la table T_Article, majorez le prix des crayons de 1.80 2.10 :
).

Peu aprs cette mise l'index, un certain Daniel Dumoulin dsire commander 50 crayons de couleur rouge : rendez-vous dans la table T_Commande, et crez cette nouvelle commande :

Une fois cette commande enregistre, fermez les tables, et rouvrez votre requte R_CalculPrixCommande :

Historique perdu Cette nouvelle commande est absolument parfaite ... mais ... les prcdentes commandes de crayons sont devenues fausses, tout coup : elles ont t ajustes avec le nouveau prix major ! Nous ne disposons plus d'aucune manire de connatre l'ancien prix qui avait t appliqu ! Cette histoire de calcul dans la requte ne convient donc pas dans ce cas ! Ce qu'il faudrait, c'est que dans T_Commande, nous conservions une copie du prix actuel de T_Article. Faisons-le ! Retournez dans la table T_Commande, et insrez le champ Prix entre IDArticle et Qte :

2 of 22

2/14/2013 09:59

Access : les macros de donnes

http://www.info-3000.com/access/macrodonnee/

Dfinissez-le en format Montaire, et prcisez le format Standard


(Pour viter de voir le symbole montaire),

2 dcimales :

Ce champ est donc un champ tout simple, qui n'effectue aucun calcul automatique. Les macros de table vont nous permettre d'aller automatiquement rechercher le prix de l'article correspondant dans T_Article, et de l'importer dans ce prix de T_Commande. Comment faisait-on dans les versions prcdentes d'Access, quand les macros de donnes n'existaient pas ? On programmait en VBA, via des formulaires !

Programmation VBA dans les formulaires


Regardez l'exemple suivant : j'ai cr un formulaire bas sur T_Commande, et j'ai demand que lorsqu'on met jour le N d'article : 1. VBA ouvre (OpenRecordSet) la table T_Article 2. Recherche (FindFirst) le N d'article du formulaire 3. Copie (Prix = T_Article("Prix")) le prix ainsi trouv dans le champ Prix du formulaire Comme ceci :

Je ne l'explicite pas plus en dtail, car ce n'est pas le sujet de ce didacticiel, mais si vous voulez le tester, tlchargez cette base de donnes, et lancez le formulaire F_ExempleVBA. Ensuite, allez dans n'importe quelle commande - ou crez-en une nouvelle - et inscrivez un N d'article (existant dans T_Article) dans IDArticle. A l'instant ou vous quitterez le champ, le prix de l'article va s'importer et il ne changera pas si, par la suite, vous changez le prix dans T_Article. On se dbrouillait trs bien comme a. Il est mme possible qu'on puisse crer une macro la place du VBA pour effectuer la mme tche, mais je n'ai simplement jamais essay (je trouve plus simple, en tant que programmeur, d'utiliser VBA) Du coup, quel est l'avantage d'utiliser une macro de table pour effectuer une tche similaire ? Avantages des macros de table Les macros de table se trouvant ... dans les tables, on pourra alors effectuer des changements dans la table-mme, et le prix sera correctement import (nous n'aurons plus besoin d'un formulaire juste pour a). Vous me direz qu'une base de donnes Access sans formulaire, c'est quand mme fort rare, je vous le concde ! Ceci dit, il faut savoir qu'on peut malgr tout construire des formulaire bas sur T_Commande, les macros de table s'excuteront aussi en arrire

3 of 22

2/14/2013 09:59

Access : les macros de donnes

http://www.info-3000.com/access/macrodonnee/

plan du formulaire, ce qui vite de le charger de programmation. De plus, si on exporte - ou copie - ces deux tables dans une autre base de donnes, les macros de table vont s'exporter avec, et fonctionneront galement dans la nouvelle base (sauf videmment s'il s'agit d'un export dans l'ancien format de base de donnes MDB, ou si on excute la base de donnes avec Access 2007 puisque les macros de table sont une nouveaut Access 2010).

Macro Avant modification


Maintenant que vous cernez le domaine d'utilisation des macros de table, crons notre premire macro. Elle va tre un peu simplette, mais c'est juste pour montrer le principe : Elle va juste crire "Ca marche" dans le champ commentaire, ds que vous enreistrerez une modification dans un quelconque enregistrement. Ouvrez T_Commande en mode saisie de donnes. Cliquez sur le ruban Table, et sur Avant Modification.

Choisissez DfinirChamp dans la liste : Dans Nom, crivez Remarque, et comme Valeur : "Ca marche" (entre "guillemets", sinon, a ne marche pas):

Fermez l'action de macro en utilisant l'une de ces deux croix, et rpondez Oui la demande de confirmation :

Testez : par exemple, ajoutez un s "Abro", dans la premire commande, puis cliquez sur un autre enregistement pour valider, et regardez : La remarque contient bien Ca marche.

Fonction Si Maintenant, admettons que nous dsirions crire le mot "Quatre" dans la remarque, seulement si nous modifions la commande numro 4. Pour ce faire, retournez dans la macro de donnes (cliquez sur , et glissez

l'instruction Si au dessus de votre instruction existante, comme ceci :

Ensuite, faites glisser l'instruction de modification du champ dans la zone Si, de cette faon :

4 of 22

2/14/2013 09:59

Access : les macros de donnes

http://www.info-3000.com/access/macrodonnee/

Cliquez entre Si et Alors :

, et crivez [IDCommande]=4 :

Cliquez ensuite sur la valeur :

, et crivez "Quatre", puis fermez :

A partir de maintenant, changez ce que vous voulez dans n'importe quel enregistrement de T_Commande, rien ne se passe, sauf si vous changez quelque chose dans la commande N 4 : il crira Quatre dans la remarque l'instant ou vous validerez vos modifications (soit en cliquant sur la petite disquette, soit quand vous appuierez sur CTRL-S, ou que vous changez simplement d'enregistrement).

Variables locales
Etudions ce qu'est une variable locale. C'est une manire de mmoriser une valeur.

Effacez le contenu de votre macro de table, grce aux petites croix :

Ajoutez, en faisant cliquer-glisser les instructions comme avant, l'instruction DfinirVarLocale (TrucMachin, 4000), et DfinirChamp (Prix, TrucMachin - qui vaut donc 4000), comme ceci :

Testez : modifiez n'importe quel enregistrement, et constatez que le prix devient CHF 4'000.00. Remarquez que je n'ai pas encadr la variable locale ni le champs de [crochets]. Plus prcisment, les "guillemets" sont obligatoires, comme on l'a vu plus haut, mais les [crochets] ne le sont que dans le cas o il y a des espaces dans les noms des champs (Si le champ s'tait appel Le prix (Espace entre Le et prix), alors, les [crochets] auraient t indispensables. Vous allez me dire que dans ce cas prsent, la variable locale TrucMachin ne sert rien. Vous avez raison. C'tait juste pour vous montrer comment l'utiliser, car nous allons en avoir besoin ultrieurement.

Fixation des prix dans les commandes


5 of 22 2/14/2013 09:59

Access : les macros de donnes

http://www.info-3000.com/access/macrodonnee/

Passons aux choses srieuses ! Rcapitulons notre demande initiale : Lorsque nous modifions un enregistrement dans T_Commande, nous devons : 1. Ouvrir la table T_Article 2. Chercher le numro d'article correspondant notre numro d'article courant dans T_Commande 3. Copier le prix ainsi trouv dans T_Article, et le coller dans Prix de T_Commande Commencez par effacer toutes les actions de macros existantes, comme tout l'heure avec les croix, puis remplissez les actions comme suit :

Vous avez compris le systme ? 1. On commence par mmoriser l'IDarticle dans la variable VARIDArticle 2. On ouvre la table T_Article, et on y recherche l'enregistrement dont l'IDArticle correspond l'IDArticle de T_Commande (C'est la condition Where) 3. Alors que nous sommes encore dans T_Article (D'o l'importance glisser-dposer DfinirVarLocale l'intrieur du bloc Rechercher un enregistrement, et pas en dessous), nous stockons le prix trouv dans une variable VARPrix 4. Nous allons replacer ce prix dans notre prix de T_Commande, et donc, cette fois nous devons disposer notre DfinirChamp en dessous du bloc Rechercher un enregistrement Testez : Modifiez n'importe quel champ de n'importe quel enregistrement de T_Commande, et constatez son prix qui vient s'installer. Je vous rappelle qu'initialiement, nous avons entrepris tout ce mic-mac uniquement pour que les nouvelles commandes soient pourvues du nouveau prix, sans altrer les prix des anciennes commandes. Effectuons un test complet pour prouver que a fonctionne :

1. Ajoutez une nouvelle commande, comme ceci :

2. Enregistrez-l avec CTRL-S : le prix est bien import : 3. Fermez T_Commande 4. Ouvrez T_Article, et majorez le prix de l'article N2 33.45 : 5. Fermez T_Article (ce qui enregistrera automatiquement le nouveau prix dans T_Article) 6. Rouvrez T_Commande, et constatez que le prix de l'ancienne commande est reste 28.90, ce qui est trs bien 7. Crez une nouvelle commande, pour Eugne Ermenons (Avec un "s" a la fin de Ermenon), aussi pour l'article N2 8. Enregistrez avec CTRL-S : Le nouveau prix actualis de 33.45 a bien t import sur cette commande, mais pas pour les autres commandes antrieures de l'article N2, c'est bien ce que nous dsirions. Eviter les mises jour excessives Par contre, comme vous l'avez constat, nous avons commis une petite faute d'orthographe M.Ermenons. Il s'crit vraiment avec un "s", et pas un "t". Vous me voyez venir ? Si vous corrigez l'orthographe de Ermenont la commande 7, la macro va s'excuter, et transformer 28.90 en 33.45, et a, c'est pas bien ! Ce qui serait bien, ce serait que cette macro ne s'excute que si le prix de l'article n'est Si on reprend l'exemple en VBA dans le formulaire que j'ai montr plus haut, c'est diffrent : la macro ne se dclenche que lorsque je change l'IDArticle : c'est plus souple. Ici, dans la macro de table, on n'a pas cette possibilit : elle s'excute lors

6 of 22

2/14/2013 09:59

Access : les macros de donnes

http://www.info-3000.com/access/macrodonnee/

pas encore rempli : ainsi, lorsqu'on effectue une modification dans une commande existante, le nouveau prix n'est pas import, mais lorsque nous nous trouvons sur une nouvelle commande - dans laquelle le prix n'existe pas encore - alors, il est import. Rajoutez un Si, comme ceci, au dbut de la macro : Ecrivez-y : EstNull([Prix])=Faux, et dans ce cas (le prix est nul, ou vide), on arrte simplement la macro. Ca va vous permettre de changer Ermenont en Ermenons sans toucher au prix.
Ajustement des mises jour des prix

de n'importe quelle mise jour de n'importe quel champ

Par contre, il demeure encore une faiblesse : Imaginez : vous avez rempli la commande N7. Elle est enregistre, le prix est import, tout va bien. Puis vous constatez que vous vous tes tromp d'article ! Ce n'est pas l'article N2 qu'il voulait, mais le 4 ! Si vous changez le N2 en 4, comme le prix tait dj indiqu, il ne va pas s'actualiser ! Ae ! Nous allons changer un tout petit peu de stratgie : occupons-nous seulement de l'IDArticle, et laissons tomber le prix. Il faudrait qu'on puisse lui dire de s'arrter immdiatement dans ces deux cas : 1. Dans le cas o IDArticle est vide (ce qui vitera un message d'erreur en mme temps) 2. Dans le cas o la valeur prcdente d'IDArticle est la mme que la nouvelle valeur (C'est dire que quand on va changer Ermenont en Ermenons, la valeur prcdente de l'IDArticle (2) est la mme que la "nouvelle" valeur (2 aussi puisqu'on ne s'est pas occup de ce champ) Modifiez votre Si comme suit : EstNull([IDArticle]) Ou [IDArticle]=[Ancien].[IDArticle]

Mise jour slective Voil ! Effectuons un test complet. Vous tes dans T_Commande : 1. Crez une nouvelle commande pour Francine Fermond (Ecrivez juste Francine Fermond dans une nouvelle ligne, rien d'autre) 2. Appuyez sur CTRL S pour enregistrer : aucune erreur ne survient Comme IDArticle est Null, notre Si initial arrte la macro immdiatement 3. Compltez la commande de Francine Fermond : crivez 2 dans son IDArticle, et enregistrez. Le prix de l'article 2 (33.45) est bien import 4. Quittez T_Commande, et allez dans T_Article. Augmentez le prix de la poupe 35.80 5. Quittez T_Article, et revenez dans T_Commande Le prix de la poupe est bien toujours 33.45 (ce qui est normal) 6. Crez une nouvelle commande pour Francine Fermont qui veut vous acheter encore une poupe. Cette fois, elle est bien logiquement facture avec le nouveau prix ! 7. Ae ! Du coup, on constate qu'on a commis une faute d'orthographe dans son nom. Rectifiez : ajoutez un "t" la fin de Fermon dans la commande 10 ! Enregistrez. Suspense ... YES ! Sa commande 10 n'a pas chang de prix ! 8. Bon, madame Fermont nous rappelle pour nous informer qu'elle s'est trompe dans sa commande 10 : elle ne voulait pas commander l'article 2, mais l'article 3. On accepte de changer 2 en 3 dans la commande 10, et on presse sur CTRL-S : Parfait : comme vous le voyez droite, la macro vient d'importer le prix de l'IDarticle 3. Il reste encore le cas exceptionnel ou l'utilisateur efface carrment l'IDArticle d'une commande : dans ce cas, le prix reste affich. Mais on va s'arrter l, c'est assez compliqu comme a.

Interactions entre les relations et les Macros de Mise jour

7 of 22

2/14/2013 09:59

Access : les macros de donnes

http://www.info-3000.com/access/macrodonnee/

Pour comprendre le chapitre qui vient, il vous faudra casser la relation entre T_Article et T_Commande (sinon, il sera tout bonnement impossible d'entrer un numro d'article non-correspondant)

L'autre bug survient dans le cas o l'utilisateur entre un IDArticle qui n'est pas rfrenc dans la table T_Article : vous serez gratifi d'un message d'erreur : Celui-ci n'est pas gnant pour un sou : lorsque la base de donnes sera termine, il est bien clair qu'on ne va jamais s'amuser inscrire des numros d'article : on aura videmment pris soin de crer une liste droulante pour choisir les articles, ce qui exclut cette erreur de facto.

Ignorer les erreurs


Si ce message d'erreur vous ennuie, vous pouvez toujours lui demander de l'ignorer (plus exactement : d'ignorer la ligne de macro qui pose problme). Voici l'astuce : ajoutez Sur Erreur tout en haut de votre macro, et choisissez Suivant :

A prsent, vous pouvez tenter d'crire un IDarticle fantaisiste dans IDArticle de T_Commande, il n'y aura plus de message d'erreur.

Par contre, restez conscient du danger : si un ancien IDarticle correct tait inscrit, le fait de le changer en numro incorrect ne changera plus le prix : Je ne saurais donc que trop vous recommander de redfinir la relation comme elle tait, avec l'intgrit rfrentielle. Voyez cette page si vous avez besoin d'aide sur l'utilit de l'intgrit rfrentielle.

Historisation des suppressions


Lorsque vous supprimez un enregistrement, il peut tre intressant de garder la trace de celui-ci. Les macros de donnes vont nous permettre cette fonctionnalit assez facilement. Je vais commencer vous montrer comment a se passe dans cette page, mais la deuxime partie de ce didacticiel y sera compltement consacr. A chaque supression d'un - ou plusieurs - enregistrement(s) de T_Commande, il faudrait que toutes les donnes de cette commande se copient dans une nouvelle table que nous appellerons T_CommandeHistorique. Nous allons commencer par crer cette table :

8 of 22

2/14/2013 09:59

Access : les macros de donnes

http://www.info-3000.com/access/macrodonnee/

1. Cliquez sur T_Commande dans le volet de navigation, et copiez-collez-l :

2.

3. Allez dans T_CommandeHistorique en mode cration, et dfinissez IDCommande en Numrique :

Macro Aprs suppression Nous disposons maintenant d'une table vide avec une structure quivalente T_Commande. On a d remplacer le NumroAuto par du Numrique simplement parce que dans cette table, les numros ne vont plus se suivre squentiellement (vous allez comprendre un peu plus tard). Fermez T_CommandeHistorique et retournez dans T_Commande. Cliquez sur le bouton Nous allons rcuprer toutes les anciennes valeurs de chaque champ (Oui : car comme le bouton l'indique - Aprs suppression - les donnes sont dj supprimes - depuis une petite fraction de seconde) dans des variables locales. Une fois que nous aurons tout stock dans ces variables locales, nous ouvrirons la table T_CommandeHistorique, et nous utiliserons CrerEnregistrement pour y intgrer le contenu de nos variables locales. Z'tes prt ? C'est par l : Une fois que vous avez bien tout recopi, testez : effacez un enregistrement :

Et allez ensuite vrifier que cet enregistrement a bel et bien t recopi dans T_CommandeHistorique.

Tiens ! Il n'a rien copi ! Et il n'a pas renvoy d'erreur !

Bug dans les champs mmos

C'est tout bte, mais faut le savoir : Ce bug est d la Remarque qui est en type de donnes Mmo ! Il suffit de supprimer ces deux instructions :

9 of 22

2/14/2013 09:59

Access : les macros de donnes

http://www.info-3000.com/access/macrodonnee/

Essayez maintenant de supprimer l'enregistrement 5 par exemple :

Et voil ! Ca marche ! (A part la remarque, videmment). A part vous demander de changer le type de la remarque de Mmo en Texte, je n'ai pas d'alternative viable vous proposer pour pouvoir journaliser cette remarque.

Interaction historisation/valeurs par dfaut Petite amlioration : Ajoutons la date et l'heure de cette suppression. Rendez-vous dans la table T_CommandeHistorique, et ajoutez un champ Moment en Date/Heure, et dans les options du champ, dfinissez la valeur par dfaut Maintenant(), comme ceci : Eh, vous savez quoi ? ... C'est dj fini ! Nul besoin de modifier la macro de table, puisque la valeur par dfaut est Maintenant(). Ds que T_CommandeHistorique va s'enrichir d'une ligne, la date et l'heure seront dj prsents. Essayez : Supprimez la commande N 8 de T_Commande, et allez ensuite dans T_CommandeHistorique :

La premire ligne ne contient pas de moment de suppression, puisqu'elle avait t supprime avant notre ajout de champ. La ligne 8 est bien prsente, avec sa date et heure de suppression (la nouvelle ligne contient la valeur par dfaut - la date et l'heure laquelle j'tais lorsque j'ai ouvert la table) mais il suffit de fermer et de rouvrir cette table pour qu'elle s'actualise automatiquement.

Suivi des modifications


Ce qui pourrait tre encore plus intressant, ce serait d'historiser galement les changements effectus dans la table T_Commande. Ce serait bien de savoir quelle valeur de quel champ a t modifie en quelle autre valeur. Nous allons utiliser le mot-cl Ancien que nous avons vu plus haut. Nous avons besoin de doubler tous les champs de la table T_CommandeHistorique afin de stocker les anciennes et nouvelles valeurs, comme ceci : Surtout, retirez la cl primaire de IDCommande, car partir de maintenant, nous pourrons avoir plusieurs enregistrements avec le mme IDCommande dans T_CommandeHistorique, puisqu'il sera possible de modifier la mme commande plusieurs reprises, ce qui cumulera autant de lignes d'historique. Quittez T_CommandeHistorique, et retournez dans T_Commande.

10 of 22

2/14/2013 09:59

Access : les macros de donnes

http://www.info-3000.com/access/macrodonnee/

Cette fois, cliquez sur l'vnement de Macro Aprs MAJ (Mise A Jour)

Format XML
Je pense que vous avez dj la puce l'oreille : ce que nous allons faire ressemble ce que nous avons fait pour la suppression : 1. On sauvegarde les donnes des valeurs actuelles et anciennes dans des variables locales 2. On cre un nouvel enregistrement dans T_CommandeHistorique 3. On y injecte les contenus des donnes Commenons avec le client. Vous allez devoir recopier la macro suivante, mais attendez : Les macros sont stockes en XML. Je ne vais pas vous donner un cours d'XML, mais tout ce que vous devez savoir, c'est qu'il s'agit d'un format de texte puissant et souple qui est utilis dans beaucoup de circonstances. Grce ce XML, justement, je vais vous viter la recopie fastidieuse de cette macro ! Voici comment j'ai procd : 1. 2. 3. 4. J'ai appuy sur CTRL A pour slectionner toute la macro puis sur CTRL C pour la copier Puis, je suis all dans le bloc notes Windows (Ou dans word) et j'ai appuy sur CTRL V (pour coller), et voici ce que j'ai obtenu :

Exemple XML Je peux donc vous proposer cette macro sous cette forme :
<?xml version="1.0" encoding="UTF-16" standalone="no"?> <DataMacros xmlns="http://schemas.microsoft.com/office/accessservices/2009/11/application"><DataMacro Event="AfterUpdate"><Statements><Action Name="SetLocalVar"><Argument Name="Name">VARClient</Argument><Argument Name="Value"> [Client]</Argument></Action><Action Name="SetLocalVar"><Argument Name="Name">VARClientAncien</Argument><Argument Name="Value">[Old].[Client]</Argument></Action><CreateRecord><Data><Reference>T_CommandeHistorique</Reference> </Data><Statements><Action Name="SetField"><Argument Name="Field">Client</Argument><Argument Name="Value">[VARClient]</Argument></Action><Action Name="SetField"><Argument Name="Field">ClientAncien</Argument><Argument Name="Value">[VARClientAncien]</Argument></Action></Statements></CreateRecord></Statements></DataMacro></DataMacros>

Slectionnez le texte XML ci-dessus, et copiez collez-le directement dans votre macro vide : miracle, vous avez votre macro sans avoir la recopier. Elle est pas belle, la vie ? Il n'y a plus qu' tester ! Dans la commande N4, corrigez l'orthographe de Charles Cottet en Charles Cottey (Avec un "y" la fin). Enregistrez, et allez voir ce qui s'est pass dans T_CommandeHistorique :

Constatez que l'IDCommande de T_CommandeHistorique ne s'est pas rempli, et les autres champs restent galement vides. Il faut donc tout faire la main :

Mais comme je suis un gars bon, je vous propose d'effacer votre macro actuelle, et de la remplacer par cette version complte juste prte tre copie-colle :

11 of 22

2/14/2013 09:59

Access : les macros de donnes

http://www.info-3000.com/access/macrodonnee/

<?xml version="1.0" encoding="UTF-16" standalone="no"?> <DataMacros xmlns="http://schemas.microsoft.com/office/accessservices/2009/11/application"><DataMacro Event="AfterUpdate"><Statements><Action Name="SetLocalVar"><Argument Name="Name">VARIDCommande</Argument><Argument Name="Value">[IDCommande]</Argument></Action><Action Name="SetLocalVar"><Argument Name="Name">VARClient</Argument><Argument Name="Value">[Client]</Argument></Action><Action Name="SetLocalVar"><Argument Name="Name">VARClientAncien</Argument><Argument Name="Value">[Old].[Client]</Argument></Action><Action Name="SetLocalVar"><Argument Name="Name">VARIDArticle</Argument><Argument Name="Value">[IDArticle]</Argument> </Action><Action Name="SetLocalVar"><Argument Name="Name">VARIDArticleAncien</Argument><Argument Name="Value">[Old].[IDArticle]</Argument></Action><Action Name="SetLocalVar"><Argument Name="Name">VARPrix</Argument> <Argument Name="Value">[Prix]</Argument></Action><Action Name="SetLocalVar"><Argument Name="Name">VARPrixAncien</Argument><Argument Name="Value">[Old].[Prix]</Argument></Action><Action Name="SetLocalVar"><Argument Name="Name">VARQte</Argument><Argument Name="Value">[Qte]</Argument></Action><Action Name="SetLocalVar"><Argument Name="Name">VARQteAncien</Argument><Argument Name="Value">[Old].[Qte]</Argument></Action> <CreateRecord><Data><Reference>T_CommandeHistorique</Reference></Data><Statements><Action Name="SetField"><Argument Name="Field">IDCommande</Argument><Argument Name="Value">[VARIDCommande]</Argument></Action><Action Name="SetField"><Argument Name="Field">Client</Argument><Argument Name="Value">[VARClient]</Argument></Action><Action Name="SetField"><Argument Name="Field">ClientAncien</Argument><Argument Name="Value">[VARClientAncien] </Argument></Action><Action Name="SetField"><Argument Name="Field">IDArticle</Argument><Argument Name="Value">[VARIDArticle]</Argument></Action><Action Name="SetField"><Argument Name="Field">IDArticleAncien</Argument> <Argument Name="Value">[VARIDArticleAncien]</Argument></Action><Action Name="SetField"><Argument Name="Field">Prix</Argument><Argument Name="Value">[VARPrix]</Argument></Action><Action Name="SetField"><Argument Name="Field">PrixAncien</Argument><Argument Name="Value">[VARPrixAncien]</Argument></Action><Action Name="SetField"><Argument Name="Field">Qte</Argument><Argument Name="Value">[VARQte]</Argument></Action><Action Name="SetField"><Argument Name="Field">QteAncien</Argument><Argument Name="Value">[VARQteAncien]</Argument></Action></Statements></CreateRecord></Statements></DataMacro></DataMacros>

Testez : Faites plein de changements dans l'enregistrement N 3, comme ci-dessous, et allez vrifier ensuite T_CommandeHistorique :

Je vous rappelle que la remarque n'est pas journalise cause de son type de donnes Mmo. Dlais d'enregistrements J'ai constat parfois un certain dlai ncessaire pour la mise jour. En d'autres mots, si vous fermez super-vite T_Commande, et que vous ouvrez T_CommandeHistorique tel Speedy Gonzales, il est possible que vous ne voyiez pas les changements. Fermez tranquillement T_CommandeHistorique et rouvrez-la touuuuuuut lentement, avant de conclure que vous avez peut-tre fait une faute d'erreur quelque part. Les suppressions sont mlanges avec les modifications. Ce serait sympathique d'avoir un champ GenreEvenement qui contiendrait soit Suppression, Soit Modification, selon les cas, non ? Je vous propose d'essayer de raliser cette petite prouesse sans consulter la solution juste ici plus bas, titre d'exercice !

Solution :

1. Crez un champ GenreEvenement, en texte, dans T_CommandeHistorique :

2. Allez dans T_Commande, dans la macro

3. Ajoutez cette ligne tout la fin :

12 of 22

2/14/2013 09:59

Access : les macros de donnes

http://www.info-3000.com/access/macrodonnee/

4. Quittez cette macro, et allez dans

5. Ajoutez cette ligne :

Maintenant, testons ! 1. Crez un nouvel enregistrement dans T_Commande : 2. Enregistrez-le : 3. Modifiez-le : 4. Supprimez-le. Ouvrez T_CommandeHistorique. la modification et la suppression ont bien t journalises :

Macro Aprs insertion


La seule chose qui n'a pas t journalise, c'est la cration de l'enregistrement. Seriez-vous capable de le faire sans regarder la solution ?

Solution :

Il n'y a rien faire de spcial dans T_CommandeHistorique, cette fois. Allez dans T_Commande, dans la Macro

Comme nous allons faire exactement la mme chose qu'Aprs MAJ, on ne va pas se priver : rendez-vous dans la macro CTRL A pour tout slectionner, et CTRL C pour tout copier. Quittez cette macro, et allez dans Appuyez sur CTRL-V pour tout coller. .

, appuyez sur

13 of 22

2/14/2013 09:59

Access : les macros de donnes

http://www.info-3000.com/access/macrodonnee/

Voil ! Maintenant, retirez toutes les instructions qui concernent les valeurs "Ancien", qui ne servent rien dans le cas actuel : Pensez ajouter en dernier lieu :

Testez ! Ajoutez une nouvelle commande :

Admirez le rsultat dans T_CommandeHistorique :

Journalisation des erreurs


Si vous commettez la moindre petite faute (un champ qui n'est pas parfaitement orthographi par exemple), la macro ne fonctionnera simplement pas, mais elle ne vous affichera pas toujours un message d'erreur.

USYSApplicationLog Dans certains cas, un message d'erreur vous sera affich,mais dans d'autres, les erreurs seront consignes dans une table spciale, nomme USYSAplicationLog (USYS = User SYStem). Si vous n'avez pas fait la moindre faute dans la base de donnes, USYSApplicationLog n'existe pas (pas encore). Si vous avez fait des fautes qui ont provoqu des erreurs de macro, la table est cre, mais elle n'est pas visible de toute faon. Pour savoir si USYSApplicationLog existe, cliquez sur le menu Fichier : vous aurez un bouton en plus :

Dans mon cas, je n'ai pas manqu de commettre quelques erreurs lors de l'laboration de de didactiel, et voici le contenu de mon USYSApplicationLog, que je visualise en cliquant sur le bouton :

On peut effacer certaines lignes, ou carrment toutes les lignes de cette table, la main. Mme si vous videz compltement la table, le bouton continuera d'tre affich.

Affichage des objets systme

14 of 22

2/14/2013 09:59

Access : les macros de donnes

http://www.info-3000.com/access/macrodonnee/

Si on veut s'en dbarasser, il faut carrment supprimer USYSApplicationLog.

Mais comment peut-on la supprimer si on ne la voit mme pas ? Il faut afficher les objets systme, comme ceci : Si vous la voyez - c'est donc que vous avez commis des erreurs - supprimez-l. Si vous ne la voyez pas, c'est que jamais aucune erreur n'a t gnre dans une macro de table de cette base. (Ne vous proccupez surtout pas des autres tables en gris clair, ce sont des tables ncessaire la cuisine interne d'Access). Si vous nommez l'une de vos tables en la commenant pas USYS, elle sera automatiquement masque, et vous ne pourrez la faire apparatre qu'en cochant la case qu'on vient de voir.

Afin d'illustrer le fonctionnement de cette journalisation des erreurs, crez deux tables : T_1 et T_2, comme ceci :

Elles sont compltement vides.

Allez dans la table T_2, Avant Modification :

, et demandez modifier le champ NBAnimal en lui attribuant

le texte "Tralala". Une erreur va survenir, puisque le champ est dfini en numrique :

. Essayez de saisir une

ligne (Georges, chat), et observez ce qui se passe au moment de l'enregistrement :

Un message d'erreur survient effectivement. Cliquez sur OK, et constatez qu'il est impossible de sauvegarder cet enregistrement. Votre seul salut est d'annuler votre saisie avec la touche .

Du coup, dans ce cas, cet avertissement a pour effet d'annuler l'erreur et USYSApplicationLog ne s'est pas cre.

Que se passerait-il si nous demandions ignorer l'erreur, comme nous l'avons vu plus haut, ainsi :

Essayez : cette fois l'enregistrement est cr, et la ligne fautive est simplement ignore (NBAnimal restera vide) ... Mais USYSApplicationLog ne sera toujours pas cre ! Par contre : 1. Supprimez cette macro 2. Fermez T_2

15 of 22

2/14/2013 09:59

Access : les macros de donnes

http://www.info-3000.com/access/macrodonnee/

3. Allez dans T_1 - Aprs insertion :

. Recopiez ceci :

Il s'agit de la mme erreur, sauf que cette fois, nous sommes dans une autre table. 4. Entrez les donnes que je vous propose sur la droite, sauvegardez avec CTRL-S, et regardez en mme temps dans le volet de navigation : la table USYSApplicationLog vient d'tre cre automatiquement :

Regardez dans le menu Fichier : la mise en garde est explicite :

Vous pouvez - au choix - cliquer sur le bouton

, ou double-cliquer sur la table USYSApplicationLog pour l'ouvrir.

Si vous utilisez le bouton

, USYSApplicationLog s'affiche, et le message dans le menu fichier s'est transform:

Ouvrez USYSApplicationLog : elle contient la seule et unique ligne dcrivant l'action qui a pos problme :

ID :N squentiel de l'erreur (pas important) SourceObjet : Le nom de la table et de sa macro qui a gnr l'erreur Data macro, Error Number : rfrences qui ne vous seront probablement jamais utiles Category (Execution) et Object Type (Macro) : je ne vois pas comment il pourrait s'agir d'autre chose que "Execution" et "Macro" Je souligne que cette erreur est silencieusement gnre, et discrtement journalise.

Que se passerait-il si, comme dans l'exemple prcdent nous demandons explicitement passer par dessus l'erreur, comme ceci :

Eh bien, tout comme l'exemple d'avant, l'erreur est simplement... ignore, et USYSApplicationLog ne sera pas complt d'une ligne de plus.

Parcours de tous les enregistrements


Revenons notre duo T_Article et T_Commande. Imaginons que lorsqu'on modifie la remarque d'un article, celle-ci doive s'ajouter aux remarques de tous les articles correspondants dans T_Commande. Je m'explique : Admettons que nous changions la remarque du crayon de couleur dans T_Article : j'aimerais que cette nouvelle remarque s'ajoute la fin des remarques existantes de toutes les commandes de

16 of 22

2/14/2013 09:59

Access : les macros de donnes

http://www.info-3000.com/access/macrodonnee/

cet article, ou qu'elle soit cre, de cette manire: Nous l'avons vu plus haut : les champs de type Mmo ne permettent pas ce genre de choses. Aussi, commencez par remplacer la Remarque de T_Article et de T_Commande de Mmo en Texte.

J'ai malheureusement constat d'normes problmes apparemment lis au fait d'avoir transform mon champ Remarque de Mmo en Texte, et je n'ai pas pu continuer (comme s'il croyait que le champ tait toujours en Mmo). Mon seul salut a t de crer un nouveau champ Rem2 dans chacune des tables.

Je vous invite faire de mme (histoire d'avoir les mmes champs que moi) :

Instruction PourChaqueEnregistrement Rendez-vous dans T_Article, dans la macro AprsMAJ :

Voici la version de cette mme macro en XML que vous avez juste copier-coller dans votre macro :
<?xml version="1.0" encoding="UTF-16" standalone="no"?> <DataMacros xmlns="http://schemas.microsoft.com/office/accessservices/2009/11/application"><DataMacro Event="AfterUpdate"><Statements><Action Name="SetLocalVar"><Argument Name="Name">VARRem2</Argument><Argument Name="Value"> [Rem2]</Argument></Action><Action Name="SetLocalVar"><Argument Name="Name">VARIDArticle</Argument><Argument Name="Value">[IDArticle]</Argument></Action><ForEachRecord><Data><Reference>T_Commande</Reference> <WhereCondition>[IDArticle]=[VARIDArticle]</WhereCondition></Data><Statements><EditRecord><Data/><Statements><Action Name="SetField"><Argument Name="Field">Rem2</Argument><Argument Name="Value">[VARRem2]</Argument> </Action></Statements></EditRecord></Statements></ForEachRecord></Statements></DataMacro></DataMacros>

Ractions en chane

17 of 22

2/14/2013 09:59

Access : les macros de donnes

http://www.info-3000.com/access/macrodonnee/

Avant de tester, jetez un oeil sur la table T_CommandeHistorique :

. J'ai actuellement 7 enregistrements.

Bien. Fermez cette table, et allez dans T_Article. Prcisez que l'article 3 "Contient du plomb" : Fermez la table, et ouvrez T_Commande :

Toutes les commandes de l'article numro 3 ont t maintenant mises jour. Mais ce n'est pas tout ! Vous vous rappelez de T_CommandeHistorique ? Il y avait - dans mon cas - 7 enregistrements. Si vous vous souvenez, nous avons prcis plus haut qu'une ligne d'historique devait tre rajoute chaque modification, ajout ou suppression d'une ligne de commande... C'est bien ce qui vient de se passer, non ? ... Toutes les lignes de T_Commande de l'article 3 ont t modifies. Du coup, le 2me effet Kiss-Cool, c'est que les trois lignes sont maintenant rfrences dans T_CommandeHistorique (j'en suis 10 enregistrements, maintenant):

Rcursivit accidentelle Du coup, imaginez : si nous avons une table A pourvue d'une macro qui va modifier des champs d'une table B, qui, elle-mme possde une macro qui va changer deschamps dans la table A ... qui va donc changer dans la table B, et ainsi de suite, l'infini ? Ca planterait tout le systme ! Heureusement, les macros de table sont pourvues d'un garde-fou (je ne me rappelle plus combien, mais il remarque assez rapidement ce problme de "boucle infinie" - Appele "Rcursivit" - le cas chant). Revenons nos moutons : ce qui est un peu bte, c'est que ces trois lignes ne nous servent strictement rien puisque Rem2 n'est pas prsent dans cette T_CommandeHistorique. Tiens : Ajoutez ce Rem2 dans cette table en modifiant la macro Aprs MAJ.

Solution :

18 of 22

2/14/2013 09:59

Access : les macros de donnes

http://www.info-3000.com/access/macrodonnee/

Cet exercice (tel qu'il est prsent) est stupide, puisque nous aurions pu tout aussi bien obtenir le mme rsultat avec une requte base sur les deux tables T_Article et T_Commande, avec bien moins d'effort :

Mais que se passe-t-il si nous modifions une Rem2 directement dans T_Commande ? (Par exemple, on modifie un des "Longueur : 14CM" en "Made in China") Ca ne changera videmment rien dans T_Article, mais dans l'exemple de la requte ci-dessus, cette modification n'apparatra pas du tout (Puisque, justement, on prend Rem2 de T_Article). Concatnation Mais... Si on se rend dans T_Article, et qu'on remplace "Longueur : 14CM" par "Garanti 1 an", alors, toutes les Rem2 de l'article 3, dans T_Commande (y compris "Made in China") seront irrmdiablement crass par "Garanti 1 an" ! Du coup, si je me rfre au libell initial de l'exercice, il ne s'agit pas de simplement craser les remarques au bulldozer, mais d'ajouter les remarques de T_Article la fin des remarques de T_Commande. En clair, a veut dire a :

Corrigez la macro comme suit :

Essayez maintenant d'crire "Bois d'Asie" dans la Rem2 de l'article N3 de T_Article, et allez ensuite voir quoi ressemble T_Commande :

Ce n'est pas mal du tout ! Le seul petit truc qu'on pourrait reprocher, c'est dans le cas ou il y avait dj une Rem2, la nouvelle Rem2 vient se coller directement sa droite : plutt que "MadeinChinaBois d'Asie", j'aurais prfr : "Made in China. Bois d'Asie". Ne serait-ce pas sympathique de rajouter un point et un espace aprs la remarque existante. Par contre, il ne faudrait pas faire a pour les cas ou la remarque est encore vide. Un petit Si va nous rgler ce problme :

19 of 22

2/14/2013 09:59

Access : les macros de donnes

http://www.info-3000.com/access/macrodonnee/

Si le champ Rem2 est vide (Null), alors, on se contente de transvaser Rem2 de T_Article, sans autre. S'il n'est pas vide, on ajoute un point et un espace, et on colle le tout la suite de Rem2 de T_Article. Comme ceci :

Il n'y a plus qu' tester : Parfait ! Elle est pas belle, la vie ? Bon, on peut toujours faire mieux : s'il y avait dj un point la fin d'une Rem2 existante, il va en rajouter un deuxime, et, si le nombre de caractres permis pour Rem2 dans T_Commande ne permet pus d'ajouter le contenu de Rem2 de T_Article, une erreur sera gnre dans USYSApplicationLog, mais voil... On va s'arrter l !

Liste des Macros de table


Nous voici donc avec un bon petit paquet de macros. Il est possible de lister d'un seul coup d'oeil toutes les macros de toutes les tables. Rendez-vous dans n'importe quelle table en mode saisie de donnes, et cliquez sur Macro Nomme, Renommer/supprimer une macro :

On regrettera que cette fentre soit juste une fentre de visualisation gnrique des macros de donnes, sans les dtails de leurs instructions, ainsi que le fait qu'on ne puisse pas double-cliquer directement dessus pour s'y rendre .

Macros nommes
Si vos diffrents vnements de chaque table effectuent chaque fois la mme tche, il est possible de crer une Macro nomme, et nous appellerons ensuite cette macro depuis les diffrents vnements de nos diffrentes tables. Par exemple, imaginons qu' chaque mise jour d'un enregistrement dans n'importe laquelle des tables, il s'agit d'envoyer un E-Mail quelqu'un l'informant qu'une table a t modifie.

20 of 22

2/14/2013 09:59

Access : les macros de donnes

http://www.info-3000.com/access/macrodonnee/

Marche suivre : 1. Allez dans n'importe quelle table (Disons T_1 par exemple)

2.

3.

4.

5.

Vous voici maintenant l'heureux propritaire d'une macro nomme, qui n'est actuellement rattache aucun vnement de table (et qui ne s'excutera donc jamais en l'tat). Vous pouvez la voir dans la liste des macros de table : Notez les diffrences avec les autres macros : Elle a un nom particulier (MD_EMail) C'est un type Macro de donnes nomme On peut la renommer

Si vous dsirez la modifier : Actions possibles Avant et Aprs les vnements Il s'agit maintenant d'excuter cette macro de donnes nomme depuis n'importe quel vnement "aprs quelque chose" de n'importe quelle table.

En effet, vous avez plus d'options d'actions de macros "Aprs" que "Avant" : Ainsi, admettons que vous dsiriez excuter la macro MD_EMail Aprs Mise jour de T_2, et Aprs suppression de T_1, il vous suffit d'aller dans T_1 et T_2, et d'appeler MD_EMail depuis leurs vnements correspondants, ainsi :

21 of 22

2/14/2013 09:59

Access : les macros de donnes

http://www.info-3000.com/access/macrodonnee/

Maintenant, essayez de modifier un enregistrement dans T_2 : un message survient :

C'est un message tout fait normal : Outlook se demande si c'est bien normal qu'un autre programme (Access, en l'occurrrence) veuille expdier des messages automatiquement. Vous devez patienter le temps que la barre verte de progression ait termin avant de pouvoir cliquer sur Accepter. A la fin, vous cliquez sur Accepter, et vous ouvrirez ensuite Outlook pour constater qu'un message est bien prt partir dans votre bote d'envoi. Evidemment, cette manipulation ne fonctionne absolument pas avec des webmails comme Yahoo ou Gmail. Si vous tentez de supprimer un enregistrement dans T_1, le mme message d'attention va apparaitre.

Table ddie aux macros de table


En conclusion, l'avantage de ces macros nommes est de pouvoir contenir beaucoup d'instructions (dans notre cas, nous en avons qu'une : Envoyer un E-Mail), et de pouvoir se faire appeler depuis plusieurs vnements de plusieurs tables diffrentes. Les macros nommes sont appelables depuis n'importe quelle table. Mais elles sont incrustes dans une table en particulier (Ici, dans T_1). Si vous supprimez T_1 de votre base de donnes, toutes les tables qui appelleraient ventuellement la macro nomme MD_EMail ne pourront plus fonctionner. Ces macros nommes ne se trouvent pas dans la liste des macros "normales", que vous aviez peut-tre l'habitude d'utiliser dans les versions prcdentes d'Access... Ainsi, il est peut-tre sage de crer une table expressment destine stocker les macros nommes (T_macroNommee par exemple) - Ou, pourquoi ne pas reprendre l'astuce de la table qui commence par USYS afin d'tre automatiquement masque ? ... Ainsi, vos macros nommes seraient stockes dans une table masque USYSMacroNommee par exemple)

Je vous invite suivre la deuxime partie de ce didacticiel : l'historisation complte de toutes les tables d'une base de donnes.

22 of 22

2/14/2013 09:59

Vous aimerez peut-être aussi