Extraire des dates anniversaires

Dans une table Access, j’ai une liste de personnes. Chaque enregistrement contient la date d’anniversaire de la personne, dans un champ de type Date/Heure. Comment extraire les personnes dont c’est l’anniversaire aujourd’hui ?

La requête

Access propose plusieurs fonctions de manipulations de dates, voici une solution possible parmi d’autres :

  1. Créez une requête graphique reposant sur la table des personnes.
  2. Déposez sur la grille de requête tous les champs qui vous intéressent (sans doute le nom, le prénom, la date de naissance…).
  3. Ajoutez le champ calculé suivant :
    Date JJMM: Format([Date de naissance];"ddmm")

    Selon votre version d’Access, remplacez "ddmm" par "jjmm". Cette formule formate la date d’anniversaire sous la forme jour/mois uniquement (l’année ne nous sert pas pour l’anniversaire). Si une personne est née le 13/07/1984, vous obtenez 1307. Date JJMM est le nom de la colonne de calcul, vous pouvez bien sûr le modifier ; vous pouvez aussi masquer cette colonne si elle n’est pas utile dans la feuille de résultats.

  4. Sur la ligne Critères associée au champ calculé précédent, ajoutez le critère suivant :
    =Format(Date(); "ddmm")

    On formate la date du jour avec les mêmes contraintes. Si la date de votre ordinateur est le 13/07/2008, vous allez obtenir également 1307. En cas d’égalité, on extrait bien les anniversaires.

Extraire les anniversaires en avance 🙂

Dans l’exemple du dessus, vous extrayez les personnes dont c’est l’anniversaire le jour même. Mais vous souhaiterez peut-être extraire ces personnes un peu à l’avance, par exemple pour préparer l’expédition d’un courrier. Dans ce cas, remplacez simplement la deuxième formule par quelque chose comme :

Le +10 extrait les personnes dont la date de naissance tombe dans 10 jours.

Déclencher une alerte automatique à la date anniversaire

Une fois terminée, votre requête fournit la liste des anniversaires. Maintenant, si vous souhaitez aller plus loin et afficher automatiquement un formulaire avec cette liste de personnes, ou expédier un e-mail à ces personnes, consultez ces autres articles du Grenier :

Vous aimerez aussi...

25 réponses

  1. Hervé Inisan dit :

    Neo62 > Quel est le code VBA qui analyse les mails ? C’est lui qui alimente la deuxième table, j’imagine. Il ne garde pas de liaison avec la première ?

    PS : Comme la conversation n’a plus de rapport avec l’article, il vaut mieux continue sur les forums self-access.com. Ce sera plus pratique.

  2. Neo62 dit :

    Bonjour,

    Non, le mail est lié à plusieurs lignes de données. Il faudrait donc bien 2 tables mais je ne vois pas comment faire puisque les mails importés contiennent, par définition, les données des 2 tables à construire!

  3. Hervé Inisan dit :

    Neo62 > Le message n’a pas été supprimé, il était juste en attente (les commentaires ne sont pas postés automatiquement : je les valide avant pour éviter le spam).

    Pour revenir à la question :

    • Si on garde le principe de 2 tables, il faut effectivement que la clef primaire de la table des mails reçus soit liée à une clef étrangère dans la table des données.
    • Maintenant, il faut trouver la structure correcte : est-ce qu’un mail est associé à une ligne de données (et une seule), ou est-ce qu’un mail est associé à plusieurs lignes de données ? Dans le premier cas, la deuxième table n’est pas utile, puisque les données dépendent directement du mail reçu.
  4. Neo62 dit :

    Bonsoir,

    C’est curieux, je vous ai répondu hier soir mais mon message n’apparait pas. Aurait-il été supprimé?
    Bonne soirée et merci.

    Joseph

  5. Neo62 dit :

    Bonjour,

    Je vais essayer d’être plus clair: le mail contient effectivement plusieurs infos à extraire ( T° ext, T° intér, Humid ext, humid intér, Pression atm, wind chill, heat index, vitesse du vent, etc… ) et je reçois 3 mails par jour de ma station. Donc, je dois procéder à des importations régulières de ma boite mail Outlook. Donc en résumé:
    1 table contenant 3 champs ( N° auto, date et heure de réception, champ mémo contenant le message dont je dois extraire les données ) et une autre table où je vais, via un code VBA, insérer toutes les données citées plus haut et qui sont extraites de la première table. Donc, je pourrais relier les tables via une clé primaire (N° auto) de la première table et une clé étrangère dans la seconde table, c’est bien ça?
    Vous pensez que c’est correct?
    Merci d’avance.

    Joseph

  6. Hervé Inisan dit :

    Neo62 > Je n’ai pas une vue d’ensemble du projet, mais voici quelques pistes (ou questions) :

    1. Est-ce qu’il faut que les données extraites à partir du mail soient dans une table différente ? A priori, je me dis qu’elles sont directement liées au mail, par une relation 1:1 (1 mail => 1 série d’infos extraites). A moins que chaque mail contienne plusieurs lignes d’informations, et qu’on ait une relation 1:n ?
    2. Dans le cas où tout est dans une seule table, le problème est réglé. 🙂
    3. Dans le cas contraire, il faut que les 2 tables soient reliées, sinon on perd des infos.
    4. Et dans ce cas, on peut créer une requête (graphique ou SQL) qui extrait les infos des 2 tables. Cette requête peut être manipulée par Recordset si nécessaire.

    En résumé, et pour répondre à la question du départ, un Recordset ne manipule qu’une seule source de données (l’équivalent d’une grille de résultats dans une requête Access). Mais cette source peut être basée sur plusieurs tables, si elles sont reliées.

  7. Neo62 dit :

    Bonsoir,

    Merci pour votre réponse. Je profite de l’occasion pour vous poser un autre petit problème: d’abord, est-il possible de fusionner 2 tables de structures différentes? Par exemple, une table avec 3 champs et une autre table avec 7 champs de telle sorte d’obtenir une seule table avec 10 champs en tout provenant de tables différentes.
    Ensuite, peut-on ouvrir, avec un seul recordset, 2 tables différentes, avec 1 instruction SQL qui ouvrent ces 2 tables par exemple?
    En fait, je vous expose mon problème. Je possède une station météo sur mon observatoire ( je suis passionné d’astronomie 🙂 )qui via un serveur, m’envoie 3 e-mails par jour avec des données météo diverses. Mon but étant de les stocker dans une base de données, j’importe mes e-mails Outlook dans une table qui possède 3 champs dont 1 avec le contenu et toutes les données. Via un code VBA, je manipule le champ mémo de l’e-mail, de manière à extraire uniquement les données qui m’intéressent pour pouvoir les inclure automatiquement dans les 7 champs de l’autre table. Le problème, c’est que j’ai 2 tables avec l’une contenant les mails importés et l’autre les données que je suis sensé importer du champ mémo de la première table. Mais comme je n’arrive pas à ouvrir, les 2 tables avec un seul recordset, je nage un peu.
    Voyez-vous le problème? Qu’en pensez-vous?
    Merci d’avance.

    Joseph

  8. Hervé Inisan dit :

    Neo62 > La raison est que les 2 dates ne sont pas identiques. Pour mieux comprendre, il vaut mieux enlever le calcul de division par 365.25. On obtient ça dans le premier cas :

    Aujourd’hui, ce calcul me donne 18153 jours. Mais « 07/11/1962 » est une chaîne de caractères (pas une date). Elle est convertie par Access comme date anglo-saxonne : #11/07/1962#, et pas 07/11/1962 francophone. Il s’agit donc du 7 novembre 1962.

    Dans le deuxième cas, on obtient ça :

    La date est cette fois-ci explicite (et déjà au format anglo-saxon). Il s’agit du 11 juillet 1962. Aujourd’hui, ça donne 18272 jours. Ce qui fait 119 jours de différence.

    L’approche la meilleure est de passer par une « vraie date », au format #mm/jj/aaaa# (en VBA ou SQL). Il n’y a pas de conversion, donc pas d’ambiguïté. Il y a quelques compléments sur l’article Dates anglo-saxonnes.

  9. Neo62 dit :

    Bonjour,

    D’abord merci et bravo pour vos codes qui sont une grande source d’inspiration.
    Voici ma question:

    int(datediff(« d », « 07/11/1962 », date())/365.25) donne 49
    tandis que
    int(datediff(« d », #07/11/1962#, date())/365.25) donne 50

    Pourriez-vous m’expliquer pourquoi?
    Merci d’avance

  10. Hervé Inisan dit :

    marcouqc > Si seul le mois doit être pris en compte, il devrait suffire de remplacer les "ddmm" de l’exemple par "mm" seulement.

    On peut aussi créer un champ calculé du style Le Mois: Month([Date de naissance]) et lui appliquer un critère du genre Month(Date())

    Ouala !

  11. marcouqc dit :

    Je veux extraire par une requête Access 2007 toutes les personnes qui ont leur anniversaire de naissance durant le mois de novembre, par exemple, sans tenir compte de l’année. Je n’y arrive pas.
    Merci!

  12. Hervé Inisan dit :

    flo69630 > Je viens de vérifier sur un Access 2007 (français), le format est "jjmm" au lieu de "ddmm". Et ça fonctionne comme il faut. Effectivement, il ne doit pas y avoir de guillemets supplémentaires (ce qui voudrait dire que le format n’a pas été reconnu).

  13. flo69630 dit :

    Je viens d’essayer vos différents conseils, mais rien ne change. Mon Access 2007 me rajout automatiquement des guillemets ce qui me fait la formule suivante:

    Date JJMM: Format([Date de naissance]; » » »dd » »mm »)

    est-ce que ça change tout?

  14. Hervé Inisan dit :

    flo69630 > Tu as essayé de mettre ddmm entre les guillemets de la fonction Format(), au lieu de jjmm ? Selon les versions d’Access, ça peut jouer, comme indiqué dans l’article.

  15. flo69630 dit :

    Le champ est bien un date/heure, et la saisie se fait bien sous forme jj/mm/aaaa/

    Dans ma colonne Date JJMM, j’ai jj05 qui apparait (il détecte bien que nous sommes au mois de Mai, mais pas le jour que nous sommes.

    Désolé de revenir répondre que maintenant.

    Cordialement

  16. Hervé Inisan dit :

    @flo69630 Quelques trucs à vérifier au cas où :

    • Est-ce que le champ de la table est bien de type Date/Heure ?
    • Est-ce que la saisie dans ce champ a bien été faite sous la forme jj/mm/aaaa (genre : 15/12/2010) ?
    • Qu’est-ce qui s’affiche dans la requête, en résultat de la colonne Date JJMM ?
  17. flo69630 dit :

    oui, je rentre exactement ce qu’il y a sur a capture d’écran. Mais les résultats qui en ressortent sont l’affichage dont l’anniversaire est le mois même.

    merci quand meme.

  18. Hervé Inisan dit :

    @flo69630 Euh… C’est toi qui tape les critères dans la requête, donc tu vois forcément les valeurs que tu tapes (?). Tu dois obtenir le même résultat que dans la capture d’écran plus haut.

  19. flo69630 dit :

    je en sais pas. Comment savoir? J’utilise access 2007 actuellement. Merci pour votre aide.

  20. Hervé Inisan dit :

    @flo69630 Tu as bien un « ddmm » ou un «  »jjmm » en format ?

  21. flo69630 dit :

    Bonjour,

    Lorsque j’utilise ce code, ma requete me donne tous les gens qui sont nées le mois meme, et non pas le jour meme. Pourrait-on m’expliquer ce que j’ai mal fait?

    Merci

    Cordialement

  22. Hervé Inisan dit :

    Gonzu > Assez d’accord : lorsque la période chevauche 2 années, il n’est plus possible de se baser uniquement sur le jour et le mois.

    Dans l’idée de départ, il s’agissait d’extraire les dates par une égalité (et là, ça marche). Maintenant, pour cibler par période, il faut aménager un peu. Un article bientôt ? 🙂

  23. Gonzu dit :

    Bonne formule, mais le soucis est que lorsque l’on passe de décembre à Janvier par exemple, cela ne marche pas!
    car on va vouloir une valeur comprise entre 12xx et 01xx, autrement dit, on va avoir toutes les dates de naissances de la table!

  24. Anto dit :

    Très bonne astuce, mais si je peux me permettre, il plus judicieux de mettre le format sous la forme « mmdd ».
    Je m’explique, si l’on veux sortir la liste des personnes dont l’anniversaire tombe dans moins de 10 jours, on peut alors utiliser un
    Entre Format(Date(); « mmdd ») Et Format(Date() + 10; « mmdd »)

    Ceci ne peux fonctionner si on laisse le jour en premier. De plus, on peut appliquer un tri directement.

    Cordialement

Laisser un commentaire

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