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 :

[E-03] écran tremblotant


Sujet :

Macros et VBA Excel

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    39
    Détails du profil
    Informations personnelles :
    Âge : 76
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 39
    Par défaut [E-03] écran tremblotant
    J'ai réalisé une macro qui, au cours de son exécution, travaille sur deux fichiers identiques (l'un est obtenu enregistrement de l'autre avec SaveAs), ouverts simultanément.
    Elle doit exécuter une série de collages spéciaux discontinus dans deux feuilles "soeurs".
    En fait elle fait le premier collage sur la première feuille et ensuite sur la deuxième, puis le 2ème collage sur la première feuille et ensuite sur la deuxième ... et ainsi de suite pour la vingtaine de collages à réaliser.

    Pendant l'exécution, il y a tremblement de terre à l'écran, et l'application Screen.Updating qui fonctionne très bien avec un seul fichier ouvert, n'est pas efficace avec 2 fichiers ouverts simultanément.

    Connaissez-vous une solution ?

    Merci d'avance

  2. #2
    Membre Expert
    Avatar de JackOuYA
    Inscrit en
    Juin 2008
    Messages
    1 040
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 1 040
    Par défaut
    bonsoir,

    un peu de code pour comprendre comment vous utilisez :
    et l'application Screen.Updating
    nous serai surement utile .

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    39
    Détails du profil
    Informations personnelles :
    Âge : 76
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 39
    Par défaut un extrait de la macro
    Dans l'extrait de macro qui suit, chaque collage est de la forme

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    'collage 1    
    Range("D62:D109").Select
    Selection.Copy
    Range("E62:E109").Select
        Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
            :=False, Transpose:=False
    Extrait de la macro concernée (appelée par un bouton de la feuille nommée Barème)

    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
    Sub Modif()
    Application.ScreenUpdating = False
     
         If Range("Y4").Value = Range("D18").Value Then
            GoTo debumodif
        Else
            GoTo finmodif
        End If
     
    debumodif:
    Call copiferm
    'collage 1
    'collage 2
     
             Sheets("Fiche").Select
     
             Name = Range("B19").Value
             Range("B18").Value = ActiveWorkbook.Path & "\" & Name
             Chemin = Range("B18").Value
     
             Nom = Range("B49").Value
             Range("B48").Value = ActiveWorkbook.Path & "\" & Nom
             Route = Range("B48").Value   
     
        Application.DisplayAlerts = False
        ActiveWorkbook.SaveAs Filename:=Chemin        
        Workbooks.Open Filename:=Route
        Application.DisplayAlerts = True
     
        Sheets("Barème").Select
        'Collage 3
        'Collage 4
        'jusqu'à collage n
     
        ActiveWorkbook.Save
        ActiveWorkbook.Close
        ActiveWindow.Close
        Application.ScreenUpdating = True
     
    finmodif:
    End Sub
    Bien entendu, la macro copiferm appelée pendant l'exécution comporte elle aussi
    Application.ScreenUpdating = False au début, et
    Application.ScreenUpdating = True à la fin.

    En ai-je dit assez (ou trop) pour donner une idée de la situation ?

  4. #4
    Membre Expert
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 567
    Détails du profil
    Informations personnelles :
    Âge : 62
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 567
    Par défaut
    se sont les select qui font cet effet.
    le screenupdating (rafraichissement de l'écran limite cet effet, mais le mieux est de parvenir a enlever tout tes select.
    tu peux remplacer
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    Range("D62:D109").Select Selection.Copy
    Range("E62:E109").Select
        Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
            :=False, Transpose:=False
    par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    set origine = workbooks("premierclasseur".worsheets("premierefeuille")
    set cible= workbooks("deuxiemeclasseur".worsheets("deuxiemefeuille")
    origine.Range("D62:D109").copy
    cible.Range("E62:E109") .PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
            :=False, Transpose:=False

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    39
    Détails du profil
    Informations personnelles :
    Âge : 76
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 39
    Par défaut réponse à alsimbad
    Merci pour ta proposition. Dans un premier temps, j'avais posté une réponse, mais je me suis aperçu qu'elle ne tenait pas debout car je n'avais pas pigé l'utilisation de la désignation d'une variable. Je l'ai donc supprimée.

    Pour revenir à ta contribution : Tu m'as proposé
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    set origine = workbooks("premierclasseur".worsheets("premierefeuille")
    set cible= workbooks("deuxiemeclasseur".worsheets("deuxiemefeuille")
    origine.Range("D62:D109").copy
    cible.Range("E62:E109") .PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
            :=False, Transpose:=False
    Ce qui evite tout Select.
    En fait, dans mon projet, les deux classeurs ont les même feuilles, puisque l'un est obtenu par enregistrement de l'autre via Save.as
    La macro colle certaines cellules de la feuille nommée Barème sur d'autres cellules de la même feuille.
    Elle fait cela dans le premier classeur, puis dans le deuxieme classeur.
    Et elle recommence la même chose pour le deuxième collage. Et donc n fois pour les n collages. Ce qui génère 2n déplacements.

    En m'inspirant de la syntaxe de ton code, j'ai écrit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Worksheets("Barème").Range("D62:D109").copy
    Worksheets("Barème").Range("E62:E109") .PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
            :=False, Transpose:=False
    'id pour collage2
    'id pour collage3
    'etc
    Cela a 2 avantages :
    - tous les Set sont supprimés
    - au lieu de travailler en séquentiel, collage par collage, elle travaille en continu en faisant tous les collages de la première feuille Barème et effectue ensuite tous les collages de la deuxième feuille Barème.

    Résultat :
    - Beaucoup plus rapide car moins de déplacements
    - Mais on voit toujours à l'écran le travail effectué par la macro.
    Cela dit, les déplacements n'étant plus si nombreux, cela tressaute beaucoup moins, et l'effet produit n'est pas si désagréable.

    Je crois que je vais m'en contenter, mais je reste quand même sur ma faim quant à Screen.Updating

  6. #6
    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
    Bonsoir

    Le problème vient du fait de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    application.screenupdating = true
    à la fin de la macro copiferm

    Tu dois mettre screenupdating = false au début de la macro Modif puis le mettre à True à la fin de la macro. Il ne faut pas modifier le screenupdating entre ces deux lignes, et surtout pas dans les macros qui sont appelées au cours de la procédure Modif
    "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...
    ---------------

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    39
    Détails du profil
    Informations personnelles :
    Âge : 76
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 39
    Par défaut Réponse à PF
    Pour être sûr de mon coup, j'ai rebâti mon projet pour supprimer la Sub copiferm et en intégrer le contenu à la macro incriminée, en prenant soin de n'avoir qu'un ScreenUpdating = False au début et un = True à la fin. Déception, ça ne changeait rien !

    J'étais prêt à te faire part de cet échec, mais à la réflexion, j'ai compris que tu avais parfaitement raison malgré tout.

    Pourquoi ?
    Dans mon message d'ouverture, j'avais écrit :
    J'ai réalisé une macro qui, au cours de son exécution, travaille sur deux fichiers identiques (l'un est obtenu par enregistrement de l'autre avec SaveAs), ouverts simultanément.
    Si j'ai bien compris le fonctionnement de SaveAs, ça équivaut à "Enregistrer sous," c'est-à-dire que ça crée un "fichier fils" et ça ferme le "fichier père". Donc, pour avoir mes deux fichiers ouverts simultanément, il a fallu qu'après le SaveAs, je rouvre le fichier père avec Workbooks.Open, comme tu as pu le voir dans l'extrait de macro que j'ai posté dans un autre message.

    Et c'est là que se situait le problème, car le fichier père, et par voie de conséquence le fichier fils, comportaient une macro exécutable à l'ouverture dans ThisWorkbook, et qui contenait un ScreenUpdating = False au début et un = True à la fin.

    Solution
    Il fallait que j'agisse sur les instructions Screen à l'endroit de la rupture, donc à la réouverture du fichier père, donc dans la Private Sub Workbook_Open de ThisWorkbook. Si je les enlève toutes les deux, c'est à l'ouverture normale qu'a lieu la valse.

    J'ai alors tenté de n'enlever que l'instruction True de la fin. Et ça marchait évidemment très bien pour la macro. Mais, alors que je m'attendais à une difficulté pour l'ouverture normale (instruction de masquage d'écran au début sans instruction d'affichage à la fin), et bien ça fonctionne à merveille.

    Conclusion
    Tu avais raison, c'était bien un problème de Screen, et il est résolu.
    Mais j'ai maintenant un questionnement métaphysique : pourquoi est-ce que ça marche si bien à l'ouverture normale sans le True de la fin ?

  8. #8
    Inactif  

    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    4 555
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 4 555
    Par défaut
    Citation Envoyé par ogho4326 Voir le message
    Tu avais raison, c'était bien un problème de Screen, et il est résolu.
    Mais j'ai maintenant un questionnement métaphysique : pourquoi est-ce que ça marche si bien à l'ouverture normale sans le True de la fin ?
    Bonsoir, ogho4326,

    Je vais tenter de répondre le plus simplement possible à cette question précise :
    Application.ScreenUpdating concerne la totalité de ton application et non la seule fenêtre qu'elle ouvre, parmi ses différentes fenêtres.
    C'est probablement la raison pour laquelle je préfère, en ce qui me concerne, ne pas courir le moindre risque et donner la main à la fonction LockWindowUpdate de la librairie user32 de l'Api de Windows, qui, elle, bloque l'affichage (ou le rétablit) de la fenêtre considérée. L'utilisation de cette dernière fonction présente :
    - un avantage (notamment en matière de maintenance d'une application) : ===>> celui de ne pas avoir à faire l'inventaire de ce qui est ou non en cours.
    - un inconvénient : ===>> celui d'avoir d'abord à extraire le hwnd de la fenêtre dont l'affichage est à bloquer ou libérer.

    En conclusion :
    - d'un côté : le confort, mais au prix de sans cesse savoir où l'on en est des affichages
    - de l'autre côté : l'inconfort relatif mais avec la récompense de ne pas imposer à celui qui aurait à maintenir l'application, d'avoir à jouer à la "bataille navale" à tout bout de champ.

    Il est toujours agréable, lorsque l'on intervient en maintenance sur une application, d'y trouver une gestion claire et simple de l'affichage de chaque fenêtre, prise et traitée séparément.

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    39
    Détails du profil
    Informations personnelles :
    Âge : 76
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 39
    Par défaut à ucfoutu
    Extrait de ta réponse :
    ...je préfère ... donner la main à la fonction LockWindowUpdate de la librairie user32 de l'Api de Windows
    ... un inconvénient : celui d'avoir d'abord à extraire le hwnd de la fenêtre dont l'affichage est à bloquer ou libérer.
    J'avoue que tout cela me dépasse. Comment s'y prend-on ?
    Quel est le code à utiliser ?
    Extraire le hwnd : ou ? quand ? comment ?

    Merci de m'éclairer

  10. #10
    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
    Bonsoir

    Conclusion
    Tu avais raison, c'était bien un problème de Screen, et il est résolu.
    Mais j'ai maintenant un questionnement métaphysique : pourquoi est-ce que ça marche si bien à l'ouverture normale sans le True de la fin ?
    Lorsque "la main" est rendue à Excel après l'exécution d'une macro, l'écran est "habituellement" rafraîchi et le screenupdating repasse à TRUE.

    Je dis "habituellement" car j'ai déjà remarqué par exemple que lorsqu'il y a une impression exécutée durant la macro et par la macro, le screenupdating n'est pas remis automatiquement à true lorsque la main est rendue à Excel. C'est pourquoi il est préférable de repasser la proriété à true en fin de macro, mais ce n'est pas "systématiquement" obligatoire.
    "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...
    ---------------

  11. #11
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    39
    Détails du profil
    Informations personnelles :
    Âge : 76
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 39
    Par défaut Réponse à PF
    Merci, ça explique tout.
    Me voilà libéré !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 17
    Dernier message: 17/10/2002, 20h06
  2. Réponses: 6
    Dernier message: 10/09/2002, 03h35
  3. plein écran
    Par patapetz dans le forum OpenGL
    Réponses: 9
    Dernier message: 21/08/2002, 14h15
  4. Creer un écran de veille
    Par Willand dans le forum C++Builder
    Réponses: 2
    Dernier message: 09/08/2002, 12h36
  5. recuperer la résolution de l'écran
    Par florent dans le forum C++Builder
    Réponses: 11
    Dernier message: 07/06/2002, 15h01

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