lundi 7 février 2011

Access : issue avec les dates (condition >= Now())

Access07 Je vous propose d’aborder dans ce billet une problématique assez ennuyeuse en rapport avec les dates. Ce problème a été soulevé lors d’une discussion sur le forum MSDN Développement Access comme suit:

Supposons que vous avez une table “Taches” avec comme champs “Num_Tache”, “Nom_Tache”, “Duree_Tache” et “DateFinPrevue_Tache” et que vous souhaitez afficher à l’aide d’une requête la liste des tâches qui devraient se terminées à partir d’aujourd’hui et au delà.

Créez un jeu de données incluant des tâches avec des dates de fin prévues antérieures à la date du jour, égales à la date du jour et postérieures à la date du jour puis créer votre requête.

Lors de la création de votre requête, vous serrez peut être tenté de procéder comme suit :

Select Taches.Nom_Tache
From Taches
Where DateFinPrevue_Tache >=Now();

Ce qui correspond, en mode création de requête, à ajouter dans la colonne du champ “DateFinPrevue_Tache” sur la ligne “Condition” l’expression “>=Now()”.

Si c’est le cas, exécutez votre requête puis observez le résultat. En y regardant de plus près vous remarquerez que les tâches avec une date étant égale à la date du jour en cours ont étaient exclues et que la liste des tâches ne contient en fait que celles ayant une date postérieure à la date du jour.

Pourquoi ce résultat ?

Pour y répondre, retenez (ou souvenez-vous) d’abord que :

Pour Access comme Excel, une date n’est rien d’autre qu’un numéro de série composé de deux (02) parties, la partie entière qui désigne le nombre de jour écoulés depuis une date de référence et la partie décimale qui représente le moment dans la journée (heures, minutes, secondes).

Sachant que le jour 1,00 (qui a pour référence le 01/01/1900 à 00h00 et qui peut aussi être défini au 01/01/1904), le numéro de série qui correspond au 07/02/2011 à 00h00 est 40581,00 le même jour à midi sera le 40581,50 et à 18h00 nous avons 40581,75

Sachez ensuite que :

Lorsque vous saisissez une date du style “07/02/2011” par exemple et n’ayant pas ajouter l’heure, l’application n’enregistrera que la partie entière du numéro de série. Donc dans notre cas 40581

Enfin retenez que :

La fonction Now() renvoie le numéro de série de la date système à l’instant où elle est exécutée. SI je l’exécute par exemple le 07/02/2010 à 09h00 la valeur qui sera considérée est 40581,25.

En conclusion :

Le numéro de série renvoyé par les tâches ayant une date de fin prévue le jour en cours étant toujours inférieur au numéro de série renvoyé par la fonction Now() ces tâches seront toujours exclues du résultat de la requête.

La solution

  • Certains seraient peut être tenter de saisir des dates complètes du style “07/02/2010 12:00:00” pour indiquer midi. cela résoudra le problème si vous exécutez votre requête avant midi mais à midi et une seconde votre solution sera obsolète. De plus, il n’est pas très pratique de saisir systématiquement la date sous cette forme.
Mais alors comment faire ?

La première solution qui m’est venu à l’esprit était d’utiliser la fonction “SérieDate(année; mois; jour)” (ou DateSerial(Year; Mounth;Day)) en la combinant aux fonctions Maintenant() (ou Now()), Année(), Mois() et Jour() de la manière suivante : SérieDate(Année(Maintenant());Mois(Maintenant());Jour(Maintenant())).

Puis dans le fil de discussion, une solution plus adéquate a été proposée par un participant (Blaise032). Cette solution consiste tout simplement à remplacer la fonction Now() par la fonction Date() qui ne renvoi que la partie entière du numéro de série de la date. Il est vrais qu’avant de proposer la première solution j’avais cherché sous Access la fonction TODAY() (qui existe sous Excel) sans la trouver. Ce n’est qu’en lisant la proposition de Blaise032 que j’ai compris que l’équivalent de la fonction Excel TODAY() est la fonction Access DATE().

La syntaxe SQL de la requête sera donc :

Select Taches.Nom_Tache
From Taches
Where ((Taches.DateFinPrevue_Tache)>=Date());

Ce qui correspond, en mode création de requête, à remplacer dans la colonne du champ “DateFinPrevue_Tache” sur la ligne “Condition” l’expression “>=Now()” par “>=Date()”.

N’hésitez pas à laisser vos commentaires.

Mots clés Technorati : ,,,,,

Aucun commentaire:

Enregistrer un commentaire