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 :

UserForm équivalent ScreenUpdating=False


Sujet :

Macros et VBA Excel

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre chevronné
    Homme Profil pro
    Ingénieur Industrialisation
    Inscrit en
    Mai 2015
    Messages
    222
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur Industrialisation
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2015
    Messages : 222
    Par défaut UserForm équivalent ScreenUpdating=False
    Salut à tous,

    Je voulais vous poser une question qui va peut-être vous paraître stupide, mais existe-t-il un équivalent de l' Application.ScreenUpdating pour UserForm ?

    Je vous explique mon "problème" (facultatif, si vous savez comment simplement enlever le rafraîchissement du UserForm, alors vous embêtez pas à lire ) :

    J'ai synchronisé une treeview (pour le côté arborescence) et une listview (pour le côté informations). À chaque Node, un ListItem est associé, est en face et tous les ListItems sont bien sûr dans le même ordre que les Nodes, etc.

    Pour les synchroniser, ce que j'ai fait est : quand je clique sur un ListItem (par exemple), je viens chercher la clé de l'item en haut de la partie visible à l'aide de GetFirstVisible.Key puis pour être sûr que la première node de la partie visible de la TreeView correspond au premier ListItem visible, j'affiche la dernière Node à l'aide d'EnsureVisible et ensuite j'affiche la node dont la clé est celle que je viens de récupérer dans la listview.

    Dans le cas où je pars de la TreeView, j'ai créé un équivalent (fonction récursive) au GetFirstVisible pour récupérer la clé et je fais de même.

    Tout marche comme sur des roulettes, cependant comme j'ai écrit, je passe par "afficher le dernier élément" puis "afficher l'élément choisi", ce qui fait un léger scintillement.
    Dans le cas des événements NodeClick, ItemClick, par exemple, ça ne pose aucun problème, c'est suffisamment léger... Par contre, dans le cas où l'on descend reste cliqué et que l'on déplace le curseur, j'ai adapté pour que ça sélectionne toujours l'item survolé (comme dans une ListBox) et là ça pose problème... Pire encore : j'ai bidouillé un truc pour que le scrolling de la souris permette de scroller dans la ListView ou dans la TreeView et que ça se fasse de manière synchronisée entre les 2 contrôles, et là ce scintillement gâche la fête... J'étais vraiment content d'arriver à faire ça mais maintenant ça fait un peu tâche.

    Si je pouvais juste avoir une sorte de ScreenUpdating = False ou empêcher le Repaint automatique ou j'en sais rien, ça m'arrangerait beaucoup !

    Merci d'avance pour votre aide !

    Quentin

    PS : si je n'ai pas utilisé de boucle pour trouver la node "FirstVisible", c'est parce que sur + de 10 000 nodes, ça galère... j'ai essayé.

  2. #2
    Membre Expert
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    652
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juin 2009
    Messages : 652
    Par défaut
    Bonjour,

    J'ai construis un exemple en recourant aux APIs qui solutionnera peut être votre problème.

    1) Créez un UserForm1 avec un Label1, un CommandButton1 et un CommandButton2
    2) Copiez le code suivant dans la fenêtre de code du UserForm
    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
    Private Declare Function FindWindow& Lib "user32" Alias "FindWindowA" ( _
       ByVal lpClassName$, ByVal lpWindowName$)
    Private Declare Function LockWindowUpdate& Lib "user32" ( _
       ByVal hwndLock&)
     
    Private Sub CommandButton1_Click()  '### Sans utilisation de USFScreenUpdating ###
    Label1 = 0
    Me.Repaint
    '---
    Call CompteTo30000
    End Sub
     
    Private Sub CommandButton2_Click()  '### Avec utilisation de USFScreenUpdating ###
    Label1 = 0
    Me.Repaint
    '---
    USFScreenUpdating False
    Call CompteTo30000
    USFScreenUpdating True  '/// ne pas oublier cette instruction pour la reprise en main
    End Sub
     
    Private Sub USFScreenUpdating(bool As Boolean)
    If bool Then
      LockWindowUpdate 0
    Else
      LockWindowUpdate FindWindow(vbNullString, Me.Caption)
    End If
    End Sub
     
    Private Sub CompteTo30000()
    Dim i&
    For i& = 1 To 30000
      Label1 = i&
      Me.Repaint
    Next i&
    End Sub
    Dans la pratique, il faut identifier les endroits de votre code où interviendra l'appel à USFScreenUpdating.
    Et surtout, rétablir la normalité avec USFScreenUpdating True pour la reprise en main de la suite du programme.
    Fichiers attachés Fichiers attachés

  3. #3
    Membre chevronné
    Homme Profil pro
    Ingénieur Industrialisation
    Inscrit en
    Mai 2015
    Messages
    222
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur Industrialisation
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2015
    Messages : 222
    Par défaut
    Bonjour PMO2017

    Merci pour votre aide ! Je trouve cette technique excellente, je vais probablement m'en servir souvent !

    Cependant, lorsque je teste avec des boucles et des captions, tout fonctionne parfaitement, mais avec ma treeview, cela ne semble pas avoir beaucoup d'impact... Mais en bidouillant un peu, je pense avoir réussi à gagner légèrement en scintillements, surtout au niveau du reste du USF qui subissait "fréquemment" des Repaints... (Les Repaints en question n'ayant aucun impact avec le scintillement au niveau de la TreeView...)

    Je vais essayer d'exploiter davantage cette piste car elle me semble très utile.

    Du coup, je me demande s'il existe l'équivalement mais uniquement pour un contrôle genre "TreeView.ScreenUpdating"... Avez-vous une piste du genre ?

    Merci encore

    Quentin

  4. #4
    Membre Expert
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    652
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juin 2009
    Messages : 652
    Par défaut
    Du coup, je me demande s'il existe l'équivalement mais uniquement pour un contrôle genre "TreeView.ScreenUpdating"... Avez-vous une piste du genre ?
    J'ai construis l'exemple de manière abstraite.
    N'étant pas en situation, je ne peux faire aucun test quant à l'efficacité sur un TreeView.
    Si vous avez la possibilité de mettre en pièce jointe votre classeur simplifié et édulcoré des données personnelles mais avec le TreeView posant problème, je pourrais effectuer des tests et voir si je peux apporter une solution. Sinon, je ne peux rien et il vous appartient, étant en situation, de faire évoluer l'optimisation.

    Bon courage.

  5. #5
    Membre Expert
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    652
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juin 2009
    Messages : 652
    Par défaut
    Vous pouvez essayer de récupérer le Hwnd du TreeView avec un code comme ce qui suit
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Private Sub CommandButton1_Click()
    Dim C As Control
    For Each C In Me.Controls
      MsgBox C.[_GethWnd] & "    " & C.Name & "    ID " & C.[_GetID]
    Next C
    End Sub
    puis le passer en paramètre à l'API LockWindowUpdate
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    LockWindowUpdate C.[_GethWnd]   'C = le contrôle qui va bien

Discussions similaires

  1. [XL-2007] Problème avec Screenupdating = False
    Par Lilou51 dans le forum Macros et VBA Excel
    Réponses: 10
    Dernier message: 02/10/2013, 19h07
  2. UserForm.Initialize & ScreenUpdating
    Par wipMan dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 10/07/2013, 10h54
  3. [XL-2003] Application.ScreenUpdating = False Marche pas
    Par jerjou26 dans le forum Macros et VBA Excel
    Réponses: 7
    Dernier message: 21/02/2012, 17h20
  4. [XL-2002] Inhiber le déplacement d'un UserForm que le ScreenUpdating est à False
    Par Touffe54 dans le forum Macros et VBA Excel
    Réponses: 16
    Dernier message: 08/11/2010, 12h39

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