begin process at 2008 05 17 03:05:36
1 173 899 membres
32 nouveaux aujourd'hui
13 973 membres club

Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum.
Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

FORMAT DE DATE SYSTEM ET PORTABILITÉ


Information sur la source

Catégorie :Base de Donnees Classé sous : format, date, portabilité, insertion, région Niveau : Débutant Date de création : 29/06/2007 Date de mise à jour : 02/07/2007 15:55:41 Vu / téléchargé: 5 769 / 382

Note :
Aucune note

Commentaire sur cette source (17)
Ajouter un commentaire et/ou une note

Description

Ce bout de code a été écrit afin gérer les dates (insertion et lecture dans la base de données) quelque soit les paramètres régionnaux du système (en supposant que l'utilisateur saisie une date dans le format de son pays, message d'erreur si ce n'est pas le cas).
J'ai eu à écrire ce code à cause de la non portabilité d'un programme utilisé dans des pays étrangers dû au format des dates.
Une des fonctions disponible dans ce code permet donc de récupérer le format du système afin d'informer l'utilisateur sur comment renseigner les dates en vue d'une insertion. Cette fonction retourne une chaîne type 'dd/mm/yyyy' (d pour jour, m pour mois, y pour année) qui sera affichée dans un label.

Pour tester ce code, modifier les paramètres régionnaux de votre système (sous XP, dans Panneau de configuration > Options régionnales et linguistiques)) et relancer le formulaire à chaque modifications

Ce code n'a été testé que sous XP !


Source

  • Option Compare Database
  • Option Explicit
  • 'Déclaration des APIs
  • Private Declare Function GetLocaleInfo Lib "kernel32.dll" Alias "GetLocaleInfoA" ( _
  • ByVal locale As Long, _
  • ByVal lctype As Long, _
  • ByVal lplcdata As String, _
  • ByVal cchdata As Long _
  • ) As Long
  • Private Declare Function GetUserDefaultLCID Lib "kernel32" () As Long
  • 'Constante passée à la fonction GetLocaleInfo afin qu'elle renvoie le format de la date courte
  • ' Pour plus d'infos et avoir la liste des constantes http://support.microsoft.com/kb/177146/fr
  • Const Format_Date_Courte = &H1F
  • Private Sub Form_Load()
  • 'On initialise le label avec le format de la date courte renvoyé par le systeme
  • format_date.Caption = ReturnFormat(Format_Date_Courte) 'retour du format de la date courte
  • End Sub
  • Private Sub Inserer_Click()
  • Dim request As String
  • 'On empêche tout message d'alerte en cas d'insertion dans la base de données
  • DoCmd.SetWarnings False
  • 'On test si la date à insérer est bien une date
  • If Not IsDate(date_test.Value) Then
  • 'Message d'erreur si ce n'est pas le cas
  • MsgBox "erreur!", vbCritical
  • Else
  • 'Sinon, on insère la date dans la table concernée
  • 'Copnstruction de la requête
  • request = "INSERT INTO test (date_test) VALUES (#" & Format$(date_test.Value, "MM\/DD\/YYYY") & "#);"
  • 'Exécution de la requête
  • DoCmd.RunSQL request
  • End If
  • End Sub
  • Private Sub Chercher_Click()
  • 'Fonction qui compte le nombre de date recherchée dans la base de donnée
  • Dim request As String
  • Dim rst As DAO.Recordset
  • 'On test si la date à insérer est bien une date
  • If Not IsDate(date_recherche.Value) Then
  • 'Message d'erreur si ce n'est pas le cas
  • MsgBox "erreur!", vbCritical
  • Else
  • 'Sinon, on recherche la date dans la table
  • 'Construction de la requête
  • request = "SELECT Count(1) AS Nb " & _
  • "FROM test " & _
  • "WHERE test.date_test=#" & Format$(date_recherche.Value, "MM\/DD\/YYYY") & "#;"
  • Set rst = CurrentDb.OpenRecordset(request, dbOpenDynaset, dbReadOnly)
  • 'Affichage du résultat
  • MsgBox "Nb de """ & CDate(date_recherche.Value) & """ : " & rst("Nb")
  • End If
  • End Sub
  • Private Function ReturnFormat(type_retour As String) As String
  • 'Création du format de la date system
  • Dim locale As Long, lctype As Long, lplcdata As String, cchdata As Long, nretval As Long, dwLCID As Long
  • 'Préparation des paramètres de la fonction GetLocaleInfo
  • locale = GetUserDefaultLCID()
  • lplcdata = Space(255)
  • cchdata = Len(lplcdata)
  • nretval = 0
  • 'On récupère le format de la date dans le tableau lplcdata
  • nretval = GetLocaleInfo(locale, type_retour, lplcdata, cchdata)
  • 'Dans le cas ou la valeur de retour est 0 => on renvoie vide ""
  • If nretval = 0 Then
  • ReturnFormat = ""
  • Else
  • 'Sinon on renvoie le format de la date
  • ReturnFormat = LCase(lplcdata)
  • End If
  • End Function
Option Compare Database
Option Explicit

'Déclaration des APIs
Private Declare Function GetLocaleInfo Lib "kernel32.dll" Alias "GetLocaleInfoA" ( _
                    ByVal locale As Long, _
                    ByVal lctype As Long, _
                    ByVal lplcdata As String, _
                    ByVal cchdata As Long _
) As Long
Private Declare Function GetUserDefaultLCID Lib "kernel32" () As Long

'Constante passée à la fonction GetLocaleInfo afin qu'elle renvoie le format de la date courte
' Pour plus d'infos et avoir la liste des constantes http://support.microsoft.com/kb/177146/fr
Const Format_Date_Courte = &H1F

Private Sub Form_Load()
    'On initialise le label avec le format de la date courte renvoyé par le systeme
    format_date.Caption = ReturnFormat(Format_Date_Courte) 'retour du format de la date courte
End Sub

Private Sub Inserer_Click()
    Dim request As String
    'On empêche tout message d'alerte en cas d'insertion dans la base de données
    DoCmd.SetWarnings False
    
    'On test si la date à insérer est bien une date
    If Not IsDate(date_test.Value) Then
        'Message d'erreur si ce n'est pas le cas
        MsgBox "erreur!", vbCritical
    Else
        'Sinon, on insère la date dans la table concernée
        
        'Copnstruction de la requête
        request = "INSERT INTO test (date_test) VALUES (#" & Format$(date_test.Value, "MM\/DD\/YYYY") & "#);"
        'Exécution de la requête
        DoCmd.RunSQL request
    End If
End Sub


Private Sub Chercher_Click()
    'Fonction qui compte le nombre de date recherchée dans la base de donnée
    Dim request As String
    Dim rst As DAO.Recordset
        
    
    'On test si la date à insérer est bien une date
    If Not IsDate(date_recherche.Value) Then
        'Message d'erreur si ce n'est pas le cas
        MsgBox "erreur!", vbCritical
    Else
        'Sinon, on recherche la date dans la table
        
        'Construction de la requête
        request = "SELECT Count(1) AS Nb " & _
                  "FROM test " & _
                  "WHERE test.date_test=#" & Format$(date_recherche.Value, "MM\/DD\/YYYY") & "#;"

        Set rst = CurrentDb.OpenRecordset(request, dbOpenDynaset, dbReadOnly)

        'Affichage du résultat
        MsgBox "Nb de """ & CDate(date_recherche.Value) & """ : " & rst("Nb")
    End If
End Sub

Private Function ReturnFormat(type_retour As String) As String
    'Création du format de la date system
    Dim locale As Long, lctype As Long, lplcdata As String, cchdata As Long, nretval As Long, dwLCID As Long
    
    'Préparation des paramètres de la fonction GetLocaleInfo
    locale = GetUserDefaultLCID()
    lplcdata = Space(255)
    cchdata = Len(lplcdata)
    nretval = 0
    
    'On récupère le format de la date dans le tableau lplcdata
    nretval = GetLocaleInfo(locale, type_retour, lplcdata, cchdata)
    
    'Dans le cas ou la valeur de retour est 0 => on renvoie vide ""
    If nretval = 0 Then
        ReturnFormat = ""
    Else
        'Sinon on renvoie le format de la date
        ReturnFormat = LCase(lplcdata)
    End If
End Function

Pour les "Membres Club", vous pouvez télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !
  • Gestion_dates_portabilité_Etranger.mdbTélécharger ce fichier [Réservé aux membres club]245 760 octets
  • print_screen.JPGTélécharger ce fichier [Réservé aux membres club]Voir ce fichier64 192 octets

Télécharger le zip

02 juillet 2007 11:07:00 :
Modifications des requètes d'insertion/lecture
02 juillet 2007 15:55:41 :
Suite aux remarques, la fonction générant le format de la date courte du système à été abandonnée et remplacée par l'API GetLocaleInfo(...)
  • signaler à un administrateur
    Commentaire de DARKSIDIOUS le 29/06/2007 15:47:08 administrateur CS

    Y'a un truc qui me choque :
    "INSERT INTO test (date_test) VALUES ('" & CDate(date_test.Value) & "');"

    Les dates en SQL access doivent être entourées de dièses et être au format américain... à moins que tu ne l'enregistre dans un champ de type texte, mais là c'est pas très optimisé !

    DarK Sidious

  • signaler à un administrateur
    Commentaire de Renfield le 29/06/2007 16:00:40 administrateur CS

    aïe...

    tu as fait tout ce qu'il ne faut pas faire, au contraire.
    c'est un sujet qui m'est cher, et ton code ne va pas.


    les manipulations de dates en SQL se font comme cela :
    "INSERT INTO test (date_test) VALUES (#" & Format$(date_test.Value,"MM\/DD\/YYYY") & "#);"

    on s'affranchit au plus tôt des parametres regionnaux.


    comme nous y invite ton interface, j'ai saisi 02/09/2007
    (deux septembre 2007)

    mais ton code :
    "INSERT INTO test (date_test) VALUES ('" & CDate(date_test.Value) & "');"
    execute
    ... VALUE('02/09/2007')

    qui sera interpreté par Access, via les parametres regionnaux...
    bonjour le 9 février ^^

    on ne force jamais un format de saisie à l'utilisateur, le programme doit s'adapter aux parametres regionnaux.


    pour ta recherche, idem...



    request = "SELECT Count(1) AS Nb " & _
                      "FROM test " & _
                      "WHERE test.date_test=#" & Format$(date_recherche.Value,"MM\/DD\/YYYY") & "#;"


    et c'est TOUT....

    Access reconnaitra une date, passée en format internationnal, parfaitement compris, quelles que soient les parametres regionnaux




  • signaler à un administrateur
    Commentaire de Renfield le 29/06/2007 16:04:08 administrateur CS

    en gros, ta seule grosse erreur a été de placer ton label qui invite a saisir les dates en format dd/mm/yyyy. (vu que CDate, que tu as utilisé utilises les parametres regionnaux)


    ce qu'indique DarkSidious est vrai, tu fait faire trop de transtypages, qui risque de ralentir la chose... présentement, Access va s'y retrouver, mais bon.

  • signaler à un administrateur
    Commentaire de pillsmen le 02/07/2007 09:53:26

    Merci pour vos conseils,

    je modifie la source de suite :).

    Par contre Renfield, je crois que tu n'as pas saisi le principe de mon label :).
    A l'ouverture du formulaire, la fonction ReturnFormat() permet de construire la chaîne de caractère (masque de saisie) qui indiquera à l'utilisateur sous quel format entrer la date par analyse de la date renvoyée par la fonction Date(). Celui-ci est donc basé sur les paramètres régionnaux (j'ai testé avec tout les formats de dates que j'avais dans Panneau de configuration > Options régionnales et linguistiques). Je n'ai trouver aucune source qui le fasse, c'était donc l'intérêt de celle-ci ;).

    En revanche, dans mon programme je devrais gérer l'insertion/lecture de dates quelque soit la région donc si j'ai bien compris en changeant mes requêtes mon code sera portable quelque soit les paramètres régionnaux du système?

    Quelle misère cette gestion des dates sous Access ... ;)

  • signaler à un administrateur
    Commentaire de pillsmen le 02/07/2007 10:30:58

    Petite remarque, juste pour essayer de comprendre un peu plus :)

    Admettons d'avoir les paramètres régionnaux pour le format date courte : yyyy.mm.dd. (format hongrois, me demander pas pourquoi, c'est le premier format "bizarre" que j'ai trouvé ^^). Si je saisie une date dans un format complètement différent il me sauvegarde n'importe quoi dans la BDD ?!

    J'ai tester en entrant un format jj/mm/yyyy (pour exemple : 09/02/2007, en gardant le format system hongrois), quand je consulte la base de donnée, il me met 2007.09.02 !
    Autrement dit, si l'utilisateur saisie une date dans un format autre que le format système, si ce format est "proche" du format système, pas de problème (style dd/mm/yyyy et dd.mm.yyyy) mais dans le cas contraire ..... ce qui implique qu'il faudrait une vérification sur le format à l'insertion histoire d'être sûr ?!

  • signaler à un administrateur
    Commentaire de Renfield le 02/07/2007 10:38:10 administrateur CS

    J'ai retesté, j'ai pas eu mon soucis de la dernière fois, étrange....
    donc ok, ta solution fonctionne. évite les transtypage, mais ca roule

    par contre, TRES dangereux de detecter le format de date de la sorte...
    07.07.07 => dd/dd/yyyy    

    utilises plutot les APIs pour retrouver directement le format

  • signaler à un administrateur
    Commentaire de pillsmen le 02/07/2007 11:24:38

    Justement, je viens juste de faire le test avec le format Kyrgyz (O_o)  dd.mm.yy (on est le 2 Juillet 2007, soit 02/07/2007 ce qui donne 02.07.07 => dd.mm.mm). Le problème viens des tests imbriqués (if ... elseif ... else ...end if) et de la génération du masque à partir de la fonction Date().

    Si on est le 2 Février 2007, pas de problème, par contre comme tu dis si il a correspondance entre deux (ou les trois) des trois parties (jour, mois et année) il s'arrètera dans l'ordre sur dd, mm.

    Le truc c'est que j'aimerais utiliser les API le moins possible, mais je crois que c'est la seule solution à mon problème ;)

  • signaler à un administrateur
    Commentaire de pillsmen le 02/07/2007 16:00:49

    Voilà, j'ai mis en place l'API, mais finalement en réfléchissant bien , je n'ai pas fait de contrôle veillant à ce que la date saisie par l'utilisateur corresponde bien au format de la date système.
    La raison est simple :
    Dans le cas du format de date fr : dd/mm/yyyy si contrôle il y a, la saisie de 09/02/07 ne fonctionnerait pas alors que ça simplifie grandement la saisie...

    Aprés tout, si l'utilisateur décide d'utiliser un autre format que celui qui lui est signalé, c'est à ses risques ;)

  • signaler à un administrateur
    Commentaire de pillsmen le 02/07/2007 16:01:34

    J'oubliais : merci Renfield pour les commentaires constructifs ;)

  • signaler à un administrateur
    Commentaire de Renfield le 02/07/2007 16:05:46 administrateur CS

    bien que tu t'en soit sortit..

    gaffe a l'API, elle renvoie des fois des choses particulières... des \t ou autres.

    concernant mon soucis que j'avais eu, en fait, j'ai du changer mes parametres regionnaux une fois l'appli lancée... et le label ne c'eait pas mis a jour.

  • signaler à un administrateur
    Commentaire de pillsmen le 03/07/2007 08:54:37

    oui j'ai remarqué pour les formats de dates un peu spéciaux style bulgare au format dd.m.yyyy г., le "г." est remplacé par un jolie  "'ã.'" mais bon.

  • signaler à un administrateur
    Commentaire de pillsmen le 03/07/2007 08:57:25

    le г correspond à un r un peu déformé ;)

  • signaler à un administrateur
    Commentaire de Renfield le 03/07/2007 09:27:34 administrateur CS

    utilises simplement la version Unicode de l'API
    les controles de Access le gèrent.

    Private Declare Function GetLocaleInfo Lib "kernel32.dll" Alias "GetLocaleInfoW" ( _
                        ByVal locale As Long, _
                        ByVal lctype As Long, _
                        ByVal lplcdata As Long, _
                        ByVal cchdata As Long _
    ) As Long


    et dans le code :

    nretval = GetLocaleInfo(locale, type_retour, StrPtr(lplcdata), cchdata)
        

  • signaler à un administrateur
    Commentaire de pillsmen le 03/07/2007 11:07:55

    Merci, ça marche nickel :)

    Par curiosité quel est le rôle de la fonction StrPtr(..) ? je n'ai pas trouvé dans l'aide ds VBA.

    Pendant que j'y suis :p, j'ai encore un p'tit problème avec les dates.
    J'ai créé et posté sur ce site 2 formulaires access de calendriers entièrement gérés par labels (pas d'APIs). Je pense que la gestion des dates doit aussi y être catastrophique que ce que j'avais fait précédemment pour cette source!

    http://www.vbfrance.com/codes/CALENDRIER-SEMAINE-VBA-ACCESS_42640.aspx
    http://www.vbfrance.com/codes/CALENDRIER-MOIS-VBA-ACCESS_42460.aspx

    Le problème c'est que je dois générer une date à partir de variables (une pour le jour, une pour le mois, une pour l'année). Je le fesait grâce à la fonction cdate style cdate(num_jour & "/" & num_mois & "/" & num_annee) mais le code n'est, par conséquent, pas portable.
    (je voulais le faire notamment pour cette source afin d'initialiser la table avec des dates aléatoires)

    A ce jour, la solution que j'ai trouvé serait d'utiliser une variable représentant le nombre de jours entre la date désirée et la date actuelle et de généré la date au format "local" avec dateadd(...). Je ne sais pas si c'est la bonne solution, ou s'il en existe une meilleur en jouant sur la fonction Format(...).
    Une idée ? :)

  • signaler à un administrateur
    Commentaire de Renfield le 03/07/2007 11:14:10 administrateur CS

    VB a été concu pour 98 (& co)...

    Unicode, moyena l'époque.
    bien que VB stockes en interne, les string en Unicode, les parametres de type String sont retransformés en ASCII lors des appels aux APIs

    StrPtr nous donne l'adresse de la chaine, ce qui interesse finallement l'API, qui n'y voit que du feu...

    seulement, le parametre n'est plusun String, VB laisse la chaine en Unicode
    (note le W dans le nom de l'API)

  • signaler à un administrateur
    Commentaire de Renfield le 03/07/2007 11:16:16 administrateur CS

    pour la fonction que tu cherches, c'est DateSerial (TimeSerial, pour les heures)

  • signaler à un administrateur
    Commentaire de pillsmen le 03/07/2007 13:24:01

    Super c'est exactement ce qu'il me fallait :)
    Merci encore Renfield

Ajouter un commentaire

Appels d'offres

Pub



CalendriCode

Mai 2008
LMMJVSD
   1234
567891011
12131415161718
19202122232425
262728293031 

VS Express FR Gratuit !

VS Express en français et 100% gratuit !

Téléchargements

Logiciels à télécharger sur le même thème :

Boutique

Boutique de goodies CodeS-SourceS