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

VBA Access Discussion :

Chronomètre et progress bar pour suivre le déroulement d'un traitement long


Sujet :

VBA Access

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    FMJ
    FMJ est déconnecté
    Membre éclairé
    Profil pro
    tutu
    Inscrit en
    Octobre 2003
    Messages
    417
    Détails du profil
    Informations personnelles :
    Localisation : France, Aveyron (Midi Pyrénées)

    Informations professionnelles :
    Activité : tutu

    Informations forums :
    Inscription : Octobre 2003
    Messages : 417
    Par défaut Chronomètre et progress bar pour suivre le déroulement d'un traitement long
    Bonjour,

    Dans un formulaire où l'utilisateur lance à destination d'un SQL Server un traitement long de synchronisation avec de nombreuses requêtes SQL, j'ai souhaité inclure une progress bar et un chronomètre permettant à l'utilisateur de visualiser l'avancement et la durée de ce traitement de plusieurs minutes (et surtout d'avoir une idée approximative de la durée restante).

    Pour la progress bar, j'ai utilisé un contrôle activex et pour le calcul du pourcentage d'avancement, je n'ai pas réinventé la poudre --> au début, calcul du nombre d'enregistrements puis insertion d'une clause if dans les boucles de recordsets qui met à jour la progress bar tous les 100, 200, ou etc. enregistrements. Ca marche bien.

    Pour le chronomètre, j'ai un peu plus de mal.
    Tout d'abord, j'ai essayé de passer par le Form_Timer et le GetTickCount du kernel32. Ca marche très bien pour des phases statiques mais ... comme VBA ne gère pas le parallel processing, Form_Timer perd la main dès qu'une sub s'exécute. Et donc le chrono se fige jusqu'à ce que la sub ait fini de s'exécuter --> méthode inutilisable à l'intérieur d'un traitement.
    Ensuite, j'ai procédé comme pour la progress bar, en incrémentant le chrono dans les boucles de recordsets.

    Cela fonctionnerait pas trop mal ... s'il n'y avait un gros souci. En fait, certaines requêtes chargent via le réseau des recordsets assez volumineux (de type rst.Open "SELECT ......"), ce qui rend plutôt très long leur temps de chargement (plusieurs dizaines de secondes). Et donc durant ce laps de temps où cette instruction est exécutée, la progress bar et le chronomètre sont bien évidemment scotchés. Le chrono prend ensuite x secondes d'un coup dès que le rst.open est chargé et que la boucle du rst est exécutée.



    Au final, à moins de réaliser un recordset par enregistrement (ce qui serait contre-productif en terme de durée, puisque certaines tables font des dizaines de milliers de lignes), je ne vois pas comment je pourrais obtenir une progress bar et un chronomètre qui tiendraient la route ???!!!

    Auriez-vous quelques suggestions lumineuses qui pourraient m'aiguiller ? Merci d'avance.

  2. #2
    Membre émérite
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2010
    Messages
    801
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2010
    Messages : 801
    Par défaut
    Citation Envoyé par FMJ Voir le message
    Ca marche très bien pour des phases statiques mais ... comme VBA ne gère pas le parallel processing, Form_Timer perd la main dès qu'une sub s'exécute. Et donc le chrono se fige jusqu'à ce que la sub ait fini de s'exécuter --> méthode inutilisable à l'intérieur d'un traitement.
    Bonjour,
    Question bête : As-tu regardé la fonction DoEvents ?

  3. #3
    FMJ
    FMJ est déconnecté
    Membre éclairé
    Profil pro
    tutu
    Inscrit en
    Octobre 2003
    Messages
    417
    Détails du profil
    Informations personnelles :
    Localisation : France, Aveyron (Midi Pyrénées)

    Informations professionnelles :
    Activité : tutu

    Informations forums :
    Inscription : Octobre 2003
    Messages : 417
    Par défaut
    Bonjour et merci pour ta réponse.

    Malheureusement, DoEvents qui permet de passer momentanément la main à l'OS n'aide pas dans mon cas. Le problème ne vient pas d'un grand nombre d'itérations dans une boucle mais du fait qu'une seule instruction (un rst.open "SELECT ....") prend beaucoup de temps à charger un gros volume de données.

    Comme j'indiquais précédemment, il serait possible de faire un rst.open "SELECT ..." pour une seule ligne, avec la clause WHERE qui va bien, mais cela serait très contreproductif compte tenu du nombre de lignes (si ajouter un chrono pour patienter entraîner une rallongement de X2 de la durée, c'est pas glop).


    Autrement, je pourrais faire une boucle où le rst.open charge traite 100 lignes par chaque itération. Mais c'est compliqué du point de vue du requêtage car en SQL il y un "TOP x" (les x premiers) mais il n'existe pas un "TOP x y" (de la ligne x à la ligne y).
    Hummmm, je vais quand même explorer cette piste car il me vient une petite idée. Mais il faut que je vérifie quel est l'impact en terme de durée de traitement supplémentaire.


    Un début d'autre piste ? --> le multi-threating
    http://access.developpez.com/sources...acc#creaThread

  4. #4
    Rédacteur/Modérateur

    Avatar de Jean-Philippe André
    Homme Profil pro
    Architecte Power Platform, ex-Développeur VBA/C#/VB.Net
    Inscrit en
    Juillet 2007
    Messages
    14 682
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Canada

    Informations professionnelles :
    Activité : Architecte Power Platform, ex-Développeur VBA/C#/VB.Net
    Secteur : Finance

    Informations forums :
    Inscription : Juillet 2007
    Messages : 14 682
    Par défaut
    Bonjour,

    j'ai une autre piste pour toi, les images d'attente ^^

    L'excellent tuto d'Arkham46 devrait t'aider à faire patienter tout ton petit monde:
    http://arkham46.developpez.com/artic...s/formattente/
    Cycle de vie d'un bon programme :
    1/ ça fonctionne 2/ ça s'optimise 3/ ça se refactorise

    Pas de question technique par MP, je ne réponds pas

    Mes ouvrages :
    Migrer les applications VBA Access et VBA Excel vers la Power Platform
    Apprendre à programmer avec Access 2016, Access 2019 et 2021

    Apprendre à programmer avec VBA Excel
    Prise en main de Dynamics 365 Business Central

    Coffrets disponibles de mes ouvrages : https://www.editions-eni.fr/jean-philippe-andre
    Pensez à consulter la FAQ Excel et la FAQ Access

    Derniers tutos
    Excel et les paramètres régionaux
    Les fichiers Excel binaires : xlsb,

    Autres tutos

  5. #5
    FMJ
    FMJ est déconnecté
    Membre éclairé
    Profil pro
    tutu
    Inscrit en
    Octobre 2003
    Messages
    417
    Détails du profil
    Informations personnelles :
    Localisation : France, Aveyron (Midi Pyrénées)

    Informations professionnelles :
    Activité : tutu

    Informations forums :
    Inscription : Octobre 2003
    Messages : 417
    Par défaut
    Bonjour et merci pour la proposition. On s'en tiendra aux images car l'autre solution proposée ne permet pas de résoudre mon pb : elle utilise un formulaire d'attente mis à jour toutes les X itérations du traitement.
    Or dans mon cas, ce sont des traitements correspondant à une seule commande (rst.open "SELECT ....") qui génère l'essentiel du temps d'attente. Donc je ne peux donc pas y insérer de DoEvents permettant de mettre à jour le formulaire d'attente.

    Il faut que je scinde cette commande en x commandes de durée largement inférieure pour pouvoir utiliser cette stratégie.

  6. #6
    Modérateur

    Homme Profil pro
    Inscrit en
    Octobre 2005
    Messages
    15 410
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations forums :
    Inscription : Octobre 2005
    Messages : 15 410
    Par défaut
    Oui si Access n'a pas la main, il ne peut pas faire la mise à jour.

    Deux idées :
    • Non testé : ouvrir une fenêtre IE qui affiche une page HTML toute bête avec un GIF animé et un message "Merci de patienter".
      On peut peut-être utiliser un ActiveX qui affiche le navigateur dans le form.
    • Ce que j'ai fait pour donner l'illusion de l'avancement progressif : avant le long traitement je fais avancer ma barre de progression de 50% de la distance prévue et quand le traitement est terminé je la met à 100%.


    A+
    Vous voulez une réponse rapide et efficace à vos questions téchniques ?
    Ne les posez pas en message privé mais dans le forum, vous bénéficiez ainsi de la compétence et de la disponibilité de tous les contributeurs.
    Et aussi regardez dans la FAQ Access et les Tutoriaux Access. C'est plein de bonnes choses.

Discussions similaires

  1. Réponses: 4
    Dernier message: 30/05/2012, 13h40
  2. Progress bar pour le chargement d'une datagrid
    Par johnaliashead dans le forum Silverlight
    Réponses: 6
    Dernier message: 28/04/2010, 12h43
  3. Progress Bar pour une initialisation de table
    Par souminet dans le forum Débuter
    Réponses: 4
    Dernier message: 01/12/2008, 10h58
  4. [FLASH 8 PRO] progress bar pour une fonction php
    Par jc_cornic dans le forum Flash
    Réponses: 6
    Dernier message: 08/11/2006, 20h55
  5. marche a suivre pour la creation d'un progress bar
    Par azde7015 dans le forum Access
    Réponses: 1
    Dernier message: 19/02/2006, 11h06

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