Question

Est-il préférable de montrer UserForms dans VBA comme ProgressBar modale ou non? Quelles sont les meilleures pratiques pour l'élaboration d'indicateurs de progrès dans VBA?

modales UserForms nécessitent l'utilisation de Application.Interactive = False, alors que UserForms modales par leur bloc nature toute interaction avec l'application jusqu'à ce que la procédure de base est terminée ou est annulée.

Si Application.Interactive = False est utilisé, cependant, la touche Echap interrompt l'exécution de code, de sorte que l'utilisation de la manipulation Application.EnableCancelKey = xlErrorHandler et l'erreur (Err.Number = 18) est nécessaire à la fois la UserForm et la procédure d'appel.

procédures d'appel à forte intensité de ressources peuvent également entraîner des événements CommandButton_Click et UserForm_Activate ratés d'allumage dans UserForms modales.

En général, les indicateurs de progrès qui utilisent UserForms modales semblent plus simples, car le code qui est en cours d'exécution est entièrement contenue dans le module UserForm, et il y a moins besoin de passer des variables.

Le problème, cependant, l'utilisation UserForms modal pour les indicateurs de progrès est qu'un module UserForm séparé est nécessaire pour chaque procédure qui a besoin d'un indicateur de progression, parce que la procédure d'appel doit se trouver dans la procédure de UserForm_Activate.

Ainsi, alors qu'il est possible d'avoir un seul indicateur de progression réutilisable dans un UserForm modales, il sera moins fiable que l'exécution du code à partir de plusieurs modes de transport UserForms.

Quel chemin est mieux?

Merci!

Était-ce utile?

La solution 2

Je vais fermer celui-ci et dire Modal est le gagnant. J'ai essayé les deux sens, mais vous finissez par essayer de fermer trop de lacunes avec userforms modales. Modal est plus difficile car il est plus stricte, mais il vous encourage à briser votre code en petits morceaux qui est mieux à long terme de toute façon.

Autres conseils

Il y a aussi une troisième voie, en utilisant le Application.StatusBar. Vous pouvez même simuler une vraie barre de progression en utilisant une séquence de U + 25A0 et U + 25A1 caractères.

Sans aucun doute Modal. Si vous allez considérer Modeless, vous devez l'exécuter sur un séparé hors processus fil et non sur le thread principal Excel.exe.

Je pense que le sujet initial vaut la peine de répondre puisque la question a été formulée si bien que Google trouve d'abord.

Section 1 - Théorie

La première chose à dire est que pour transférer les variables entre les modules est pas difficile du tout.

La seule chose que vous devez faire est de créer un module séparé et y mettre toutes les variables globales. Ensuite, vous pourrez les lire partout dans toutes les formes, des feuilles, des modules.

La deuxième chose est la fenêtre doit être un modales. Pourquoi ça? La réponse est pour maintenir la mobilité du code , à savoir

  1. la fonction où le procédé le plus courant est exécuté ne doit pas être situé dans le module de formulaire utilisateur
  2. vous pouvez appeler la fenêtre avec barre de progression de partout et
  3. la seule connexion entre la fonction de routine / procédure sont les variables globales

Ceci est un grand avantage d'être polyvalent ici.

Section 2 - Pratique

1) Créer un module "Déclaration" avec les variables globales:

StopForce public As Integer « Cette variable sera utilisée comme un indicateur que l'utilisateur appuie sur le bouton Annuler

PCTDone public As Single «C'est le% du travail qui a été fait déjà

CurrentFile public As String «Tout autre paramètre que nous voulons transférer à la forme.

2) Créer le formulaire avec le bouton. En cas OnClick du bouton il devrait y avoir un code où l'on se réfère à la variable globale StopForce Déclaration le module

 Private Sub CommandButton1_Click()

 Declaration.StopForce = 1
  End Sub

3) Ajouter une procédure dans laquelle vous mettez à jour la barre de progression

Sub UpdateProgressBar(PCTDone_in As Single)
With UserForm1
    ' Update the Caption property of the Frame control.
    .FrameProgress.Caption = Format(PCTDone_in, "0%")
    ' Widen the Label control.
    .LabelProgress.Width = PCTDone_in * _
        (.FrameProgress.Width)
    ' Display the current file from global variable   
    .Label1.Caption = Declaration.CurrentFile
End With
End Sub

4) dans un autre module, nous devons avoir les fonctions ou la procédure / sous où la routine est fait:

 For i=1 to All_Files

 Declaration.CurrentFile = myFiles (i)

 FormFnc.UpdateProgressBar (i / .Range("C11").Value)


 DoEvents

 If Declaration.StopForce = 1 Then
    GoTo 3
 End If

 Next i

En fait, vous avez des propriétés suivantes, entraînant avantages / inconvénients selon vos besoins:

Type      | Impact on UI | Impact on caller execution
----------|--------------|-----------------------------
Modal     | Blocked      | Blocked until Form is closed
Modeless  | Not blocked  | Continues

Si vous voulez bloquer l'interface utilisateur et laisser l'appelant continuer, vous devez ouvrir le formulaire en mode modal avec Application.OnTime.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top