IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Sondages et Débats Discussion :

[Cours pt-05]Moteur de mise à jour de base de données


Sujet :

Sondages et Débats

  1. #21
    Membre expérimenté
    Avatar de Papy Turbo
    Homme Profil pro
    Développeur Office/VBA
    Inscrit en
    Mars 2004
    Messages
    822
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Office/VBA
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2004
    Messages : 822
    Points : 1 709
    Points
    1 709
    Par défaut
    Olla. D'abord, pas de panique sur la quantité des remarques : il y a pas mal de changements dans la structure de cette aplication, du fait qu'on sépare bien maintenant le modèle de base (réutilisable à merci) de la nouvelle base, copiée.
    Par contre, c'est vrai que, quand tu te lances dans un essai de code comme la dernière fois, ça me permet de repérer les points faibles à travailler. Donc, commençons par les

    Corrections sur Sub CopieModeleBase()
    1- Le chemin d'accès à l'ancienne base : on ne le connait pas, puisque l'utilisateur peut avoir stocké cela n'importe où, en local ou sur n'importe quel serveur. On va le lui demander, dans notre interface -> nouveau contrôle txtPathOldBase + bouton btnBrowse

    2- Le nom du modèle
    de base est inscrit dans le code : si on veut réutiliser ce modèle de moteur de mise à jour, mieux vaut stocker ce genre d'info dans une table de paramètres : voir nouvelle table taApplicationParameters. (préfixe ta pour TurboApp, bien sûr )
    Au passage, note que tu aurais pu mettre ce nom dans une CONSTante, plutôt qu'une variable string.

    3- analyse du code

    NomModeleBase = PathModeleBase & NomModeleBase
    Pratique parfaitement acceptable et courante, mais qui risque de te coûter de nombreuses erreurs mineures. Je conseille de toujours distinguer très clairement les variables qui contiennent
    les noms de fichiers : XxxxFileName
    les chemins d'accès : XxxxPath

    la totale, avec chemin + nom : XxxxPathFileName Je n'utilise pratiquement jamais de telles variables (sauf exception ), parce que je finis presque toujours par avoir besoin de changer, soit le chemin, soit le nom du fichier. Donc, la méthode qui marche toujours : une variable XxxxPath + une variable XxxxFileName.
    Méthodes agiles : ce type de recommendations fait partie du "re-engineering" (ou "refactoring" ?). Ne pas hésiter à réécrire tes applications existantes, en clarifiant les noms des variables.

    Et toc, en lisant plus loin, je constate ceci :
    If Dir(PathAncienneBase & NomModeleBase & ".mdb") Then
    Bien sûr, le test plantera, s'il n'y a pas de test sur la valeur, comme dans : If Dir(PathAncienneBase & NomModeleBase & ".mdb") > "" Then
    Mais surtout, du fait que NomModeleBase contient déjà un chemin, alors PathAncienneBase & NomModeleBase en contiennent 2, l'un derrière l'autre !!! Illustration typique des erreurs que je t'annonce plus haut.
    Et ça veut dire que tu nas pas testé ta routine (même avec une constante pour le chemin de destination). Là, pan sur les doigts ! Les tests sont la première mamelle de la programmation. Incontournables !!!!!!!
    Enfin, rappel concernant les chemins d'accès (voir classe clLog, Public Property Let Path) : toujours s'assurer que chaque chemin se termine bien par un "\". D'où la nouvelle fonction CleanPath(), dans le module _Demarrage_Utilitaires.

    If Dir(NomModeleBase & ".mdb") > "" Then (plus haut)
    Tu vérifies, je cite : "'si le modèle existe dans le répertoire en cours". Mais le répertoire en cours (CurDir) peut être n'importe quel répertoire de la machine et peut être modifié par n'importe quelle application. Donc je ne vois pas trop l'intérêt ?? Mais si j'ai raté qqchose, tu me dis ?

    Application.Quit
    Pourquoi pas, mais le vieux soixantehuitard attardé, ex-hippie peace & love que je suis, préfère des réactions moins violentes : simple retour à l'interface de notre application, en laissant le choix à l'utilisateur
    - de corriger le problème (le modèle n'est pas là où il faut : il va le réinstaller correctement...), ou
    - de quitter de lui-même,
    - etc.
    Contrôle d'erreur : bel essai, mais planté
    On ne met pas (dixit papyturbo) de contrôle d'erreur dans une classe objet. Je reviendrai sous peu en détail sur ce sujet, à la fois pour cette application et l'application principale.
    On verra alors quelles routines et fonctions, généralement quels modules, en fait, ont intérêt à avoir ce genre de code, et quelles sont celles qui devraient plutôt renvoyer les erreurs à l'appelant...

    4- Nom du modèle en *.mod : excellente idée, à laquelle je n'avais pas pensé, et que je vais certainement réutiliser dans mes applis futures. Probablement avec une extension de type "*.dbt" pour "Data Base Template", comme les xlT d'Excel et les .doT de Word....
    Aussi que parce que, chez moi, les *.mod lancent Windows Media Player... !

    5- Appel depuis App_Init : OK, mais, si l'utilisateur doit recommencer plusieurs fois, il faut faire une copie à chaque lancemnt, pour écraser la version précédente, qui n'était pas bonne ou incomplète... Donc, appel maintenant depuis le bouton cmdMAJTables.

    6- Structure de l'application : tu as mis cette routine de copie dans l'objet clApplication. Le but de cette classe est de nous fournir des fonctions qui n'existent pas dans l'application Access, mais que nous allons réutiliser partout.
    Par contre, la copie du fichier "modèle de base de données" est spécifique à cette application de mise à jour. On ne va pas l'utiliser dans une appli comme "SuiviAffaires", par exemple.
    Donc, je l'ai (pour l'instant)
    - déplacée dans les utilitaires propres à notre UpdateWizard : module SpecificTransferRoutines,
    - elle appelle une routine CopyFile qui, elle, est bien dans _Demarrage_Utilitaires. Elle est mieux là, pour qu'on l'appelle directement, comme le FileCopy de VBA, sans préfixer avec ThisApp.CopyFile
    Je t'ai copié "ma" routine de copie de fichier, un poil simplifiée, à partir de la librairie qui accompagne toutes mes applications. Un de buts de cet exercice est que tu commences à constituer ta propre librairie de code réutilisable d'une application à l'autre.

    ---------------------------------
    Nouveautés + mises au point :

    1- Formulaire UpdateWizard :
    - Les boutons de commande sont alignés à droite (quelques lignes de code dans Form_Resize()), et MinWidth devient une simple constante. le tout, à titre d'exemple, et parce que ça m'amuse...

    - bouton Supprimer le journal remplacé par une case à cocher.

    - onglet Transfert, simplification pour l'utilisateur : juste les noms des tables + le fait que ce sont des données (à récupérer) ou des paramètres.

    - bouton cmdEmptyDataTables : ne vide que les tables du modèle + tables locales temporaires (pour alléger le programme à envoyer aux utilisateurs).
    Utilise des paramètres de la nouvelle table de paramètres, au lieu de constantes : moins il y a de modifs à faire dans le code, plus ce programme sera facile à réutiliser.

    2- Connexions :
    - on sépare bien maintenant
    ::: la connexion au modèle de base, seulement pour le développeur, et
    ::: la connexion à la copie, dans le même répertoire que l'ancienne base, pour l'utilisateur.

    - Au démarrage, on reconnecte automatiquement le modèle, qui est "sur place" -> toutes les tables du modèle (*.dbt) sont maintenant connectées aussi.
    La méthode ThisApp.CheckTablesConnection ne reconnecte plus que la base spécifiée par l'argument. Cela permettra de la réutiliser, en ne spécifiant que les bases que l'on souhaite reconnecter automatiqument au démarrage.
    Noter la manière de s'arrêter ( dans App_Quit), qui n'est pas la même selon que l'utilisateur est un dévelopeur ou pas + le fait qu'au démarrage, la fenêtre base de données est maintenant masquée.

    Connexions aux "vraies" bases :
    - Pour l'utilisateur (question d'ergonomie) : on le laisse cliquer sur le bouton Parcourir... pour indiquer où se trouve sa base. Lorsqu'on a un chemin valide, dans cmdMAJTables_click, on reconnecte les 2 copies de la base : l'ancienne + la nouvelle (après copie).

    3- Divers codes :
    - Les routines OuvrirUnFichier() et OuvrirFichierSpécifique() remaniées pour pouvoir obtenir le chemin d'accès séparément du nom de fichier (voir remarques plus haut).

    - Fonction CopyFile() dans le module _Demarrage_Utilitaires (à réutiliser ailleurs). Profites en pour regarder comment on crée ses propres erreurs, avec la méthode Err.Raise...

    - la classe clApplication a maintenant une propriété Parameters(), en lecture (Get) + écriture (Let). Liée à la table taApplicationParameters.

    Si le paramètre n'existe pas, il est créé lors de la première écriture.
    Cette table va, comme indiqué + haut, te permettre de ranger ici un maximum de constantes propres à cette application, mais qu'il faudra changer pour d'autres. Très pratique, plutôt que de fouiller dans tout le code, lors de la création d'une nouvelle appli.
    Attention quand même, de ne pas y ranger des séries de 100 ou 1000 valeurs semblables : on sait créer des tables pour ce genre d'usage. Le propre d'un paramètre est d'être unique (ou presque.)

    -----------------------
    En ce qui te concerne, je verrai bien, à titre d'exercice, l'inversion des préfixes 1_ et 2_ en postfixes (derrière le nom de chaque table).
    Comme pour les tables locales, temporaires.

    On peut garder à part les tables du modèle qui n'intéressent que la phase 1 (ci-dessous).
    Comme déjà mentionné, je pense que tu y verras plus clair dans les seules opérations complexes, à faire avec chaque nouvelle mise à jour d'une base quelconque : mise au point des opérations de transfert entre les tables prises 2 par 2, l'ancienne et la nouvelle, parfois avec une temporaire en plus.
    Rien ne t'y oblige, mais essaye les 2 avant de décider lequel est le plus pratique.

    Sinon, en ce qui me concerne, notre UpdateWizard est au point, selon le scénario suivant :
    1- le développeur réutilise cet assistant, reconnecte les bonnes tables, change les paramètres (dans 000 DestinationTables + taApplicationParameters), adapte le code...
    Il dispose d'une base à l'ancienne version (pour ses tests) + une base à la nouvelle version. Dans cette dernière, il doit y avoir les données d'origine + quelques nouveaux enregistrements "Titi-Toto-Tata", pour tester chaque cas particulier, pendant la mise au point de son application, dernière version.
    Il utilise l'onglet Nettoyage modele pour vider les tables du modèle.
    Il teste et ajoute ce qu'il faut comme requêtes et code VBA pour que tout passe bien.
    En fait, c'est la seule chose qui te reste à faire chaque fois : juste le spécifique.

    2- Déploiement : Quand tout est bon,
    - au démarrage, n'oublie pas de mettre ThisApp.Debugging = False (je l'ai fait, dans l'assistant ci-joint).
    - compactage (par Access) du wizard + de l'application (non inclus ici) + du modèle de base (inclus ci-joint),
    - compactage zip ou similaire. Astuce pas chère : un zip auto-extractible (*.exe) va
    ::: s'ouvrir,
    ::: créer si nécessaire un nouveau dossier pour l'application,
    ::: lancer automatiquement l'UpdateWizard.
    Pour l'utilisateur, c'est simple et ça fait très pro

    3- L'utilisateur reçoit le zip, l'exécute, lance l'assistant, met à jour sa base de données. Ça ne devrait pas lui prendre plus de 5 à 10 minutes, pour une base très lourde et complexe.
    Ça peut être plus long si des interventions lui sont demandées, telles qu'une boîte de dialogue pour nettoyer les valeurs qui ne passent pas, l'impression d'un état listant les valeurs incompatibles, choisir des options, etc.

    4- pour la version suivante de la même application, tu recommences en 1-

    En sachant bien que, maintenant que le plus gros de ce moteur est réutilisable, tu as un très grand intérêt à faire de petites mises à jour à chaque fois qu'une modif (nouveau champ, nouvelle table...) est nécessaire.
    Attendre longtemps, pour faire tout d'un coup, va te coûter beaucoup plus cher (transformations de données plus complexes...).
    Vive le développement par itérations
    Fichiers attachés Fichiers attachés

  2. #22
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    79
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 79
    Points : 67
    Points
    67
    Par défaut
    Citation Envoyé par Papy Turbo
    Olla. D'abord, pas de panique sur la quantité des remarques
    Facile à écrire ‘pas de panique ‘ !! Ce n’est pas les remarques qui me panique, mais le code de l’application. Il me faut pas mal de temps pour l’ingurgiter.

    Tant que les commentaires sont en français, je suis un peu près, mais si tu commences a écrire Anglais, se sera encore plus difficile …

    J’ai un petit problème sur l’application ‘SuiviAffaire_MaJ_V1_V2 2007-02-12.zip’. L’ayant décompressée et lancée, 1ère demande, recherche du fichier ‘SuiviAffaire_BDD_V2.dbt’ qui se trouve sous le même répertoire que l’application. La fenêtre recherche de fichier s’ouvre, je vois bien le fichier sous le répertoire en question, je le sélectionne et… erreur, message : le nom de fichier est incorrect, abandonner, Recommencer, Ignorer. Pas trouvée l’erreur !!!!

    Question sur le point :2- Déploiement : Quand tout est bon.
    Lors du déploiement vers l’utilisateur, laisses-tu tous les menus Access de base ? Serait-il pas plus judicieux de mettre la fenêtre du formulaire ‘UpdateWizard’ en modale ?


    Citation Envoyé par Papy Turbo
    En ce qui te concerne, je verrai bien, à titre d'exercice, l'inversion des préfixes 1_ et 2_ en postfixes (derrière le nom de chaque table).
    Exercice réalisé.
    - Changer dans le code ‘cmdMAJTables_Click’ les constantes VERSION1 et VERSION2,
    - Dans le module ‘SpecificTransferRoutines’ sub ‘AfterTransfer’ modification du nom de la table AvancementEtudePersonnel_1….
    - Par contre gros travail pour reprendre toutes les requêtes ‘d’ajout’.

    Joint fichier modifié sans le fichier .dbt
    -------
    Fichiers attachés : SuiviAffaire_MaJ_V1_V2 2007-02-23.zip (115 ko)
    -------

  3. #23
    Membre expérimenté
    Avatar de Papy Turbo
    Homme Profil pro
    Développeur Office/VBA
    Inscrit en
    Mars 2004
    Messages
    822
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Office/VBA
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2004
    Messages : 822
    Points : 1 709
    Points
    1 709
    Par défaut Récréation
    Citation Envoyé par Serge57
    Facile à écrire ‘pas de panique ‘ !! Ce n’est pas les remarques qui me panique, mais le code de l’application. Il me faut pas mal de temps pour l’ingurgiter.
    [... et plus loin ...]
    Pas trouvée l’erreur !!!!
    C'est l'heure de la récré. Je pense qu'il faut faire une petite pause pour évoquer les méthodes de développement du code.

    Le problème à résoudre :



    Je voudrais une fonction qui me dise si j'ai le droit ou pas, en fonction du jour de semaine, de l'heure d'arrivée et du type de véhicule que je conduis (qui est un véhicule d'approvisionnement ou pas).
    Ce n'est pas très compliqué, mais j'espère que ça va nous permettre de bien mettre en évidence ce qu'on appelle "la méthode de test".

    La méthode "classique" consiste à plonger dans le code, à créer une fonction, à écrire une par une les conditions et, si tu es un programmeur efficace, à tester régulièrement ta fonction avec toutes les valeurs possibles pour chaque paramètre. Par exemple, dans la fenêtre d'exécution :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    debug.? StationnementAutorisé(vbSaturday ,#15:30#,False)
    La fonction StationnementAutorisé() doit renvoyer Vrai/Faux, ou "OK/pas bon"... comme tu veux.
    Les arguments :
    - j'utilise les constantes internes de VBA (vbMonday...) pour les jours de semaine. Plus d'info : Appuyer sur F2 (explorateur d'objets) et chercher "DayOfWeek"...
    - rappel aux débutants qui s'amusent avec nous : les heures sont stockées dans des variables de type Date. Les valeurs de dates et d'heure peuvent être indiquées entre 2 signes dièses (sharp, in english). Dans une date, 1 jour = valeur 1. Donc 1 heure = (1/24), etc.
    - j'ai juste utilisé un Vrai/Faux booléen, pour indiquer si j'ai ou non un véhicule d'approvisionnement de marché.

    Exercice : chronomètre en main, tu notes succinctement les étapes de mise au point de la routine, de manière à pourvoir coller ici le temps que tu as mis pour développer cette routine.
    Avec juste assez de détail pour qu'on suive ta démarche.

    Ma solution est prête, commentée et stockée dans un fichier .txt, que je te livrerai ensuite.
    On ne fait pas la course, on n'est pas pressés.
    Ce qui importera au final, ce sera
    1- un résultat juste,
    2- les méthodes de travail, qu'on comparera alors.

  4. #24
    Expert éminent

    Avatar de Maxence HUBICHE
    Homme Profil pro
    Développeur SQLServer/Access
    Inscrit en
    Juin 2002
    Messages
    3 842
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Développeur SQLServer/Access

    Informations forums :
    Inscription : Juin 2002
    Messages : 3 842
    Points : 9 197
    Points
    9 197
    Par défaut
    je peux jouer ? Je peux jouer ?

    J'ai fait une solution qui fonctionne en ...
    00:09:45
    tests compris.

    et, je me suis permis un 'tiote variante en faisant une enum à la place d''un boolean pour les véhicules

  5. #25
    Membre expérimenté
    Avatar de Papy Turbo
    Homme Profil pro
    Développeur Office/VBA
    Inscrit en
    Mars 2004
    Messages
    822
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Office/VBA
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2004
    Messages : 822
    Points : 1 709
    Points
    1 709
    Par défaut
    Citation Envoyé par Maxence HUBICHE
    00:09:45
    tests compris.
    Pas mal pour un petit jeune .
    C'est beau l'enthousiasme. Mais rien ne sera homologué tant qu'on n'aura pas la réponse de Serge, les codes, et contrôlé que chaque jour, chaque tranche horaire et chaque type de véhicule sont tout bons (ce dont je ne doute pas ).

    Je dirai même plus : il est nettement plus important d'être 100% confident que tous les tests sont bons, plutôt que de gagner quelques minutes.
    C'est revenir sur le code, chercher le bug, refaire tous les tests une xième fois, qui causent des dépassements catastrophiques dans les temps de développement...
    Citation Envoyé par Maxence HUBICHE
    et, je me suis permis un 'tiote variante en faisant une enum à la place d''un boolean pour les véhicules
    . C'est toujours un + de confort pour les ceusses qui passeront derrière.

  6. #26
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    79
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 79
    Points : 67
    Points
    67
    Par défaut
    Citation Envoyé par Papy Turbo
    Exercice : chronomètre en main, tu notes succinctement les étapes de mise au point de la routine, de manière à pourvoir coller ici le temps que tu as mis pour développer cette routine.
    Avec juste assez de détail pour qu'on suive ta démarche
    Temps passé : 00 :45 :00.
    Beaucoup!! J'ai eu beaucoup de problème sur le test de l’heure.(conversion ...). J’y suis arrivé mais je penses qu’il y a plus simple.

    Démarche de mon raisonnement :
    1- Test sur le jour de la semaine
    Stationnement autorisé le dimanche,lundi,mardi,jeudi,vendredi. A toute heure et à tout véhicule.
    2- si ‘Mercredi ou samedi
    Stationnement interdit pour tous les véhicules de 0 à 5h et de 14h30 à 16h
    Si heure entre 5h et 14h30 et si véhicules d'approvisionnement staionnement autorisé sinon interdit.

  7. #27
    Membre expérimenté
    Avatar de Papy Turbo
    Homme Profil pro
    Développeur Office/VBA
    Inscrit en
    Mars 2004
    Messages
    822
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Office/VBA
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2004
    Messages : 822
    Points : 1 709
    Points
    1 709
    Par défaut
    Ne t'affole pas pour les 45 minutes :
    Citation Envoyé par Serge57
    J'ai eu beaucoup de problème sur le test de l’heure.(conversion ...).
    1- c'est bien normal qu'un maxence ou moi écrivions le code sans même réfléchir à ce genre de question, qui devient évidente après quelques années,
    2- 45 minutes n'a rien d'irréaliste, dans un contexte de développement réel, de production pour un client.

    Maintenant, j'attends ton code, bien sûr, et Maxence pourra nous coller le sien aussi, avec son approche : un pti croquis sur une nappe en papier, peut être, ou autre chose ?
    À noter (chacun pour lui même, bien sûr, c'est sûr qu'y a pas de contrôle) : si, juste avant de publier les codes ici, tu passes ne serait-ce que quelques secondes ou minutes pour re-vérifier les résultats, faudra les ajouter au temps total.
    Toujours en contexte réel, de développement, ce temps sera facturé au client !!! Donc, ça compte.

  8. #28
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    79
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 79
    Points : 67
    Points
    67
    Par défaut
    Citation Envoyé par Papy Turbo
    Maintenant, j'attends ton code, bien sûr, et Maxence pourra nous coller le sien aussi, avec son approche : un pti croquis sur une nappe en papier, peut être, ou autre chose ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    Public Function StationnementAutorisé(JourDemande As Integer, HeureDemande As Date, VehiculeDemande As Boolean) As Boolean
    'VehiculeDemande = True pour Véhicule d'approvisionnement, = False pour tout autre véhicule
     
    Select Case JourDemande
     
        Case 1, 2, 3, 5, 6 'Dimanche,Lundi,Mardi,Jeudi,Vendredi
            StationnementAutorisé = True
     
        Case 4, 7 'Mercredi, Samedi
            'si 0 à 16h
            If HeureDemande >= TimeValue(#12:00:00 AM#) And HeureDemande <= TimeValue(#4:00:00 PM#) Then
                  StationnementAutorisé = False
                'si 5h à 14h30 et si véhicule d'approvisionnement
                If HeureDemande >= TimeValue(#5:00:00 AM#) And HeureDemande <= TimeValue(#2:30:00 PM#) _
                                And VehiculeDemande Then
                    StationnementAutorisé = True
                End If
            Else
                StationnementAutorisé = True
            End If
     
        Case Else
            MsgBox "Erreur de demande"
     
    End Select

  9. #29
    Expert éminent

    Avatar de Maxence HUBICHE
    Homme Profil pro
    Développeur SQLServer/Access
    Inscrit en
    Juin 2002
    Messages
    3 842
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Développeur SQLServer/Access

    Informations forums :
    Inscription : Juin 2002
    Messages : 3 842
    Points : 9 197
    Points
    9 197
    Par défaut
    bon, puisque j'ai le droit de poster ...
    moi, j'ai fait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
     
    Public Enum TypeVehicule
        TypeVehicule_Standard
        TypeVehicule_Appro
    End Enum
     
    Public Function StationnementAutorise(LeJour As VbDayOfWeek, LHeure As Date, LeVehicule As TypeVehicule) As Boolean
        'Commencer par examiner le jour
        Select Case LeJour
            'seuls les mercredis et samedis sont intéressant
            Case vbWednesday, vbSaturday
                'tester le type de véhicule (standard)
                If LeVehicule = TypeVehicule_Standard Then
                    'stationnement autorisé si heure > 16:00
                    StationnementAutorise = (LHeure > #4:00:00 PM#)
                'sinon, véhicule appro
                Else
                    'stationnement autorisé si heure non compris entre 5 et 14:30
                    StationnementAutorise = LHeure < #5:00:00 AM# Or LHeure > #2:30:00 PM#
                End If
            'dans les autres cas, c'est toujours autorisé
            Case Else
                StationnementAutorise = True
        End Select
    End Function
    c'est bon patron
    c'est bon ?

    Pour pas m'enquiquiner, j'ai fait une batterie de 1000 tests en générant aléatoirement les valeurs horaires (=ALEA()) pour des valeurs de jours de 1 à 7, sur des types de véhicules possibles (0 ou 1) dans une feuille de calculs Excel.
    Ca ne m'a pas pris plus de 45 secondes pour générer les tests.
    Ensuite, un petit tableau croisé dynamique pour voir ce que ça donnait.

    comme c'était bon, j'ai arrêté les tests
    Mais, j'aimerai avoir ton avis

  10. #30
    Membre expérimenté
    Avatar de Papy Turbo
    Homme Profil pro
    Développeur Office/VBA
    Inscrit en
    Mars 2004
    Messages
    822
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Office/VBA
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2004
    Messages : 822
    Points : 1 709
    Points
    1 709
    Par défaut Réponse, 1ère partie : les résultats
    J'espère que vous êtes Zimpatients de connaître les résultats du test. Je vois un Maxence - speedy gonzales qui bouilonne depuis le début

    Hé bé, il en revient pas, le papy : vous avez tous les 2 des résultats... faux.
    Mort de rire.
    Du coup, j'ai tendance à re-re-revérifier je ne sais combien de fois la logique, les résultats, mais, rien à faire : vous vous êtes + ou - plantés, tous les 2 !

    Commençons par l'analyse des résultats.
    Je vous colle d'abord ici les résultats attendus :
    Légende :
    Ut. (Utilitaire) = véhicule d'approvisionnement du marché.
    Tour. (Tourisme) = autre type de véhicule, que les contractuel(le)s vont verbaliser avec joie.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
                  ---- Dim ---- ---- Lun ---- ---- Mar ---- ---- Mer ---- ---- Jeu ---- ---- Ven ---- ---- Sam ----
                  | Ut. |Tour.| | Ut. |Tour.| | Ut. |Tour.| | Ut. |Tour.| | Ut. |Tour.| | Ut. |Tour.| | Ut. |Tour.|
    00:00            OK | OK       OK | OK       OK | OK      xxxx|xxxx      OK | OK       OK | OK      xxxx|xxxx   
    00:30            OK | OK       OK | OK       OK | OK      xxxx|xxxx      OK | OK       OK | OK      xxxx|xxxx   
    01:00            OK | OK       OK | OK       OK | OK      xxxx|xxxx      OK | OK       OK | OK      xxxx|xxxx   
    01:30            OK | OK       OK | OK       OK | OK      xxxx|xxxx      OK | OK       OK | OK      xxxx|xxxx   
    02:00            OK | OK       OK | OK       OK | OK      xxxx|xxxx      OK | OK       OK | OK      xxxx|xxxx   
    02:30            OK | OK       OK | OK       OK | OK      xxxx|xxxx      OK | OK       OK | OK      xxxx|xxxx   
    03:00            OK | OK       OK | OK       OK | OK      xxxx|xxxx      OK | OK       OK | OK      xxxx|xxxx   
    03:30            OK | OK       OK | OK       OK | OK      xxxx|xxxx      OK | OK       OK | OK      xxxx|xxxx   
    04:00            OK | OK       OK | OK       OK | OK      xxxx|xxxx      OK | OK       OK | OK      xxxx|xxxx   
    04:30            OK | OK       OK | OK       OK | OK      xxxx|xxxx      OK | OK       OK | OK      xxxx|xxxx   
    05:00            OK | OK       OK | OK       OK | OK      -OK-|xxxx      OK | OK       OK | OK      -OK-|xxxx   
    05:30            OK | OK       OK | OK       OK | OK      -OK-|xxxx      OK | OK       OK | OK      -OK-|xxxx   
    06:00            OK | OK       OK | OK       OK | OK      -OK-|xxxx      OK | OK       OK | OK      -OK-|xxxx   
    06:30            OK | OK       OK | OK       OK | OK      -OK-|xxxx      OK | OK       OK | OK      -OK-|xxxx   
    07:00            OK | OK       OK | OK       OK | OK      -OK-|xxxx      OK | OK       OK | OK      -OK-|xxxx   
    07:30            OK | OK       OK | OK       OK | OK      -OK-|xxxx      OK | OK       OK | OK      -OK-|xxxx   
    08:00            OK | OK       OK | OK       OK | OK      -OK-|xxxx      OK | OK       OK | OK      -OK-|xxxx   
    08:30            OK | OK       OK | OK       OK | OK      -OK-|xxxx      OK | OK       OK | OK      -OK-|xxxx   
    09:00            OK | OK       OK | OK       OK | OK      -OK-|xxxx      OK | OK       OK | OK      -OK-|xxxx   
    09:30            OK | OK       OK | OK       OK | OK      -OK-|xxxx      OK | OK       OK | OK      -OK-|xxxx   
    10:00            OK | OK       OK | OK       OK | OK      -OK-|xxxx      OK | OK       OK | OK      -OK-|xxxx   
    10:30            OK | OK       OK | OK       OK | OK      -OK-|xxxx      OK | OK       OK | OK      -OK-|xxxx   
    11:00            OK | OK       OK | OK       OK | OK      -OK-|xxxx      OK | OK       OK | OK      -OK-|xxxx   
    11:30            OK | OK       OK | OK       OK | OK      -OK-|xxxx      OK | OK       OK | OK      -OK-|xxxx   
    12:00            OK | OK       OK | OK       OK | OK      -OK-|xxxx      OK | OK       OK | OK      -OK-|xxxx   
    12:30            OK | OK       OK | OK       OK | OK      -OK-|xxxx      OK | OK       OK | OK      -OK-|xxxx   
    13:00            OK | OK       OK | OK       OK | OK      -OK-|xxxx      OK | OK       OK | OK      -OK-|xxxx   
    13:30            OK | OK       OK | OK       OK | OK      -OK-|xxxx      OK | OK       OK | OK      -OK-|xxxx   
    14:00            OK | OK       OK | OK       OK | OK      -OK-|xxxx      OK | OK       OK | OK      -OK-|xxxx   
    14:30            OK | OK       OK | OK       OK | OK      xxxx|xxxx      OK | OK       OK | OK      xxxx|xxxx   
    15:00            OK | OK       OK | OK       OK | OK      xxxx|xxxx      OK | OK       OK | OK      xxxx|xxxx   
    15:30            OK | OK       OK | OK       OK | OK      xxxx|xxxx      OK | OK       OK | OK      xxxx|xxxx   
    16:00            OK | OK       OK | OK       OK | OK       OK | OK       OK | OK       OK | OK       OK | OK    
    16:30            OK | OK       OK | OK       OK | OK       OK | OK       OK | OK       OK | OK       OK | OK    
    17:00            OK | OK       OK | OK       OK | OK       OK | OK       OK | OK       OK | OK       OK | OK    
    17:30            OK | OK       OK | OK       OK | OK       OK | OK       OK | OK       OK | OK       OK | OK    
    18:00            OK | OK       OK | OK       OK | OK       OK | OK       OK | OK       OK | OK       OK | OK    
    18:30            OK | OK       OK | OK       OK | OK       OK | OK       OK | OK       OK | OK       OK | OK    
    19:00            OK | OK       OK | OK       OK | OK       OK | OK       OK | OK       OK | OK       OK | OK    
    19:30            OK | OK       OK | OK       OK | OK       OK | OK       OK | OK       OK | OK       OK | OK    
    20:00            OK | OK       OK | OK       OK | OK       OK | OK       OK | OK       OK | OK       OK | OK    
    20:30            OK | OK       OK | OK       OK | OK       OK | OK       OK | OK       OK | OK       OK | OK    
    21:00            OK | OK       OK | OK       OK | OK       OK | OK       OK | OK       OK | OK       OK | OK    
    21:30            OK | OK       OK | OK       OK | OK       OK | OK       OK | OK       OK | OK       OK | OK    
    22:00            OK | OK       OK | OK       OK | OK       OK | OK       OK | OK       OK | OK       OK | OK    
    22:30            OK | OK       OK | OK       OK | OK       OK | OK       OK | OK       OK | OK       OK | OK    
    23:00            OK | OK       OK | OK       OK | OK       OK | OK       OK | OK       OK | OK       OK | OK    
    23:30            OK | OK       OK | OK       OK | OK       OK | OK       OK | OK       OK | OK       OK | OK    
    00:00            OK | OK       OK | OK       OK | OK       OK | OK       OK | OK       OK | OK       OK | OK
    Si vous reprenez l'image de départ (le problème à résoudre), notez bien que
    - À PARTIR DE 14h30, (mais, bien sûr pas à 14h00 ni 14h29) le stationnement n'est plus autorisé pour personne, les mercredis et samedi (jusqu'à 16h00, ou plus exactement : jusqu'à 15 h 59 min 59 secondes).
    Vous vous êtes tous les 2 plantés sur celui là, mais pas dans le même sens, parce que Maxence a inversé les types de véhicule.
    - idem pour chaque horaire "charnière"... à re-re-vérifier, avec leurs ">", "<", ">=" et/ou "<=".
    Voici vos réultats, obtenus en copiant les codes ci-dessous pour en modifier légèrement la sortie, et en les appelant depuis la sub Test()
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    résultat Maxence :
     
                  ---- Dim ---- ---- Lun ---- ---- Mar ---- ---- Mer ---- ---- Jeu ---- ---- Ven ---- ---- Sam ----
                  | Ut. |Tour.| | Ut. |Tour.| | Ut. |Tour.| | Ut. |Tour.| | Ut. |Tour.| | Ut. |Tour.| | Ut. |Tour.|
    00:00            OK | OK       OK | OK       OK | OK      -OK-|xxxx      OK | OK       OK | OK      -OK-|xxxx   
    00:30            OK | OK       OK | OK       OK | OK      -OK-|xxxx      OK | OK       OK | OK      -OK-|xxxx   
    01:00            OK | OK       OK | OK       OK | OK      -OK-|xxxx      OK | OK       OK | OK      -OK-|xxxx   
    01:30            OK | OK       OK | OK       OK | OK      -OK-|xxxx      OK | OK       OK | OK      -OK-|xxxx   
    02:00            OK | OK       OK | OK       OK | OK      -OK-|xxxx      OK | OK       OK | OK      -OK-|xxxx   
    02:30            OK | OK       OK | OK       OK | OK      -OK-|xxxx      OK | OK       OK | OK      -OK-|xxxx   
    03:00            OK | OK       OK | OK       OK | OK      -OK-|xxxx      OK | OK       OK | OK      -OK-|xxxx   
    03:30            OK | OK       OK | OK       OK | OK      -OK-|xxxx      OK | OK       OK | OK      -OK-|xxxx   
    04:00            OK | OK       OK | OK       OK | OK      -OK-|xxxx      OK | OK       OK | OK      -OK-|xxxx   
    04:30            OK | OK       OK | OK       OK | OK      -OK-|xxxx      OK | OK       OK | OK      -OK-|xxxx   
    05:00            OK | OK       OK | OK       OK | OK      xxxx|xxxx      OK | OK       OK | OK      xxxx|xxxx   
    05:30            OK | OK       OK | OK       OK | OK      xxxx|xxxx      OK | OK       OK | OK      xxxx|xxxx   
    06:00            OK | OK       OK | OK       OK | OK      xxxx|xxxx      OK | OK       OK | OK      xxxx|xxxx   
    06:30            OK | OK       OK | OK       OK | OK      xxxx|xxxx      OK | OK       OK | OK      xxxx|xxxx   
    07:00            OK | OK       OK | OK       OK | OK      xxxx|xxxx      OK | OK       OK | OK      xxxx|xxxx   
    07:30            OK | OK       OK | OK       OK | OK      xxxx|xxxx      OK | OK       OK | OK      xxxx|xxxx   
    08:00            OK | OK       OK | OK       OK | OK      xxxx|xxxx      OK | OK       OK | OK      xxxx|xxxx   
    08:30            OK | OK       OK | OK       OK | OK      xxxx|xxxx      OK | OK       OK | OK      xxxx|xxxx   
    09:00            OK | OK       OK | OK       OK | OK      xxxx|xxxx      OK | OK       OK | OK      xxxx|xxxx   
    09:30            OK | OK       OK | OK       OK | OK      xxxx|xxxx      OK | OK       OK | OK      xxxx|xxxx   
    10:00            OK | OK       OK | OK       OK | OK      xxxx|xxxx      OK | OK       OK | OK      xxxx|xxxx   
    10:30            OK | OK       OK | OK       OK | OK      xxxx|xxxx      OK | OK       OK | OK      xxxx|xxxx   
    11:00            OK | OK       OK | OK       OK | OK      xxxx|xxxx      OK | OK       OK | OK      xxxx|xxxx   
    11:30            OK | OK       OK | OK       OK | OK      xxxx|xxxx      OK | OK       OK | OK      xxxx|xxxx   
    12:00            OK | OK       OK | OK       OK | OK      xxxx|xxxx      OK | OK       OK | OK      xxxx|xxxx   
    12:30            OK | OK       OK | OK       OK | OK      xxxx|xxxx      OK | OK       OK | OK      xxxx|xxxx   
    13:00            OK | OK       OK | OK       OK | OK      xxxx|xxxx      OK | OK       OK | OK      xxxx|xxxx   
    13:30            OK | OK       OK | OK       OK | OK      xxxx|xxxx      OK | OK       OK | OK      xxxx|xxxx   
    14:00            OK | OK       OK | OK       OK | OK      xxxx|xxxx      OK | OK       OK | OK      xxxx|xxxx   
    14:30            OK | OK       OK | OK       OK | OK      xxxx|xxxx      OK | OK       OK | OK      xxxx|xxxx   
    15:00            OK | OK       OK | OK       OK | OK      -OK-|xxxx      OK | OK       OK | OK      -OK-|xxxx   
    15:30            OK | OK       OK | OK       OK | OK      -OK-|xxxx      OK | OK       OK | OK      -OK-|xxxx   
    16:00            OK | OK       OK | OK       OK | OK      -OK-|xxxx      OK | OK       OK | OK      -OK-|xxxx   
    16:30            OK | OK       OK | OK       OK | OK      -OK-| OK       OK | OK       OK | OK      -OK-| OK    
    17:00            OK | OK       OK | OK       OK | OK      -OK-| OK       OK | OK       OK | OK      -OK-| OK    
    17:30            OK | OK       OK | OK       OK | OK      -OK-| OK       OK | OK       OK | OK      -OK-| OK    
    18:00            OK | OK       OK | OK       OK | OK      -OK-| OK       OK | OK       OK | OK      -OK-| OK    
    18:30            OK | OK       OK | OK       OK | OK      -OK-| OK       OK | OK       OK | OK      -OK-| OK    
    19:00            OK | OK       OK | OK       OK | OK      -OK-| OK       OK | OK       OK | OK      -OK-| OK    
    19:30            OK | OK       OK | OK       OK | OK      -OK-| OK       OK | OK       OK | OK      -OK-| OK    
    20:00            OK | OK       OK | OK       OK | OK      -OK-| OK       OK | OK       OK | OK      -OK-| OK    
    20:30            OK | OK       OK | OK       OK | OK      -OK-| OK       OK | OK       OK | OK      -OK-| OK    
    21:00            OK | OK       OK | OK       OK | OK      -OK-| OK       OK | OK       OK | OK      -OK-| OK    
    21:30            OK | OK       OK | OK       OK | OK      -OK-| OK       OK | OK       OK | OK      -OK-| OK    
    22:00            OK | OK       OK | OK       OK | OK      -OK-| OK       OK | OK       OK | OK      -OK-| OK    
    22:30            OK | OK       OK | OK       OK | OK      -OK-| OK       OK | OK       OK | OK      -OK-| OK    
    23:00            OK | OK       OK | OK       OK | OK      -OK-| OK       OK | OK       OK | OK      -OK-| OK    
    23:30            OK | OK       OK | OK       OK | OK      -OK-| OK       OK | OK       OK | OK      -OK-| OK    
    00:00            OK | OK       OK | OK       OK | OK      -OK-| OK       OK | OK       OK | OK      -OK-| OK    
     
     
    Résultat Serge :
                  ---- Dim ---- ---- Lun ---- ---- Mar ---- ---- Mer ---- ---- Jeu ---- ---- Ven ---- ---- Sam ----
                  | Ut. |Tour.| | Ut. |Tour.| | Ut. |Tour.| | Ut. |Tour.| | Ut. |Tour.| | Ut. |Tour.| | Ut. |Tour.|
    00:00            OK | OK       OK | OK       OK | OK      xxxx|xxxx      OK | OK       OK | OK      xxxx|xxxx   
    00:30            OK | OK       OK | OK       OK | OK      xxxx|xxxx      OK | OK       OK | OK      xxxx|xxxx   
    01:00            OK | OK       OK | OK       OK | OK      xxxx|xxxx      OK | OK       OK | OK      xxxx|xxxx   
    01:30            OK | OK       OK | OK       OK | OK      xxxx|xxxx      OK | OK       OK | OK      xxxx|xxxx   
    02:00            OK | OK       OK | OK       OK | OK      xxxx|xxxx      OK | OK       OK | OK      xxxx|xxxx   
    02:30            OK | OK       OK | OK       OK | OK      xxxx|xxxx      OK | OK       OK | OK      xxxx|xxxx   
    03:00            OK | OK       OK | OK       OK | OK      xxxx|xxxx      OK | OK       OK | OK      xxxx|xxxx   
    03:30            OK | OK       OK | OK       OK | OK      xxxx|xxxx      OK | OK       OK | OK      xxxx|xxxx   
    04:00            OK | OK       OK | OK       OK | OK      xxxx|xxxx      OK | OK       OK | OK      xxxx|xxxx   
    04:30            OK | OK       OK | OK       OK | OK      xxxx|xxxx      OK | OK       OK | OK      xxxx|xxxx   
    05:00            OK | OK       OK | OK       OK | OK      -OK-|xxxx      OK | OK       OK | OK      -OK-|xxxx   
    05:30            OK | OK       OK | OK       OK | OK      -OK-|xxxx      OK | OK       OK | OK      -OK-|xxxx   
    06:00            OK | OK       OK | OK       OK | OK      -OK-|xxxx      OK | OK       OK | OK      -OK-|xxxx   
    06:30            OK | OK       OK | OK       OK | OK      -OK-|xxxx      OK | OK       OK | OK      -OK-|xxxx   
    07:00            OK | OK       OK | OK       OK | OK      -OK-|xxxx      OK | OK       OK | OK      -OK-|xxxx   
    07:30            OK | OK       OK | OK       OK | OK      -OK-|xxxx      OK | OK       OK | OK      -OK-|xxxx   
    08:00            OK | OK       OK | OK       OK | OK      -OK-|xxxx      OK | OK       OK | OK      -OK-|xxxx   
    08:30            OK | OK       OK | OK       OK | OK      -OK-|xxxx      OK | OK       OK | OK      -OK-|xxxx   
    09:00            OK | OK       OK | OK       OK | OK      -OK-|xxxx      OK | OK       OK | OK      -OK-|xxxx   
    09:30            OK | OK       OK | OK       OK | OK      -OK-|xxxx      OK | OK       OK | OK      -OK-|xxxx   
    10:00            OK | OK       OK | OK       OK | OK      -OK-|xxxx      OK | OK       OK | OK      -OK-|xxxx   
    10:30            OK | OK       OK | OK       OK | OK      -OK-|xxxx      OK | OK       OK | OK      -OK-|xxxx   
    11:00            OK | OK       OK | OK       OK | OK      -OK-|xxxx      OK | OK       OK | OK      -OK-|xxxx   
    11:30            OK | OK       OK | OK       OK | OK      -OK-|xxxx      OK | OK       OK | OK      -OK-|xxxx   
    12:00            OK | OK       OK | OK       OK | OK      -OK-|xxxx      OK | OK       OK | OK      -OK-|xxxx   
    12:30            OK | OK       OK | OK       OK | OK      -OK-|xxxx      OK | OK       OK | OK      -OK-|xxxx   
    13:00            OK | OK       OK | OK       OK | OK      -OK-|xxxx      OK | OK       OK | OK      -OK-|xxxx   
    13:30            OK | OK       OK | OK       OK | OK      -OK-|xxxx      OK | OK       OK | OK      -OK-|xxxx   
    14:00            OK | OK       OK | OK       OK | OK      -OK-|xxxx      OK | OK       OK | OK      -OK-|xxxx   
    14:30            OK | OK       OK | OK       OK | OK      -OK-|xxxx      OK | OK       OK | OK      -OK-|xxxx   
    15:00            OK | OK       OK | OK       OK | OK      xxxx|xxxx      OK | OK       OK | OK      xxxx|xxxx   
    15:30            OK | OK       OK | OK       OK | OK      xxxx|xxxx      OK | OK       OK | OK      xxxx|xxxx   
    16:00            OK | OK       OK | OK       OK | OK      xxxx|xxxx      OK | OK       OK | OK      xxxx|xxxx   
    16:30            OK | OK       OK | OK       OK | OK       OK | OK       OK | OK       OK | OK       OK | OK    
    17:00            OK | OK       OK | OK       OK | OK       OK | OK       OK | OK       OK | OK       OK | OK    
    17:30            OK | OK       OK | OK       OK | OK       OK | OK       OK | OK       OK | OK       OK | OK    
    18:00            OK | OK       OK | OK       OK | OK       OK | OK       OK | OK       OK | OK       OK | OK    
    18:30            OK | OK       OK | OK       OK | OK       OK | OK       OK | OK       OK | OK       OK | OK    
    19:00            OK | OK       OK | OK       OK | OK       OK | OK       OK | OK       OK | OK       OK | OK    
    19:30            OK | OK       OK | OK       OK | OK       OK | OK       OK | OK       OK | OK       OK | OK    
    20:00            OK | OK       OK | OK       OK | OK       OK | OK       OK | OK       OK | OK       OK | OK    
    20:30            OK | OK       OK | OK       OK | OK       OK | OK       OK | OK       OK | OK       OK | OK    
    21:00            OK | OK       OK | OK       OK | OK       OK | OK       OK | OK       OK | OK       OK | OK    
    21:30            OK | OK       OK | OK       OK | OK       OK | OK       OK | OK       OK | OK       OK | OK    
    22:00            OK | OK       OK | OK       OK | OK       OK | OK       OK | OK       OK | OK       OK | OK    
    22:30            OK | OK       OK | OK       OK | OK       OK | OK       OK | OK       OK | OK       OK | OK    
    23:00            OK | OK       OK | OK       OK | OK       OK | OK       OK | OK       OK | OK       OK | OK    
    23:30            OK | OK       OK | OK       OK | OK       OK | OK       OK | OK       OK | OK       OK | OK    
    00:00            OK | OK       OK | OK       OK | OK       OK | OK       OK | OK       OK | OK       OK | OK
    Pour mieux visualiser les résultats, j'ai remplacé vos 'True' par des " OK " ou bien "-OK-", et vos 'False' par des "xxxx". Mais notez que je n'ai pas touché à la logique des routines qui sont incluses, avec les modifs, dans le module de code VBA du tableau Excel ci-joint, un peu plus bas.

  11. #31
    Membre expérimenté
    Avatar de Papy Turbo
    Homme Profil pro
    Développeur Office/VBA
    Inscrit en
    Mars 2004
    Messages
    822
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Office/VBA
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2004
    Messages : 822
    Points : 1 709
    Points
    1 709
    Par défaut 2ème partie : la méthode de tests
    Maintenant, ce qui nous intéresse ici, c'est d'abord la méthode.
    La méthode doit nous aider à garantir que tous les résultats seront bons, dans un minimum de temps (1 heure de développement = beaucoup pognon).
    Je veux parler de ce qu'on appelle la méthode de Test.
    En lisant un article sur ce sujet, il y a quelques années, je me suis dit : "ils sont fous ces romains".
    En gros, l'article disait, je cite de mémoire : "avant d'écrire une routine, vous écrivez, d'abord, la routine de tests".
    --- Et comment tu veux que j'écrive le test, s'il n'y a rien à tester ???

    Avec l'exemple de notre récré :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    Étapes :    
    A- création du test :     
    14:52    Ebauche + création routine test : Dim + lignes de titre (jours semaine + véhicule) + boucle toutes les 1/2 h : affichage des heures
    14:57    ajout boucle interne : jours semaine.  Affichage : ajustement alignement des réponses (Vrai/Faux) en colonne
    15:01    La sub "test" affiche bien tous les jours/heures/types de véhicule.  Tous les résultats sont "True".
    Total :  9 minutes.
     
    A- Ebauche de routine : ----------------------------
    Public Function StationnementAutorisé(JourSemaine As VbDayOfWeek, _
                                          DébutStationnement As Date, _
                                          VéhiculeApprovisionnement As Boolean) _
                                          As String
        StationnementAutorisé = True
    End Function
     
    B- La routine de test : ----------------------------
    Public Sub Test()
    Dim JourSemaine As VbDayOfWeek
    Dim CompteurTemps As Byte   'compte le nombre de 1/2 heures entre 00:00 et 24:00
    Dim DébutStationnement As Date
     
        Debug.Print , "---- Dim ----", "---- Lun ----", "---- Mar ----", "---- Mer ----", "---- Jeu ----", "---- Ven ----", "---- Sam ----"
        'Ut. = utilitaire d'approvisionnement
        'Tour. : véhicule de tourime
        Debug.Print , "| Ut. |Tour.|", "| Ut. |Tour.|", "| Ut. |Tour.|", "| Ut. |Tour.|", "| Ut. |Tour.|", "| Ut. |Tour.|", "| Ut. |Tour.|"
        For CompteurTemps = 0 To 48
            '1 jour  = 1
            '1 heure = 1/24
            '1/2 h = 1/48
            DébutStationnement = CompteurTemps / 48
            Debug.Print Format(DébutStationnement, "hh:mm"),
            For JourSemaine = vbSunday To vbSaturday  '1 to 7
                Debug.Print "  "; StationnementAutorisé(JourSemaine, DébutStationnement, True); "|"; StationnementAutorisé(JourSemaine, DébutStationnement, False),
            Next
            'à la ligne
            Debug.Print
        Next
     
    End Sub
     
     
    C- écriture de la fonction : -----------------------------
    15:02    Select Case JourSemaine + test
    15:03    If DébutStationnement (après 16 h00) + test
    15:05    Remplacement du résultat booléen "True/False" par un string "  OK "/"xxxx"
    15:06    Corrigé bug dans sub Test : double appel de la fonction avec 2 fois "True" pour véhicules
    15:10    Dernier test : 5h -> 14h30
    15:11    OK. 
    Grand Total : 19 minutes
     
    La fonction recherchée :
    Public Function StationnementAutorisé(JourSemaine As VbDayOfWeek, _
                                          DébutStationnement As Date, _
                                          VéhiculeApprovisionnement As Boolean) _
                                          As String
    Const SEIZEHEURES = 16 / 24
    Const CINQHEURES = 5 / 24
    Const QUATORZEHEURESTRENTE = 14.5 / 24
     
        StationnementAutorisé = "xxxx"
        Select Case JourSemaine
        Case vbWednesday, vbSaturday
            If DébutStationnement >= SEIZEHEURES Then
                StationnementAutorisé = " OK "
            Else
                If VéhiculeApprovisionnement Then
                    If (DébutStationnement >= CINQHEURES) And (DébutStationnement < QUATORZEHEURESTRENTE) Then
                        StationnementAutorisé = "-OK-"
                    End If
                End If
            End If
        Case Else
            StationnementAutorisé = " OK "
        End Select
    End Function
     
    D- test dans Excel : -----------------------------
    Mise en forme tableau Excel : env. 20~30 minutes
    Découverte du bug à #5:00# (AM)
    Analyse du bug Rounding à #05:00# : + 15~20 minutes env.
     
    Public Sub TestRoundingBug()
        'Noter que c'est VBA qui ajoute automatiquement le ":00 AM" derrière "#5:00"
        Debug.Print "#5:00#", #5:00:00 AM#, StationnementAutorisé(4, #5:00:00 AM#, -1)
        Debug.Print "10 / 48", 10 / 48, StationnementAutorisé(4, 10 / 48, -1)
        Debug.Print "CDate(0.208333333333333)", CDate(0.208333333333333), StationnementAutorisé(4, CDate(0.208333333333333), -1)
        Debug.Print "0.208333333333333", 0.208333333333333, StationnementAutorisé(4, 0.208333333333333, -1)
        Debug.Print "----------------"
        Debug.Print "#5:00:00 AM# = #5:00:00 AM#", #5:00:00 AM# = #5:00:00 AM#
        Debug.Print "(10 / 48) = #5:00:00 AM#", (10 / 48) = #5:00:00 AM#
        Debug.Print "CDate(0.208333333333333) = #5:00:00 AM#", CDate(0.208333333333333) = #5:00:00 AM#
        Debug.Print "0.208333333333333 = #5:00:00 AM#", 0.208333333333333 = #5:00:00 AM#
        Debug.Print "0.208333333333333 < #5:00:00 AM#", 0.208333333333333 < #5:00:00 AM#
    End Sub
    en bref :
    A- création du test :
    14:52 Ebauche + création routine test : Dim + lignes de titre (jours semaine + véhicule) + boucle toutes les 1/2 h : affichage des heures
    14:57 ajout boucle interne : jours semaine. Affichage : ajustement alignement des réponses (Vrai/Faux) en colonne
    15:01 La sub "test" affiche bien tous les jours/heures/types de véhicule. Tous les résultats sont "True".
    Total : 9 minutes.

    À ce stade, la fonction renvoit tout simplement 'True' (ou 'False', ou 'bisou' ou ce que vous voudrez...)
    Mais le tableau de test peut être copié dans un fichier .txt, imprimé, colorié avec des feutres pour bien voir où commence et où finit chaque tranche horaire, (ce que j'ai fait, bien sûr) etc.

    Ensuite, écriture de la fonction elle-même :
    C- écriture de la fonction : -----------------------------
    15:02 Select Case JourSemaine + test
    15:03 If DébutStationnement (après 16 h00) + test
    15:05 Remplacement du résultat booléen "True/False" par un string " OK "/"xxxx"
    15:06 Corrigé bug dans sub Test : double appel de la fonction avec 2 fois "True" pour véhicules
    15:10 Dernier test : 5h -> 14h30
    15:11 OK.
    Grand Total : 19 minutes

    Ensuite, me suis amusé à faire le même tableau dans Excel : plus visuel pour la démo.
    Et vlan ! un bug.
    La même routine ne donne pas les mêmes résultats dans le tableau Xl que dans la fenêtre d'exécution .
    D'où l'étape finale :
    D- test dans Excel : -----------------------------
    Mise en forme tableau Excel : env. 20~30 minutes
    Découverte du bug à #5:00# (AM)
    Analyse du bug Rounding à #05:00# : + 15~20 minutes env.

    Soit un vrai temps total de plus d'une heure (avec les pauses café/pipi).
    Tu es battu, Serge, j'ai mis + longtemps que toi.

    Si tu enlèves le temps perdu avec tes fonctions TimeValue() que tu peux supprimer , et autres, on n'est pas loin les uns des autres, pour la partie hors bug VBA.

    Avec l'avantage d'une méthode qui me permet,
    - en 1 minute, de tester toutes les solutions,
    - de détecter un bug (documenté dans VBA) sur les erreurs d'arrondi pendant la conversion d'un double en date -> attention aux arguments pour appeler la fonction ! à préciser dans la doc "développeurs" de cette fonction.

    Pour bien voir les bénéfices, je vous propose, comme à tous ceux qui ont fait l'exercice (sans regarder les résultats),
    - de tout effacer chez vous, sauf l'image de départ (le problème).
    - oublier tout ça pendant 15 jours / 1 mois,
    - mettre un RDVs ou une tâche dans votre agenda pour refaire l'exercice avec un cerveau frais,
    - utiliser la/les méthodes de votre choix pour recommencer, en prenant tout le temps nécessaire,
    - re-chrono + re-vérification des résultats.
    Citation Envoyé par Maxence Hubiche
    Pour pas m'enquiquiner, j'ai fait une batterie de 1000 tests en générant aléatoirement les valeurs horaires (=ALEA()) pour des valeurs de jours de 1 à 7, sur des types de véhicules possibles (0 ou 1) dans une feuille de calculs Excel.
    Ca ne m'a pas pris plus de 45 secondes pour générer les tests.
    Ensuite, un petit tableau croisé dynamique pour voir ce que ça donnait.
    M'intéresse beaucoup, le petit tableau croisé, ainsi que tout les 1000 tests aléatoires

    En conclusion, je cite ici l'intro de Sébastien Meric, dans son article Tests unitaires :
    Citation Envoyé par Sebastien MERIC
    L'utilisation de framework de tests unitaires est essentielle à la constitution d'un code robuste. Elle s'inscrit dans la lignée des articles précédents et viens en complément, vous aider, d'une part à placer votre code en situation difficile, d'autre part, elle en améliore la lisibilité ! Est-ce possible, alors qu'on écrit plus de code que necessaire ? N'allez-vous pas passer encore du temps à écrire du code en plus de ce qui est demandé, déjà qu'il y a les commentaires à écrire. Nous verrons que loin de ralentir le développement, il vous fait gagner un temps de débuggage franchement important. Sachant qu'avant d'avoir mis au point ces diverses techniques, le débuggage était considéré comme occupant une part allant de 50% du temps pour un expert à 90% pour un débutant, je vous laisse imaginer le gain en performances que vous allez faire.
    Si ce petit jeu a pu en convaincre quelques uns de l'importance
    - des méthodes de développement en général,
    - de l'importance des tests par rapport à la seule "écriture de code",
    - du bon vieux "che va piano va sano",
    alors, c'est une bonne journée.
    Fichiers attachés Fichiers attachés

  12. #32
    Expert éminent

    Avatar de Maxence HUBICHE
    Homme Profil pro
    Développeur SQLServer/Access
    Inscrit en
    Juin 2002
    Messages
    3 842
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Développeur SQLServer/Access

    Informations forums :
    Inscription : Juin 2002
    Messages : 3 842
    Points : 9 197
    Points
    9 197
    Par défaut
    Euuuh !
    Nous n'avons pas le même avis sur l'interprétation du message cher ami...
    Pour moi, un véhicule utilitaire ne peut stationner que jusqu'à 5h00 (il doit bien décharger quand même !!) et à partir de A4h30) il faut bien remballer !

    Mais ne doit pas rester sur place entre temps.
    C'est pour cela que tu dis que j'ai inversé.


    Donc, déjà pas d'accord sur le sens de l'énoncé => forcément, ca peut poser des soucis de résultats.
    Ceci explique cela.

    Evidemment, dans le cas de ton interprétation, il me suffit d'inverser mes signes.

  13. #33
    Expert éminent

    Avatar de Maxence HUBICHE
    Homme Profil pro
    Développeur SQLServer/Access
    Inscrit en
    Juin 2002
    Messages
    3 842
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Développeur SQLServer/Access

    Informations forums :
    Inscription : Juin 2002
    Messages : 3 842
    Points : 9 197
    Points
    9 197
    Par défaut
    Citation Envoyé par Papy Turbo
    M'intéresse beaucoup, le petit tableau croisé, ainsi que tout les 1000 tests aléatoires
    Première colonne (les jours de la semaine)
    JOUR
    1
    2
    3
    4
    5
    6
    7
    Deuxième colonne (les hh:nn:ss)
    HEURE
    =alea()
    Troisième colonne (le type de véhicule)
    TYPE
    0
    1
    Quatrième colonne (le calcul)
    VALEUR
    =SI(StationnementAutorise(A1;B1;C1);1;0)

    On copie les 3 premières colonnes colonnes sur n lignes, ce qui donne un ensemble de valeurs à volonté
    Copier-Collage spécial valeur (pour tuer la fonction ALEA() qui est gonflante)
    Recopier la formule de la 4° colonne
    (ps : j'ai refais mes tests sur 15000 lignes et je ne suis pas hors-jeu avec ma compréhension ou alors, je n'ai toujour pas vu le loup... )

    Sur cette liste de valeurs on fait un tableau croisé dynamique

    Jour en en-tête de colonne
    Type en en-tête de colonne
    Heure en en-tête de ligne
    Somme de Valeur en valeur

    finito !

    c'est ma méthode de tests, prévue pour tester la fonction.
    La série de tests permet d'avoir à priori l'ensemble de toutes les valeurs aléatoirement.
    Super rapie.
    Pas besoin de faire de procédure de tests encodée VBA, car, si je suis le raisonnement jusqu'à bout, il faudrait une procédure de tests qui teste la procédure de tests
    Les résultats sortent très vite sur un AMD Athlon64bits / 2Go RAM (lol)

    vàlà

  14. #34
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    79
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 79
    Points : 67
    Points
    67
    Par défaut
    Sans vouloir polémiquer, les heures sur le panneau sont des heures incluses. De 0h à 16h (à partir de 0h incluse, jusqu’à 16h incluse) idem pour 5h à 14h30. D’où l’importance du cahier des charges.
    Mais j’ai compris la leçon. Je ne fais pas assez de test (remarque récurrente de Papy Turbo) sur mes fonctions, mais j’essaye de me corrige

  15. #35
    Membre expérimenté
    Avatar de Papy Turbo
    Homme Profil pro
    Développeur Office/VBA
    Inscrit en
    Mars 2004
    Messages
    822
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Office/VBA
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2004
    Messages : 822
    Points : 1 709
    Points
    1 709
    Par défaut Les règles métier
    Serge, c'est pas de la polémique. Dans un domaine financier, des différences de 1 centime peuvent changer tout un graphique ou surtout, déséquilibrer un bilan !
    Donc, je reconnais que Serge marque un point, même si, du point de vue du contractuel... Mais ça, c'est typiquement une question à
    - exposer en clair au client (qui aura + de mal que nous à comprendre ce genre de problème),
    - attendre sa décision.
    - ou, ajouter une option : arrondi audessus/au dessous ?

    Tu veux un cas réel ?
    - sur les 6 niveaux d'organisation d'une société, on consolide les pourcentages d'avancement.
    - Les pourcentages sont saisis au niveau 6,
    - on fait la moyenne de tous les pourcentages du niveau 6,
    - on affiche, au niveau 5, l'ensemble des moyennes de tous les sous-niveaux
    - puis, au niveau 5, on fait la "moyenne de ces moyennes",
    - idem au niveau 4 : affichage des moyennes du niveau 5, dont on fait la moyenne... le tout jusqu'au niveau 1, global.
    Le lapin levé par le développeur : une moyenne de moyenne ne donnera pas le même résultat que si, au niveau 4, par exemple
    - on reprend tous les niveaux 6 inclus dans tous les niveaux 5 concernés,
    - on refait cette moyenne là.
    Le hic : on n'a ça dans des classeurs Excel, pas dans une base de données, donc ça coûtera plus cher et, surtout, ça sera plus long
    Décision du client (après 4 jours occupé à faire autre chose) : on continue. "Je (client) suis conscient du problème. On corrigera peut être plus tard."
    Tout ce que je veux dire : y a pas de petite question. Et c'est le client-utilisateur qui tranche. C'est son outil.

    Par contre, Maxence, désolé, mais je pense que tu as été un peu vite dans ton interprétation. Quand il y a le moindre doute sur une règle métier, toujours pareil : (re-)demander au client, sans hésiter à passer pour un imbécile. Ça m'arrive tous les jours et ça vaut beaucoup mieux, à long terme, que de se précipiter pour devoir ensuite recommencer.
    En l'occurence, j'ai redemandé à ma voisine brocanteuse, qui fait les marchés. Elle me confirme bien ce que nous avions interprété, pour les jours de marché :
    - de minuit à 5h00, la fourrière embarque tout le monde pour libérer la place,
    - à 5h00, les exposants s'installent, et restent jusqu'à la fin,
    - vers 7-8h00 du matin, les clients arrivent,
    - vers 13-14h00 dernier délai, faut remballer (ça va + vite)
    - de 14h30 à 16h00, les éboueurs passent pour nettoyer.
    - à 16h00, tout le monde peut se garer à nouveau...

    Ceci dit, moi aussi, me suis planté
    J'ai fait l'impasse sur un bug potentiel : même si mes tests sont finalement bons, il a fallu, après avoir posté les résultats et relu mon code, encore une heure avant de réaliser que mes constantes risquaient de coller des erreurs d'arrondi.
    Rappel - je m'étais amusé à ça, juste pour montrer comme c'est facile de faire des calculs d'heures :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Const SEIZEHEURES = 16 / 24
    Const CINQHEURES = 5 / 24
    Const QUATORZEHEURESTRENTE = 14.5 / 24
    Il me paraît après coup évident qu'il vaut mieux utiliser directement les heures #16:00#, etc. dans le code, comme vous l'avez fait. Plutôt que ces constantes qui induisent une comparaison avec un double. (Voir la sub TestRoundingBug(), à la suite du code).

    Méthodes de test :
    Citation Envoyé par Maxence
    La série de tests permet d'avoir à priori l'ensemble de toutes les valeurs aléatoirement.
    +1. C'est excellent, on l'utilise très souvent pour remplir des tables de test (voir les générateurs de Freg.G dans Formule1...)
    Citation Envoyé par Maxence
    Pas besoin de faire de procédure de tests encodée VBA, car, si je suis le raisonnement jusqu'à bout, il faudrait une procédure de tests qui teste la procédure de tests
    Là, par contre, pas d'accord. Il n'y a jamais une seule méthode, mais toujours tout un jeu. J'ai préféré une méthode + graphique, qui affiche tout de suite l'ensemble des règles à respecter, et me permet (quelle que soit l'interprétation des heures 'charnières', merci, Serge ) de me concentrer sur les changements d'état... D'où le choix de granularité : un test toutes les 1/2 heures.
    Je pense aujourd'hui que le tableau idéal incluerait, en plus des tests aléatoires, surtout des tests sur les valeurs telles que, si on admet une granularité d'une minute mini : #04:59#, #05:00#, #05:01#, puis #14h29#, #14h30#, #14h31#, etc.
    Attention aussi aux 15000 tests : j'ai peur que tu ne les lises trop vite, et que tu rates une erreur au milieu de tant de données ?

    Quant au paradoxe de la routine de test qu'il faut aussi tester et déboguer , oui, ça paraît aussi stupide que d'écrire le test avant la fonction à tester, mais ça fait partie du jeu. J'ai eu un bug dans ma sub Test(), à cause d'un copier-coller trop rapide. Et pan pour moi.
    Pour + de détails, voir l'article de Sébastien.

    Si je me permets d'être aussi bavard, c'est pour insister lourdement : la pratique n'est jamais aussi systématique que la théorie.
    - ici, on a une règle qui dit : commençons par écrire le test (ce qui veut dire : visualisation des résultats et de leur contrôle)
    - au cas par cas, on fait ça rarement avant. Généralement après, et surtout, ça évolue pendant : à chaque nouvelle question -> réajustement du test -> mise au propre de la fonction -> réexamen des résultats -> ...
    Rien n'est figé.

    Donc, soyons lourd de chez lourd, comme l'a bien senti Serge :
    - Prendre son temps pour analyser le problème,
    - prendre son temps pour se demander quels tests il faudra faire, et lesquels,
    - prendre le temps de se relire, de tout contrôler,
    - prendre le temps de nettoyer le code, de le commenter (un bon code, ça doit se lire comme un polar )
    - prendre le temps,
    - prendre le temps,
    - prendre le temps...
    - tester,
    - tester,
    - tester...

  16. #36
    Expert confirmé

    Profil pro
    Inscrit en
    Mai 2005
    Messages
    3 419
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 419
    Points : 4 297
    Points
    4 297
    Par défaut
    bravo pour cette excellente discussion

    juste une remarque sur l'utilisation des constantes horaires
    les scrupules me semblent injustifiés

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     
     
    Function valconst()
    Dim heure As Integer
    Dim minute As Integer
    Dim seconde As Integer
    Dim maconstante As Single
    Dim monheure As Double
    For heure = 1 To 24
      For minute = 1 To 60
        For seconde = 1 To 60
        monheure = TimeSerial(heure, minute, seconde)
        maconstante = (heure / 24) + (minute / 24 / 60) + (seconde / 24 / 60 / 60)
             If monheure <> maconstante Then
             MsgBox (monheure)
             Exit Function
             End If
        Next seconde
     Next minute
    Next heure
    MsgBox ("constantes à priori valides")
    End Function
    toutefois ...
    "Si vous ne déclarez pas explicitement le type d'une constante à l'aide de As type, la constante se voit attribuer le type de données qui convient le mieux à l'argument expression" (doc sic)

    ne suffirait t'il pas
    de mettre const onzheur=11/24

    sachant que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    Function testeconst()
    Const tiers = 1 / 3
    Dim untiers As Double
    untiers = 1 / 3
    MsgBox (tiers = untiers)
     
    End Function

  17. #37
    Membre expérimenté
    Avatar de Papy Turbo
    Homme Profil pro
    Développeur Office/VBA
    Inscrit en
    Mars 2004
    Messages
    822
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Office/VBA
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2004
    Messages : 822
    Points : 1 709
    Points
    1 709
    Par défaut
    Bonjour, random
    Citation Envoyé par random
    les scrupules me semblent injustifiés
    J'espère bien que tu as raison.
    Mes seuls scupules sont partis d'une erreur, à 5h00 du matin, non pas dans le résultat de mon test en VBA, mais seulement dans le tableau Excel, qui affichait "xxxx" (soit False), alors que j'attendais "-OK-".
    Il ne le fait plus
    D'où ma sub TestRoundingBug, qui ne révèle pas grand chose, sauf que la résultat des calculs est bien le même quel que soit le type de variable, mais est différent si on le tape directement (valeur : 0.208333333333333) dans le code VBA.
    Bien sûr, seule la représentation binaire est différente, mais on ne peut pas l'afficher...

    Ceci dit, attention aux contresens :
    Citation Envoyé par random
    "Si vous ne déclarez pas explicitement le type d'une constante à l'aide de As type, la constante se voit attribuer le type de données qui convient le mieux à l'argument expression" (doc sic)
    1- Tous tes tests sont faits sur des variables, pas des constantes Attention, confusion de nommage dans
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Dim maconstante As Single
    2- Je ne sais pas d'où tu sors cette doc, vu que toute déclaration de "Const XXX As Type" donnera toujours une erreur de syntaxe.

    Ceci dit, impossible de typer un constante ? Pas en VBA
    - avec 'As Type' : oui
    - avec les bonnes vieilles extensions de nom de variable que plus personne n'utilise depuis ds siècles, non.
    Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    Public Sub TestTypeConstante()
    Const maCONSTANTEHeure = #5:00:00 AM#    'should be a date ?
    Const maCONSTANTEString$ = #5:00:00 AM# 'should be a string ?
    Const maCONSTANTEInteger% = maCONSTANTEHeure
    Const maCONSTANTESingle! = maCONSTANTEHeure
    Const maCONSTANTEDouble# = maCONSTANTEHeure
        
        Debug.Print "Heure : "; VarType(maCONSTANTEHeure), maCONSTANTEHeure
        Debug.Print "String : "; VarType(maCONSTANTEString), maCONSTANTEString
        Debug.Print "Integer : "; VarType(maCONSTANTEInteger), maCONSTANTEInteger
        Debug.Print "Single : "; VarType(maCONSTANTESingle), maCONSTANTESingle
        Debug.Print "Double : "; VarType(maCONSTANTEDouble), maCONSTANTEDouble
    End Sub
    Pour vérifier les types, clic sur VarType > F1.

    Tu as raison : ça ne vaut pas la peine de passer des heures sur ce sujet. Mais attention quand même aux conversions, sachant qu'une date est stockée dans un double donc il ne devrait y avoir aucun problème de conversion date <-> double, mais il y en aura avec des aller-retour entre single et date...

  18. #38
    Membre expérimenté
    Avatar de Papy Turbo
    Homme Profil pro
    Développeur Office/VBA
    Inscrit en
    Mars 2004
    Messages
    822
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Office/VBA
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2004
    Messages : 822
    Points : 1 709
    Points
    1 709
    Par défaut
    Bon, faut aussi qu'on avance (qu'on termine un jour) notre moteur qui est resté en panne pendant toute la récré.
    Je commence par le + simple :
    Citation Envoyé par Serge57
    Question sur le point :2- Déploiement : Quand tout est bon.
    Lors du déploiement vers l’utilisateur, laisses-tu tous les menus Access de base ?
    C'est un choix :
    1- applications ultra-rapides et ne nécessitant aucune protection particulière.
    Je travaille sur une série de ce type en ce moment : chaque application va tourner sur les postes d'un à 3 responsables, les saisies de données étant décentralisées (distribuées dans le monde) via des classeurs Excel (ça, c'est une autre histoire).
    Je laisse tout visible (menus, outils). Les documentations utilisateurs/développeurs et les séances d'installation/formation mettent l'accent sur les bêtises à ne pas faire, mais il n'y a même pas de mot de passe sur le code.
    Donc, ils peuvent tout faire. Il y a quelques plantages mineurs, mais je suis toujours là pour renvoyer la dernière version de l'application...
    2- applications "pro", distribuées à plusieurs dizaines/centaines d'utilisateurs distants :
    ::: blindage total, avec mots de passe au code, blocage fenêtre BDD et autres menus, authentification optionnelle pour les utilisateurs mais obligatoire pour les développeurs...
    ::: menus Access : je garde quelques commandes de type Fichier > Fermer ou Fichier > Quitter (réécrite spécifiquement, mais ils ne le savent pas), presque tout le menu Edition, toutes les commandes de filtrage (sur les turbo-formulaires en mode feuille de données )...
    ::: idem sur les barres d'outils : rechercher, filtrer...
    ::: tout le reste est spécifique à l'application : une commande par formulaire, reflétant la structure de l'application.
    Les impressions et sorties vers Excel, PDF, Mail..., sont sur chaque formulaire, dans une liste déroulante des Sorties (Voir cours 03-turbo-formulaires).

    Citation Envoyé par Serge57
    Serait-il pas plus judicieux de mettre la fenêtre du formulaire ‘UpdateWizard’ en modale ?
    Oui et non
    Non, si tu veux garder le passage de plein écran à vue réduite, redimensionnement, ... ou parce que c'est moins cher.
    L'exemple de la version "pro" est modal. Il n'affiche pas la liste des tables, l'avancement étant indiqué par une boîte de message avec jauge d'avancement (mais j'aime bien ton idée de voir ça sur la liste des tables).

    - j'aurai dû masquer le menu par défaut, mais pas le temps et il n'est pas accessible
    - il y a 4 étapes : la 1ère correspond à ce qu'on fait ici : mise à jour (pour les utilisateurs de la version précédente seulement) de l'ancienne base. Les autres étapes sont mineures : mise en lecture seule de l'application, installation d'un pilote pdf du commerce et création des icônes sur le bureau.
    C'est plus de boulot !
    -----------------------
    Maintenant, finie la récré, revenons en à notre bug :
    J’ai un petit problème sur l’application ‘SuiviAffaire_MaJ_V1_V2 2007-02-12.zip’. L’ayant décompressée et lancée, 1ère demande, recherche du fichier ‘SuiviAffaire_BDD_V2.dbt’ qui se trouve sous le même répertoire que l’application. La fenêtre recherche de fichier s’ouvre, je vois bien le fichier sous le répertoire en question, je le sélectionne et… erreur, message : le nom de fichier est incorrect, abandonner, Recommencer, Ignorer. Pas trouvée l’erreur !!!!
    Hé ben, faut la trouver. parce que c'est la base de tout développement : trouver ses propres bugs, ou ceux du développeur précédent.

    Je te propose d'ouvrir une nouvelle parenthèse, en repassant dans le cours 04-les bases du débogage, pour un moment.
    On va en profiter pour clarifier les notions de base telles que la chasse aux erreurs non prévues.

  19. #39
    Membre expérimenté
    Avatar de Papy Turbo
    Homme Profil pro
    Développeur Office/VBA
    Inscrit en
    Mars 2004
    Messages
    822
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Office/VBA
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2004
    Messages : 822
    Points : 1 709
    Points
    1 709
    Par défaut Les cours sont terminés
    Un très très grand merci à Serge qui a servi de cobaye pour cette première expérience de cours "en direct", et bien sûr à tous les membres du forum et ceux de l'équipe Access qui ont apporté leur soutien et leurs commentaires, directement ou par MP.

    Nous nous sommes amusés pendant près d'un an et demi, à survoler, sans aucun plan, les divers aspects de construction et mise au point d'une application de gestion type, avec base de données et interface.

    Je vais maintenant, pendant les semaines/mois qui viennent, réexaminer tout ça pour voir ce qu'on peut concrètement en retirer. En gros, un exemple d'application type avec
    - un formulaire type, (plein d'autres sont possibles)
    - un début de bibliothèque pour stocker du code et des objets réutilisables,
    - un journal d'erreur qui enregistre les erreurs non prévues,
    - un moteur de mise à jour de la base, qui peut aussi servir de point de départ pour toute synchronisation ou autre import/export de données entre 2 bases relationnelles (.mdb ou autres).
    - etc.

    Tous commentaires sont bienvenus, essentiellement sur les méthodes de travail, bien sûr (pour les questions techniques, il reste le forum )

    À plus...

Discussions similaires

  1. Mise à jour structure base de données
    Par engi dans le forum Langage SQL
    Réponses: 2
    Dernier message: 23/10/2007, 17h11
  2. Mise à Jour Champ Base de Donnée
    Par arjo54 dans le forum IHM
    Réponses: 0
    Dernier message: 10/10/2007, 15h38
  3. [MySQL] Mise à jour dynamique base de données
    Par Lili72430 dans le forum PHP & Base de données
    Réponses: 1
    Dernier message: 28/09/2007, 12h36
  4. Requête de mise à jour - Ouverture base de données
    Par ade94 dans le forum Requêtes et SQL.
    Réponses: 1
    Dernier message: 31/05/2007, 16h50
  5. Problème de mise à jour de base de données
    Par poirier dans le forum ASP
    Réponses: 2
    Dernier message: 26/05/2004, 11h38

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo