Numérotation personnalisée : variante

Suite à cet article sur la numérotation personnalisée, la question suivante a été posée sur le forum self-access.com : « Comment créer une numérotation de la forme YYMM001, YYMM002, sachant que le mois MM est variable, mais que la numérotation est constante sur l’année AA ? ».

Plus de détails

On souhaite ici une numérotation de la forme 0908001, 0908002 en Août ; puis en Septembre : 0909003, 0909004, etc. En Janvier 2010, on souhaite par contre repartir à 1 : 1001001, 1001002, etc. En d’autres termes, l’année sert bien de base de numérotation, mais pas le mois.

… mais le mois doit quand même être intégré au numéro, et sa valeur est dynamique. Et c’est là le problème !

  • Si vous avez lu l’article précédent, vous pourriez être tenté d’utiliser un format de numérotation du type "[YY][MM]". Le problème est que dans ce cas, la numérotation va être du style 0908001, 0908002, etc. (en Août 2009), puis 0909001, 0909002, etc. (en Septembre 2009). Et ainsi de suite. C’est dans cet objectif qu’a été écrite la fonction AutoNumber() à l’origine.
  • C’est uniquement l’année qui sert de déclencheur pour le changement de numérotation. Mais le format "[YY]" ne convient pas non plus, parce que le mois ne sera pas présent dans le code final !

Solution

On devrait pouvoir s’en sortir sans modifier la fonction AutoNumber(). L’idée repose sur le fait que :

  • la base de calcul se fait sur une partie fixe (l’année). Donc on peut garder le préfixe [YY].
  • la comparaison des préfixes (dans le code VBA) se fait par un LIKE SQL, lequel peut contenir des caractères génériques (jokers). AutoNumber() utilise déjà le caractère *, mais on peut aussi faire appel au caractère ?.

Pour la mise en œuvre, remplacez le code VBA du formulaire de saisie (voir l’article précédent) par celui-ci :

  • En pratique, on récupère le numéro de produit avec un préfixe basé sur l’année et sur 2 caractères quelconques (les 2 points d’interrogation). 2 caractères, parce que le mois va être injecté sous la forme 01, 02… 11, 12. Du coup, la fonction AutoNumber() renvoie un numéro de la forme 09??001, 09??002… sans le mois.
  • C’est ensuite qu’on injecte le mois (sur 2 positions précisément) dans le code produit, à l’aide de la fonction Replace().

Vous aimerez aussi...

42 réponses

  1. Angel dit :

    Bonsoir,
    j’utilise votre code AutoNumber
    Me.idDate = AutoNumber(« TOperation », « idDate », « [YY][MM][DD], », 4, [DateOperation])
    qui fonctionne mais je rencontre un problème :
    j’obtiens 171122,0001 171122,0009 Lorsque j’arrive à la saisie N°10 : 171122,001 171122,0002 et la je bloque risque de doublon
    Je ne suis pas très doué en VBa
    Merci de votre réponse
    Cordialement

  2. Junior dit :

    Bonjour.
    mon problème ce que je doit recommencer chaque jour pi je n’arrive pas

  3. ASB dit :

    Bonjour,

    Merci pour la réponse.
    Désolée de ne pas avoir répondu, quelques soucis d’Internet en ce moment.
    Oui c’est ça, c’est une variante de YY00001 avec au 1er Août, Facture YY00001 et à continuer.
    Admettons qu’il y ait 35 factures en Août, la 1ère facture de Septembre sera YY00036.
    10 factures en septembre, la 1ère d’octobre sera YY00046.
    Et ainsi de suite jusqu’au 31 juillet. Admettons que la dernière facture de juillet soit : YY00372, la 1ère d’Août sera ensuite YY00001.
    En fait le YY n’est pas si important puisque je peux le récupérer en faisant PartDate (et qu’il change en cours d’année comptable). L’important est de repartir de 1 au 1er août (date de facture).
    En fait, ça permet de connaître le nombre de factures éditées sur l’année comptable et non sur l’année civile.
    Le truc bien sûr est qu’il ne peut pas y avoir de doublons donc si on ne prend pas le YY en compte mais juste les numéros, on aura forcément des doublons.
    Avez-vous une solution pour ce genre de numérotation ?
    D’avance merci pour la réponse.

    • Hervé Inisan dit :

      Il faut un préfixe commun de Août jusqu’au Juillet suivant. En partant du principe que ce sera l’année, on pourrait faire quelque chose comme ceci, en utilisant la date de référence de la fonction AutoNumber() :

      Une facture de Août 2014 sera numérotée 1500001, et ainsi de suite jusqu’à Juillet 2015.

      • ASB dit :

        Un grand merci pour la réponse.
        Ce n’est pas tout à fait ce que l’on me demande.
        En effet, les factures de Août 2014 devront être 1400001 et celles de Juillet 2015 : 150XXXX. Et l’année comptable d’après, Août 2015 : 1500001 etc.
        Mais bon, je vais essayer de bidouiller avec ce code et le code de départ (avec les ??) et je pense qu’il y a moyen de trouver la solution.
        Je vous tiens au courant.

        • Hervé Inisan dit :

          C’est un peu le sens de ma réponse précédente : il faut un préfixe dans le numéro de facture, ou un autre champ, en tout cas une information qui soit commune sur toute la période, pour calculer le DMax(). S’il n’y a pas de continuité, on ne peut pas directement utiliser le numéro pour le calcul.

          • ASB dit :

            Désolée pour la réponse tardive. Pas d’Internet en vacances !
            Merci beaucoup. Ca marche super.
            J’ai rajouté un champ dans ma table de factures qui permet d’avoir le n° avec le préfixe de référence.
            C’est impec ! Vraiment merci.

          • Hervé Inisan dit :

            Content que ça marche ! 🙂

  4. ASB dit :

    Bonjour,

    J’utilise la numérotation personnalisée et ça fonctionne à merveille ! Merci beaucoup pour ce code !
    J’ai besoin de faire une nouvelle base pour la facturation et on me demande de redémarrer à zéro avec l’année comptable c’est-à-dire au 1 août. Ah ! Ces comptables !!!…
    En fait le numéro doit être comme suit : YYMM00001 avec le numéro qui redémarre au 1 août.
    Où faut-il donner l’information pour qu’il prenne cette date de référence ?
    J’ai fait plusieurs essais mais rien de concluant pour le moment.
    Merci d’avance pour la réponse.

    • Hervé Inisan dit :

      Avec le format YYMM00001, le numéro redémarre automatiquement chaque mois. Ce n’est pas plutôt une variante de YY00001 dont tu aurais besoin ?
      En d’autres termes, comment numérotes-tu exactement en Janvier, puis Février… puis Août, puis Septembre ?

  5. Hervé Inisan dit :

    Landry18 > Dans ce cas, j’imagine qu’il y a 2 tables différentes, et 2 formulaires différents pour la saisie. Pour le formulaire Clients, ça peut donner quelque chose comme ça :

    En adaptant bien sûr les noms de champs et de tables à ton exemple.

  6. Landry18 dit :

    Bonjour!
    j’ai bien parcouru le forum, mais malheureusement j’ai pas trouvé la solution à mon problème. En effet j’aimerai affection aux identifiants de mes tables des identifiants personnalisés tel que CLT001 pour les clients ou alors CDE001 pour les commandes. Comment pourrai je modifier la fonction proposée ci-dessus afin d’avoir ces résultats.
    Merci pour vos contributions

  7. Hervé Inisan dit :

    Nanille > Je prévois un article bientôt pour répondre à la question (plus facile que dans un commentaire). A suivre ! 🙂

  8. Nanille dit :

    Bonjour,
    Je souhaite réaliser une base de donnée pour une collection et j’aimerais que ma clé se crée automatiquement, il faudrait quelle récupère les 3 premières lettre d’un mot d’un premier champ, les 3 première d’un autre et quelle incrémente un numéro ensuite. Sachant que si les 6 lettres sont différentes, une nouvelle incrémentation commence. En plus il y aurait possibilité d’avoir des doublons dans la collection, du coup j’aimerais rajouter une lettre à la suite des chiffres afin de déterminer si c’est le premier exemplaire(a), le deuxième (b)…
    Je suis débutante avec access et me perds un peu avec tous les codes. J’ai réussi à adapter les codes des 2 articles à ma base et cela fonctionne très bien, mais du coup pour le changer et obtenir ce que j’explique plus haut je suis un peu perdue est-ce que quelqu’un pourrait m’éclairer ?

  9. Hervé Inisan dit :

    The-Etudiant > La table que tu veux numéroter est la source du formulaire père, ou du sous-formulaire ?

    Et le code VBA est placé dans le formulaire ou le sous-formulaire ?

  10. The-Etudiant dit :

    Il s’agit d’un formulaire et un sous formulaire, le NAO est dans le formulaire principal et le NLot est dans le sous-formulaire

  11. The-Etudiant dit :

    Voila, c’est parce qu’il s’agit d’un formulaire ou le NAO est créer automatiquement, avec un sous formulaire pour saisir les Lots. Alors le NAO vient du formulaire père.

  12. Hervé Inisan dit :

    The-Etudiant > Effectivement, pas facilement de répondre sans toutes les infos… 😉

    Dans ton dernier exemple, d’où vient NAO ? D’après ce que je vois, ce serait un champ du formulaire (ou de la  table sous-jacente) ?

  13. The-Etudiant dit :

    Je crois que je me suis mal exprimé, il y a 3 tables: « DCE » avec « N°Ordre » comme clé primaire, « AO » avec la clé « NAO », et la table « Lots » qui a comme clé « NLot ».
    Jusqu’à présent, j’ai réussi la numérotation de la table DCE et AO,
    pour automatiser le NLot j’ai écris le code suivant:

    Private Sub Form_BeforeUpdate(Cancel As Integer)
    Dim strCode As String

    If IsNull(Me.NLot) Then
    strCode = AutoNumber(« Lots », « NLot », « ???????????????? », 2)
    strCode = Replace(strCode, « ???????????????? », NAO +  » Lot « )
    Me.NLot = strCode
    End If
    End Sub

    et les problèmes rencontrés sont cités ci-dessus

  14. Hervé Inisan dit :

    The-Etudiant > Par « VBA », j’entendais en fait le bout de code que tu utilises. Dans le doute, je reprends celui de ton message précédent…

    Si j’ai suivi, il faudrait que tu écrives quelque chose comme ça, pour obtenir ta numérotation :

    Le 1 dans AutoNumber() numérotera sur 1 chiffre. Mais si tu peux avoir plus de 9 lots, utilise au moins 2.

    En passant : si AO_NAO est une clef primaire, elle n’est pas très pratique à manipuler… 😉

  15. The-Etudiant dit :

    J’utilise la version 7 du VBA, et le code du lot doit être composé du code d’AO (exemple: 21-2012 A/T)+ « Lot » + numéro incrémenté. pour obtenir:
    21-2012 A/T Lot 1
    21-2012 A/T Lot 2…
    32-2012 EP/T&F Lot 1
    32-2012 EP/T&F Lot 2…
    Le numéro incrémenté doit dépendre du code d’AO.

  16. Hervé Inisan dit :

    The-Etudiant > Par rapport à tes questions précédentes : quel VBA est-ce que tu utilises maintenant pour construire ton code ? Et où (et comment) ce code doit-il être numéroté ?

  17. The-Etudiant dit :

    Merci beaucoup.
    J’ai deux autres petites questions.
    Après avoir automatisé le code qui permet d’avoir ce format: 21-2012 A/T , ce dernier fait référence a une table qui au fait contient des lots, alors j’essaye de créer le code suivant:
    21-2012 A/T Lot 1
    21-2012 A/T Lot 2…
    32-2012 EP/T&F Lot 1
    32-2012 EP/T&F Lot 2…
    J’ai rencontré 2 problèmes:
    – le 1er c’est que les « ?? » remplace un seul caractère et le code de la 1ere table n’a pas une taille fixe (comme cité dans l’exemple).
    – le 2eme c’est que même en changeant le 1er code (de 21-2012 A/T à 32-2012 EP/T&F) le numéro ne se réinitialise pas à 1.

  18. Hervé Inisan dit :

    The-Etudiant > Pour le cas d’un sous-formulaire, il faut que tu places le code dans l’événement Avant MAJ aussi (BeforeUpdate), mais l’événement du sous-formulaire, et pas l’événement du formulaire principal.

  19. Hervé Inisan dit :

    The-Etudiant > A vue de nez, il suffit que tu fasses :

  20. The-Etudiant dit :

    Merci, c’est bien ce que je voulais, la seule chose qui me reste c’est d’effectuer cette numérotation automatique dans un sous-formulaire. Le problème est le numéro qui ne s’incrémente pas

  21. The-Etudiant dit :

    Voila le code:
    Private Sub Form_BeforeUpdate(Cancel As Integer)
    Dim strCode As String

    If IsNull(Me.AO_NAO) Then
    strCode = AutoNumber(« AO », « NAO », « ?? « , 0)
    strCode = Replace(strCode, « ?? », N°Ordre +  »  » + Left(Metier, 1) + « / » + Left(Prestation, 1))
    Me.AO_NAO = strCode
    End If
    End Sub

    Comment puis-je éliminé le Autonumber()?

  22. Hervé Inisan dit :

    The-Etudiant > La partie 21-2012 vient de l’autre table ? Et tu lui ajoutes A/T, c’est bien ça ? Ton code est généré par concaténation de ces valeurs ?

    Dans ce cas, tu n’as pas besoin de la fonction AutoNumber(), si tu ne veux pas de numérotation.

    Ou bien…?

  23. The-Etudiant dit :

    Merci beaucoup
    j’ai une autre question, j’ai réalisé un code qui ce génère a partir du code d’une autre table avec un rajout de quelques abréviations:
    exemple: a partir du code 21-2012 le code généré sera 21-2012 A/T (les abréviations sont choisies a partir des listes déroulantes)
    j’ai réglé tout ça mais mon problème au fait est d’éliminé le numéro incrémenté, car pour l’instant j’ai le format 21-2012 A/T 001

  24. Hervé Inisan dit :

    The-Etudiant > Voir mes réponses à Islemus et à Yohan sur le premier article de la série. Pour faire court 🙂 : j’aurais tendance à ne pas suivre cette idée.

    Par contre, rien n’empêche de numéroter « façon AutoNumber », et d’afficher l’inverse. Il suffirait d’écrire une fonction qui inverse le numéro créé par AutoNumber, juste pour l’affichage. Fonction qui serait utilisée sur un formulaire ou sur un état, par exemple.

  25. The-Etudiant dit :

    Bonjour,
    Est-il possible de commencer par le numéro incrémenté?
    sous le format 01-2012 02-2012 ….
    Merci

  26. mick dit :

    C’est tout à cela.
    Merci encore

  27. Hervé Inisan dit :

    Mick > La table de paramètres peut être effectivement stockée dans la base frontale ou dorsale.

    Dans ce que j’avais compris initialement, les utilisateurs étaient codifiés par leur unité, mais pouvaient éventuellement se connecter à une autre base dorsale en conservant leur identification. En d’autres termes, un utilisateur de l’unité « 00 » devait être identifié comme « 00 » même s’il se connectait à l’unité « 01 ».

    Si j’ai compris la dernière remarque, ce serait l’unité (la dorsale) qui dicte le code. Si l’utilisateur initial de « 00 » se connecte à « 01 », c’est le code « 01 » qui est pris en compte. Dans ce cas, ce serait bien un paramétrage par la base dorsale.

  28. Mick dit :

    Merci pour ces renseignements et votre aide précieuse.

    J’ai procédé selon vos recommandations en créant une table de paramètres.
    Pour le moment c’est table ne comporte que le paramètres « Unité » (IDPC). J’ai créé une fonction pour récupérer le paramètre [ GetParam = Nz(DLookup(…)) ].
    Ensuite dans la fonction AutoNumber() j’ai rajouté l’appel de paramètre [ AutoNumber(table,champ,getparam(« IDPC ») & « [YY][MM][DD] »,2, me!Date) ].

    Pour ce qui est du stockage de la table paramètre, je pensais davantage la placer sur la base dorsale.
    De cette façon les frontales connectés à cette base travaillerais sur des enregistrements « codifiés » sur le même patron.
    Une autre installation base dorsale + frontale, installé sur un ordi portable par exemple, non connectée à l’unité principale (par exemple le siège de l’entreprise) pourrait produire des enregistrements qui au moment de la synchronisation n’entrainait pas de conflit dû à l’existence de doublon.

    J’imagine effectivement qu’une table paramètre propre à chaque frontale permettrait de distinguer les enregistrements produits mais il n’y aurait alors plus l’identification par sites (siège, succursale, ordi portable en autonome).

    Que pensez vous de ce raisonnement? 🙂

  29. Hervé Inisan dit :

    Mick > Je ne stockerais pas la valeur sous forme de constante dans un module. D’une part parce que ce n’est pas vraiment une constante (sa valeur varie en fonction de l’unité) ; d’autre part parce qu’une constante nécessiterait une intervention à chaque installation de la partie frontale (ce qui peut être lourd si on travaille en MDE/ACCDE).

    Une table de paramètres serait plus pratique (l’unité étant l’un des paramètres, il peut y en avoir d’autres à long terme). A vue de nez, je placerais cette table dans la base frontale, de manière à ce que chaque utilisateur dispose de son propre paramètre d’unité. Pour faire bien, un formulaire permettant de modifier ces paramètres…

    Pour enchaîner sur AutoNumber(), il faudrait donc lire le paramètre de la table (un DLookup() peut suffire), et l’injecter dans le format. Si strUnite est l’unité obtenue de la table de paramètres, le format devient strUnite & " [YY][MM][DD] " (en tenant compte des espaces de séparation).

    Dans les grandes lignes… 🙂

  30. Mick dit :

    Bonjour,
    Effectivement cette méthode de numérotation est très bien.
    Quels seraient vos conseils dans le cas suivant:
    A mon numéro auto je souhaite ajouter un préfixe sur 2 caractères, comme « 00 » « 01 » etc…
    Un peu dans l’esprit de la réplication, ce préfixe viendrait identifier les enregistrements créés par telle ou telle unité (unité=ensemble de poste travaillant sur une base dorsale).
    Par exemple, une facture élaborée sur le site A (00) serait identifié par « [Préfixe][YY][MM][DD][numéro] » soit « 00 110706 0001 » alors qu’une facture du site B (01) donnerait « 01 110706 0001 ».
    Au sein de la fonction autonumber(), cela consiste uniquement dans l’ajout d’un variable supplémentaire… mais comment gérer cette variable qui est une « constante » propre à chaque unité?
    Si je déclare cette constante dans un module, comment puis-je attribuer cette donnée lors de l’installation d’un instance de ma base de donnée frontale sans avoir à le faire manuellement en changeant la constante dans mon module?
    Merci d’avance pour vos suggestions

  31. Hervé Inisan dit :

    milo1820 > Normalement, le paragraphe « Le formulaire de saisie », sur l’article Numérotation personnalisée devrait répondre à la question.

  32. milo1820 dit :

    Bonjour,
    J’ai mis en application votre méthode de numérotation auto et je l’ai trouvé géniale !
    Il me reste toutefois un petit problème à résoudre…
    Comment faire pour afficher ce numéro personnalisé dans mon formulaire avant de passer à l’enregistrement suivant ?
    Merci d’avance

  33. Hervé Inisan dit :

    wagolo > Pour réinitialiser le NuméroAuto, il faut d’abord vider la table, puis compacter la base de données.

  34. wagolo dit :

    Est-il possible de remettre un numeroAuto a zero?
    je vous remercie

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *