Vous êtes sur la page 1sur 13

Numrotation personnalise des enregistrements dans Access 2010

par Christophe WARIN (Mon espace perso)


Date de publication : 16 novembre 2009 Dernire mise jour :

Mise en place d'une numrotation personnalise l'aide des vnements de table de Microsoft Access 2010.

Numrotation personnalise des enregistrements dans Access 2010 par Christophe WARIN (Mon espace perso)

I - Introduction..............................................................................................................................................................3 II - Avant Access 2010................................................................................................................................................ 4 III - Avec Access 2010................................................................................................................................................ 7 III-A - DataMacro.................................................................................................................................................... 7 III-B - Mise en place dans un formulaire............................................................................................................... 9 III-C - Intrt d'une table supplmentaire............................................................................................................ 11 IV - Conclusion.......................................................................................................................................................... 13

-2Copyright 2009 - Warin Christophe. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrets. Droits de diffusion permanents accords developpez LLC.
http://warin.developpez.com/tutoriels/access/numauto2010/

Numrotation personnalise des enregistrements dans Access 2010 par Christophe WARIN (Mon espace perso)

I - Introduction
La mise en place d'une numrotation personnalise est un thme qui revient souvent sur les forums. Ces questions sont aussi bien poses par des utilisateurs novices souhaitant transformer un champ NumAuto afin qu'il corresponde leur besoin ou bien de personnes plus exprimentes provenant d'une autre technologie o les procdures stockes permettent aisment ce genre de traitement (SQL Server par exemple). A travers ce document, je vous propose de dcouvrir une nouvelle approche de la numrotation des enregistrements dans Microsoft Access 2010 et plus particulirement celle des numros de factures dans une application de gestion.

-3Copyright 2009 - Warin Christophe. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrets. Droits de diffusion permanents accords developpez LLC.
http://warin.developpez.com/tutoriels/access/numauto2010/

Numrotation personnalise des enregistrements dans Access 2010 par Christophe WARIN (Mon espace perso)

II - Avant Access 2010


Dans un premier temps, un retour aux versions prcdentes va permettre de cerner les problmes auxquels les dveloppeurs sont confronts, passage oblig afin de dterminer les rels plus apports par Access 2010. Les hypothses sont les suivantes : Une table tblFacture_ac2007 regroupe les factures tablies par le service commercial. Les factures seront numrotes selon la norme : FAYYMMXXX de telle sorte que pour chaque mois (MM) de l'anne (YY) un compteur (XXX) soit incrment partir de 1.

Voici la structure de la table correspondante : Nom du Type champ IDFacture NumroAuto IDClient Integer DateFacture Date DateEcheance Date Indice Integer Extra Cl primaire

Et son contenu : IDFacture IDClient 1 2 3 1 4 1 5 2 DateFacture DateEcheance Indice 12/11/2009 20/11/2009 1 17/11/2009 19/11/2009 2 10/12/2009 10/12/2009 1 11/12/2009 12/12/2009 2

Comme indiqu plus haut, vous remarquerez qu' chaque nouveau mois, la valeur du champ Indice redmarre 1. La mise en forme du numro de facture peut alors tre obtenu l'aide de l'expression suivante :
="FA" & Format([DateFacture];"yymm") & Format([Indice];"000")

Comme vous le savez sans doute, aucun mcanisme propre Access ne permet de dfinir un tel comportement pour le champ Indice. Jusqu' prsent, la seule solution consistait confier cette tape de calcul du code VBA inclus dans le formulaire servant la saisie d'une nouvelle facture. Plus prcisment, il tait d'usage d'utiliser l'algorithme ci-dessous avant la mise jour des donnes saisies dans les contrles du formulaire.

-4Copyright 2009 - Warin Christophe. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrets. Droits de diffusion permanents accords developpez LLC.
http://warin.developpez.com/tutoriels/access/numauto2010/

Numrotation personnalise des enregistrements dans Access 2010 par Christophe WARIN (Mon espace perso)

Soit en VBA :
Private Sub Form_BeforeUpdate(Cancel As Integer) Dim oRst As DAO.Recordset If Me.NewRecord Then Set oRst = CurrentDb.OpenRecordset( _ "SELECT Max(Indice) FROM tblFacture_ac2007 WHERE Format(DateFacture,""yymm"")=" & _ Chr(34) & Format(Me.DateFacture, "yymm") & Chr(34)) With oRst If Not .EOF Then Me![Indice].Value = Nz(.Fields(0).Value, 0) + 1 Else Me![Indice].Value = 1 End If .Close End With End If End Sub

Illustration :

-5Copyright 2009 - Warin Christophe. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrets. Droits de diffusion permanents accords developpez LLC.
http://warin.developpez.com/tutoriels/access/numauto2010/

Numrotation personnalise des enregistrements dans Access 2010 par Christophe WARIN (Mon espace perso)

Si cette solution peut paratre suffisante, il n'en reste pas moins qu'elle prsente quelques inconvnients majeurs : Dans un cadre multi-utilisateurs, il se peut qu'un utilisateur A valide son insertion pendant qu'un utilisateur B calcule son indice. Consquence : B soumet une facture d'indice 3 alors que A vient juste de la crer. Au mieux, une erreur de doublon est leve si le champ les interdits, au pire, la base de donnes comporte une incohrence avec deux factures possdant le mme numro lgal. En bref, rien ne garantit que l'indice calcul l'tape 3 soit toujours valide l'tape 5. Le recours au langage VBA pour l'incrmentation de l'indice empche toute saisie externe au formulaire telle qu'une criture directe dans la table, une requte action, ou bien encore une importation d'un fichier Excel par exemple.

-6Copyright 2009 - Warin Christophe. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrets. Droits de diffusion permanents accords developpez LLC.
http://warin.developpez.com/tutoriels/access/numauto2010/

Numrotation personnalise des enregistrements dans Access 2010 par Christophe WARIN (Mon espace perso)

III - Avec Access 2010 III-A - DataMacro


Les vnements de table prsents dans Access 2010 permettent de pallier aux inconvnients lists ci-dessus. En effet, en confiant la dtermination du nouvel indice d'une facture au moteur de base donnes, nous rduisons les risques d'accs concurrents (le dlai entre les oprations est diminu) et nous tendons le domaine d'action de la rgle de calcul. Dsormais, mme une saisie directe dans la table conduira la cration d'un indice adquat. Il en va de mme pour une importation depuis un fichier Excel par exemple. La structure principale de la table tblFacture sera semblable celle de tblFacture_ac2007. Nom du Type champ IDFacture NumroAuto IDClient Integer DateFacture Date DateEcheance Date Indice Integer Extra Cl primaire

Pour plus de facilit, un champ calcul NumeroFacture peut y tre ajout de telle sorte centraliser la formule de calcul dans la table. A la date de publication de ce tutoriel, la fonction Format n'est pas disponible dans les vnements de table. Impossible de savoir ce qu'il en sera dans la version finale prvue au printemps 2010. Nous sommes donc obligs de recourir une expression quivalente base de String$ et Right$. Les deux appels suivants retournent le mme rsultat, pour des valeurs du champ [Indice] ne dpassant pas 999.
Format([Indice];"000") String$(3-Len([Indice]);"0") & [Indice]

L'expression de calcul du champ NumeroFacture sera donc :


"FA" & Right$(Year([DateFacture]);2) & String$(2-Len(Month([DateFacture]));"0") & Month([DateFacture]) & String$(3-Len([Indice]);"0") & [Indice]

IDFacture IDClient 1 2 3 1 4 1 5 2

DateFacture DateEcheance Indice 12/11/2009 20/11/2009 1 17/11/2009 19/11/2009 2 10/12/2009 10/12/2009 1 11/12/2009 12/12/2009 2

-7Copyright 2009 - Warin Christophe. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrets. Droits de diffusion permanents accords developpez LLC.
http://warin.developpez.com/tutoriels/access/numauto2010/

Numrotation personnalise des enregistrements dans Access 2010 par Christophe WARIN (Mon espace perso)

Juste avant l'insertion effective dans la table, l'vnement ValidateChange est lev. C'est dans cet vnement que nous allons prparer l'indice de la facture sur le point d'tre cre. L'algorithme sera assez proche de celui utilis dans l'vnement BeforeUpdate du formulaire vu plus haut.

L'vnement de table ValidateChange offrant trs peu de possibilit en terme de programmation, nous allons confier le calcul du nouvel indice la requte qryNouvelIndice dont le code SQL est le suivant :
SELECT Max(Indice)+1 AS NOUVELINDICE, Year(DateFacture) AS ANNEE, Month(DateFacture) AS MOIS FROM TblFacture GROUP BY Year(DateFacture), Month(DateFacture);

Info : nous n'utiliserons pas de requtes paramtres, pour l'instant incompatibles avec l'vnement ValidateChange. Celle-ci propose une nouvelle valeur d'indice pour chaque mois dj rfrenc dans la table. En l'occurrence pour notre jeu d'essai, le retour sera : NOUVELINDICENNEE A 3 2009 3 2009 MOIS 11 12

L'action LookUpRecord permettra ainsi aisment de rcuprer cette valeur et de la stocker dans une variable locale. Dans le cas o aucun enregistrement n'est trouv, en thorie, le bloc LookUpRecord ne devrait pas tre excut. Cependant, dans la version actuelle, celui-ci se poursuit et les champs de l'enregistrement trouv possde la valeur NULL. Dans le doute et en attendant une ventuelle fonction NoMacth, je vous conseille de procder ainsi :
SetLocalVar (VIndice;1) LookUp A Record In qryNouvelIndice WHERE [ANNEE]=Year([tblFacture].[DateFacture]) AND [MOIS]=Month([tblFacture].[DateFacture]) ALIAS record

-8Copyright 2009 - Warin Christophe. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrets. Droits de diffusion permanents accords developpez LLC.
http://warin.developpez.com/tutoriels/access/numauto2010/

Numrotation personnalise des enregistrements dans Access 2010 par Christophe WARIN (Mon espace perso) SetLocalVar(vIndice;Nz(NouvelIndice,1)) SetField ([Indice];[vIndice])

Ainsi, si aucun enregistrement n'est trouv et que le bloc LookUpRecord n'est pas excut, le champ Indice prendra la valeur de la variable locale vIndice initialise en dbut de macro, dans le cas contraire, et si la valeur NULL est retourne, la fonction NZ la convertira en 1. L'appel la proprit IsInsert avant toute action permettra de s'assurer que le traitement interviendra uniquement lors de la cration d'une nouvelle facture. En effet, il serait dommageable qu'un simple changement de l'chance provoque la modification du numro de la facture courante.
If [IsInsert] Then SetLocalVar (VIndice;1) LookUp A Record In qryNouvelIndice WHERE [ANNEE]=Year([tblFacture].[DateFacture]) AND [MOIS]=Month([tblFacture].[DateFacture]) ALIAS record SetLocalVar(vIndice;Nz(NouvelIndice,1)) SetField ([Indice];[vIndice]) End If

III-B - Mise en place dans un formulaire


L'interface de saisie d'une nouvelle facture sera identique celle dcrite pour Access 2007. Nous vous proposons de nous attarder la dfinition d'une stratgie permettant l'utilisateur de visualiser le numro du document en cours de cration. En effet, la tche est plus complexe qu'il n'y parait. L'vnement de table tant dclench aprs la validation des donnes dans le formulaire, il est impossible d'afficher en temps rel l'indice calcul dans la DataMacro vue plus haut. La mission va donc consister prsenter un numro de facture probable et de le comparer en fin de traitement avec celui effectivement inscrit dans la base de donnes. Dans cette optique, un champ nomm txtNumFacture possdant l'expression suivante comme source peut suffire :
=IIf( [NewRecord]; "FA" & Format(Nz([DateFacture]);"yymm") & Format( Nz ( DMax( "Indice"; "tblFacture"; "Format([DateFacture],""yymm"")=" & Chr(34) & Format(Nz([txtDateFacture]);"yymm") & Chr(34) )+1; 1 ); "000" ); [NumeroFacture])

Il s'agit en fait de retourner : Le numro d'une facture existante en mode consultation. Un numro calcul qui sera thoriquement allou une nouvelle facture.

En dbut de saisie :

-9Copyright 2009 - Warin Christophe. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrets. Droits de diffusion permanents accords developpez LLC.
http://warin.developpez.com/tutoriels/access/numauto2010/

Numrotation personnalise des enregistrements dans Access 2010 par Christophe WARIN (Mon espace perso)

Aprs la saisie de la date :

Enfin, la comparaison l'aide du code VBA ci-dessous des valeurs avant et aprs update permet de gnrer l'alerte utilisateur.
Option Compare Database Option Explicit Dim vNumFacture As String

Private Sub Form_BeforeUpdate(Cancel As Integer) 'Stocke le numro de facture avant enregistrement vNumFacture = Me.txtNumFacture End Sub Private Sub form_AfterUpdate() 'Compare le numro actuel avec celui sauvegard avant l'update If vNumFacture <> Me.txtNumFacture Then _ MsgBox "Une autre saisie a t traite avant la vtre, le numro de votre facture a t modifi : " &

Me.txtNumFacture End If End Sub - 10 Copyright 2009 - Warin Christophe. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrets. Droits de diffusion permanents accords developpez LLC.
http://warin.developpez.com/tutoriels/access/numauto2010/

Numrotation personnalise des enregistrements dans Access 2010 par Christophe WARIN (Mon espace perso)

Private Sub cmdValider_Click() Me.Refresh End Sub

III-C - Intrt d'une table supplmentaire


Si ce titre n'est pas trs parlant, il suffit d'un simple exemple pour en comprendre toute la porte. Reprenons le jeu d'essai de dpart avec 2 factures pour le mois de dcembre 2009 : FA0912001 et FA0912002. L'utilisateur valide une troisime facture FA0912003 avant de se rtracter. Quel sera le numro de la prochaine ? Dans le modle actuel, ce sera FA0912003 (l'indice 3 ayant t supprim, max(Indice)+1=2+1=3). Pourtant, il serait prfrable qu'elle porte le numro FA0912004 et que l'utilisateur justifie de l'absence de la prcdente plutt que de prendre le risque d'avoir un doublon. En effet, ici, il s'agit d'une simple rtractation de l'oprateur de saisie, mais que se passera-t-il si la dernire facture venait tre supprime cause d'une dfaillance ? Pour pallier ce problme, une solution consiste crer une nouvelle table qui hbergera le dernier indice cr pour chaque priode. Cet indice servira de rfrence et le calcul se fera en toute indpendance du contenu de la table tblFacture. Contenu de la table tblIndiceFacture : Mois 11 12 Annee 2009 2009 Indice 2 2

Le code de l'vnement ValidateChange devient alors :


If [IsInsert] Then SetLocalVar (VIndice;1) LookUp A Record In tblIndiceFacture WHERE [ANNEE]=Year([tblFacture].[DateFacture]) AND [MOIS]=Month([tblFacture].[DateFacture]) ALIAS record If (IsNUll([Indice]) Then SetLocalVar([vIndice];1) Else SetLocalVar([vIndice];[Indice]+1) End If SetField ([Indice];[vIndice]) End If - 11 Copyright 2009 - Warin Christophe. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrets. Droits de diffusion permanents accords developpez LLC.
http://warin.developpez.com/tutoriels/access/numauto2010/

Numrotation personnalise des enregistrements dans Access 2010 par Christophe WARIN (Mon espace perso)

Enfin, l'vnement de table AfterInsert se chargera de modifier le contenu de la table tblIndiceFacture en crant un nouvel enregistrement si besoin est.
Look Up A Record In tblIndiceFacture Where [ANNE]=Year([tblFacture].[DateFacture]) AND [Mois]=Month([tblFacture].[DateFacture]) Alias record If IsNull([Indice]) Then Create a Record In tblIndiceFacture Alias rec_NouvelIndice SetField(Annee;Year([tblFacture].[DateFacture])) SetField(Mois;Month([tblFacture].[DateFacture])) SetField(Indice;1) Else Edit Record Alias record SetField(Indice;Indice+1) End If

Nous avons volontairement spar les deux tapes dans deux vnements diffrents bien que le rsultat aurait t le mme si tout tait rassembl dans l'vnement AfterInsert. Cependant, prparer les donnes dans un vnement Before* tel que ValidateChange en vue de leur insertion nous parat plus proche de la ralit que de les modifier en aval.

- 12 Copyright 2009 - Warin Christophe. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrets. Droits de diffusion permanents accords developpez LLC.
http://warin.developpez.com/tutoriels/access/numauto2010/

Numrotation personnalise des enregistrements dans Access 2010 par Christophe WARIN (Mon espace perso)

IV - Conclusion
Comme promis, Access rvolutionne certaines techniques utilises depuis plus de 15 ans. En confiant certaines tches touchant de prs la cohrence et l'intgrit des donnes au moteur, le dveloppeur Access met toutes les chances de son ct afin de rendre son application la plus robuste possible. Dommage que cela ne soit pas intervenu plus tt... Le recours systmatique au langage VBA pour grer certaines rgles de gestion a particip l'entretien de la rputation SGBD bas de gamme de Microsoft Access. Nul doute qu'Access 2010 saura renverser la vapeur.

- 13 Copyright 2009 - Warin Christophe. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrets. Droits de diffusion permanents accords developpez LLC.
http://warin.developpez.com/tutoriels/access/numauto2010/

Vous aimerez peut-être aussi