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

Macros et VBA Excel Discussion :

Proposition de résolution des conflits de manipulation des statuts


Sujet :

Macros et VBA Excel

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre Expert
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    1 508
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 508
    Par défaut Proposition de résolution des conflits de manipulation des statuts
    Bonjour,

    Suite à plusieurs discussions sur la manipulation du statut de l'activation des évènements, calculs, affichage, protection des feuilles ect ... qui est source de conflit,
    je me suis penché sur le problème.

    Historiquement, des problèmes peuvent apparaitre lors de l'appel de sous-fonction qui manipulent ces status, dont la fonction appelante n'a pas conscience (et elle n'a pas à s'en préoccuper).
    Par exemple:
    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
    Public Sub Foo()
        Application.ScreenUpdating = False
        '// code qui manipule l'affichage
     
        Bar
        '// code qui manipule l'affichage
     
        Application.ScreenUpdating = True
    End Sub
     
    Private Sub Bar()
        Application.ScreenUpdating = False
     
        '// code qui manipule l'affichage
     
        Application.ScreenUpdating = True
    End Sub
    La fonction Bar rétablit l'affichage, en conséquence, les instructions suivantes mettant à jour l'affichage provoquent d'horribles clignotements à l'écran, ce qui dégrade l'expérience utilisateur.

    Une première solution peut consister à ne désactiver l'affichage que dans la fonction de plus haut niveau:
    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 Foo()
        Application.ScreenUpdating = False
        '// code qui manipule l'affichage
     
        Bar
        '// code qui manipule l'affichage
     
        Application.ScreenUpdating = True
    End Sub
     
    Private Sub Bar()
        '// code qui manipule l'affichage
    End Sub
    Mais, cela implique que la fonction appelante aie une idée précise du comportement des fonctions appelées,
    et que les fonctions appelées assument que la fonction appelante a pris ses dispositions.
    Ce qui en contradiction avec la Loi de Demeter.

    Une seconde solution peut consister à mémoriser l'état de l'affichage en début de fonction, et le restituer en fin de fonction:
    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
    Public Sub Foo()
        Application.ScreenUpdating = False
        '// code qui manipule l'affichage
     
        Bar
        '// code qui manipule l'affichage
     
        Application.ScreenUpdating = True
    End Sub
     
    Private Sub Bar()
        Dim ScreenUpdating As Boolean
        ScreenUpdating = Application.ScreenUpdating
     
        Application.ScreenUpdating = False
        '// code qui manipule l'affichage
     
        Application.ScreenUpdating = ScreenUpdating
    End Sub
    C'est correcte, mais c'est une approche défensive de la programmation, d'une part lourdingue, d'autre part qui détourne le développeur de sa tâche première: Produire une fonction avec le comportement escompté.

    N'y a t'il pas un moyen d'automatiser la sauvegarde / restauration de ces status ?
    Je pense que oui, via une classe au final fort simple, qu'il suffira d'instancier (et oublier sa présence):
    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
    '// Class ApplicationStateHolder
    Option Explicit
     
        '// référence vers l'application
    Private mApp As Excel.Application
     
        '// Status que l'on désire mémoriser
    Private mEnableEvents As Boolean
    Private mScreenUpdating As Boolean
    Private mCalculation As Boolean
     
        '// Pseudo-constructeur
        '// Memorisation des status
    Friend Sub Create(ByRef App As Excel.Application)
        Set mApp = App
        mEnableEvents = mApp.EnableEvents
        mScreenUpdating = mApp.ScreenUpdating
        mCalculation = mApp.Calculation
    End Sub
     
        '// Destructeur
        '// Restitution des status
    Private Sub Class_Terminate()
        mApp.enableevent = mEnableEvents
        mApp.sceenupdating = mScreenUpdating
    End Sub
    Cette classe nécéssite un module Factory pour être instanciée:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    '// Module: Factory
    Option Explicit
     
    Public Function CreateApplicationStateHolder(ByRef App As Excel.Application) As ApplicationStateHolder
        Dim State As ApplicationStateHolder
        Set State = New ApplicationStateHolder
     
        State.Create App
        Set CreateApplicationStateHolder = State
    End Function
    Demo:
    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
    Public Sub Foo()
        Dim State As ApplicationStateHolder
        Set State = Factory.CreateApplicationStateHolder(Application)
     
        Application.ScreenUpdating = False
        '// code qui manipule l'affichage
     
        Bar
        '// code qui manipule l'affichage
    End Sub
     
    Private Sub Bar()
        Dim State As ApplicationStateHolder
        Set State = Factory.CreateApplicationStateHolder(Application)
     
        Application.ScreenUpdating = False
        '// code qui manipule l'affichage
    End Sub
    Lorsqu'une fonction se termine, l'instance State est détruite, ce qui entraine la restauration des status sauvegardés en début de fonction.
    Les fonctions Foo et Bar peuvent maintenant manipuler l'affichage pour leurs besoins propre, sans avoir à se soucier de ce qu'on fait leurs prédécesseurs, ni ce que feront leurs successeurs,
    elles sont plus facile à lire et à comprendre.
    Des classes reposant sur le même principe, concernant les feuilles (protection) ou autre objet sont envisageable.

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Formateur et développeur chez EXCELLEZ.net
    Inscrit en
    Novembre 2003
    Messages
    19 125
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : Belgique

    Informations professionnelles :
    Activité : Formateur et développeur chez EXCELLEZ.net
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2003
    Messages : 19 125
    Billets dans le blog
    131
    Par défaut
    Bonjour.

    Si on architecture correctement son code, on n'a pas pas besoin de tous ces montages.

    Les procédures événementielles gèrent les propriétés d'application et appellent les fonctions qui réalisent le travail applicatif. Il n'y a alors jamais de conflit ni de restauration d'options d'application intempestives.
    "Plus les hommes seront éclairés, plus ils seront libres" (Voltaire)
    ---------------
    Mes billets de blog sur DVP
    Mes remarques et critiques sont purement techniques. Ne les prenez jamais pour des attaques personnelles...
    Pensez à utiliser les tableaux structurés. Ils vous simplifieront la vie, tant en Excel qu'en VBA ==> mon tuto
    Le VBA ne palliera jamais une mauvaise conception de classeur ou un manque de connaissances des outils natifs d'Excel...
    Ce ne sont pas des bonnes pratiques parce que ce sont les miennes, ce sont les miennes parce que ce sont des bonnes pratiques
    VBA pour Excel? Pensez D'ABORD en EXCEL avant de penser en VBA...
    ---------------

  3. #3
    Membre Expert
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    1 508
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 508
    Par défaut
    C'est un vœux pieux.

    Je craint que la réalité du terrain ne soit tout autre.

  4. #4
    Rédacteur/Modérateur


    Homme Profil pro
    Formateur et développeur chez EXCELLEZ.net
    Inscrit en
    Novembre 2003
    Messages
    19 125
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : Belgique

    Informations professionnelles :
    Activité : Formateur et développeur chez EXCELLEZ.net
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2003
    Messages : 19 125
    Billets dans le blog
    131
    Par défaut
    Citation Envoyé par deedolith Voir le message
    C'est un vœux pieux.

    Je craint que la réalité du terrain ne soit tout autre.
    Dans un projet VBA, de mon expérience, on est souvent tout seul. Donc soit on code selon les règles et on n'a pas besoin d'une classe pour gérer les options d'application, soit pas et on oubliera d'utiliser une classe (dans chaque fonction?) et de toute façon le code sera merdique sous d'autres aspects. Et si on voulait être exhaustif, on ne se limiterait pas à trois propriétés d'application.

    Donc perso, je ne vois pas l'utilité de la chose.
    "Plus les hommes seront éclairés, plus ils seront libres" (Voltaire)
    ---------------
    Mes billets de blog sur DVP
    Mes remarques et critiques sont purement techniques. Ne les prenez jamais pour des attaques personnelles...
    Pensez à utiliser les tableaux structurés. Ils vous simplifieront la vie, tant en Excel qu'en VBA ==> mon tuto
    Le VBA ne palliera jamais une mauvaise conception de classeur ou un manque de connaissances des outils natifs d'Excel...
    Ce ne sont pas des bonnes pratiques parce que ce sont les miennes, ce sont les miennes parce que ce sont des bonnes pratiques
    VBA pour Excel? Pensez D'ABORD en EXCEL avant de penser en VBA...
    ---------------

  5. #5
    Rédacteur

    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2013
    Messages
    1 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Finance

    Informations forums :
    Inscription : Août 2013
    Messages : 1 033
    Par défaut
    Bonjour,
    Je trouve l'approche intéressante.

    J'ai testé après avoir corrigé quelques coquilles dans le module de classe présenté :
    - lignes 24 et 25 : les noms des variables ne sont pas corrects soit "mApp.EnableEvents = mEnableEvents" et "mApp.ScreenUpdating = mScreenUpdating"
    - il manque la suite logique : "mApp.Calculation = mCalculation" ;
    - ligne 10 : "Private mCalculation As Long" et pas "As Boolean".

    J'ai aussi ajouté une variable pour gérer la forme du curseur, et tout semble fonctionner correctement.

  6. #6
    Membre Expert
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    1 508
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 508
    Par défaut
    @Laurent_ott:
    C'est une proposition (ou un POC), il faut vraiment la prendre comme cela.
    L'essentiel reste le principe.

    A adapter selon les besoins.

  7. #7
    Membre Expert Avatar de Thumb down
    Homme Profil pro
    Retraité
    Inscrit en
    Juin 2019
    Messages
    1 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Juin 2019
    Messages : 1 575
    Par défaut
    Bonsoir,
    Ta proposition pour résoudre les conflits de manipulation des statuts dans les macros Excel est vraiment bien pensée. Voici quelques points à prendre en considération :


    1. Simplicité d'utilisation : Ta solution avec la classe ApplicationStateHolder et le module Factory rend la gestion des statuts super facile. En encapsulant la logique de sauvegarde et de restauration dans une classe dédiée, ça simplifie grandement le travail pour les développeurs. Cela réduit aussi les risques d'erreurs et facilite la maintenance du code.
    2. Conformité aux principes de programmation : Ta façon de faire respecte des principes solides de programmation comme la Loi de Demeter en réduisant les dépendances entre les différentes parties du code. Ça rend le code plus modulaire et réutilisable, ce qui est super important pour développer des applications solides et évolutives.
    3. Extensibilité : Ta proposition suggère même d'étendre cette approche à d'autres aspects de la manipulation des feuilles Excel, comme la protection des feuilles. Ça montre que ton idée est flexible et peut répondre à différents besoins.
    4. Gestion des erreurs : Ça pourrait être une bonne idée d'ajouter une gestion des erreurs dans ta classe ApplicationStateHolder pour être sûr que les statuts sont toujours restaurés même en cas d'erreur pendant l'exécution des macros.
    5. Documentation et bonnes pratiques : Il serait bien d'accompagner cette solution d'une documentation claire expliquant son fonctionnement et ses avantages, ainsi que des bonnes pratiques pour son utilisation. Ça assurerait une bonne adoption par d'autres développeurs.


    En résumé, ta proposition semble être une solution efficace et élégante pour résoudre les conflits de manipulation des statuts dans les macros Excel. Elle est simple, conforme aux principes de programmation et extensible pour répondre à différents besoins.

Discussions similaires

  1. JDK 7: Proposition 12 : déclaration des propriétés
    Par vbrabant dans le forum Langage
    Réponses: 127
    Dernier message: 16/10/2008, 19h13
  2. Proposition pour creation des PDF
    Par debutantasp dans le forum ASP
    Réponses: 1
    Dernier message: 29/04/2008, 14h54

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