XL 2016 Userform Modal / Non Modal - Suspension code

vgendron

XLDnaute Barbatruc
Bonjour à toutes et tous!

Je viens vers vous pour un souci d'utilisation des formulaires en mode modal et non modal.

De ce que j'ai compris et vu
le mode MODAL (par défaut à la création d'un Userform)
- ne permet pas d'acceder aux feuilles du classeur pendant l'execution du code
- l'appel en cascade de formulaires suspend l'execution du code du formulaire "Amont" jusqu'à ce que le formulaire "aval" soit fermé
- le formulaire "Amont" reste visible, mais est inaccessible

le mode NON modal
- permet d'acceder aux feuilles du classeur pendant l'execution du code
- l'appel en cascade de formulaires ne suspend PAS l'execution du code du formulaire "Amont" ==> Pendant que le formulaire "aval" est executé, tout le code du formulaire du formulaire "amont" se déroule.
- les formulaires sont tous visibles et accessibles indépendamment..

jusque la.. c'est plutot clair..

l'ennui, c'est que moi.. je veux un peu des deux....
du modal avec accces aux feuilles du classeur....
ou du NON modal avec Suspension du code du formulaire amont...

j'étais parti avec des formulaires TOUS en NON modal
et lorsqu'un formulaire "Amont" appel un formulaire "Aval", pour éviter d'interagir sur les deux formulaires en meme temps, je mettais un "formulaire amont.hide" avant d'appeler le formulaireaval .show

l'ennui, c'est que toute une partie du code du formulaire Amont dépend de ce qui a été fait dans le formulaire aval.... et donc.. il me manque le moyen de suspendre le code...
à noter. que dans mon appli, j'ai près de 70 userforms qui peuvent interagir les uns avec les autres.. certains ne peuvent etre appelés QUE par un formulaire, d'autres. par plusieurs..

peut etre est il finalement plus simple de mettre tout le monde en MODAL et avoir une astuce pour garder les feuilles excel accessibles ??

auriez vous une idée ?
 

Pièces jointes

  • Test Formulaire Modal.xlsm
    30.6 KB · Affichages: 17

Dranreb

XLDnaute Barbatruc
Bonjour.
Pourquoi suspendre un code ? En exécuter un quand il faut plutôt ! Personnellement je préfèrerais tout en non modal, les UserForm étant équipés de méthodes pouvant être invoquées depuis n'importe où, y compris d'autres UserForm. Il est même possible de faire décréter des évènements à un UserForm et de les prendre en charge dans d'autres, si ça vous intéresse.
 

vgendron

XLDnaute Barbatruc
Bonjour Bernard
pourquoi suspendre un code?
parce que ce code agit différemment selon ce qu'a fait le userform aval
exemple
Userform1 s'initialise
met un text dans le Textbox
appelle le userform2
celui ci modifie ou pas le text du userform1
fermeture du userform2 ==> retour au userform1
SUITE du code du useform1
si contenu a été modifié alors Code 1
si contenu non modifié alors code 2.

dans le cas du non modal, la Suite du code s'est déroulée avant meme que le formulaire2 ait été refermé.. voire meme avant que l'utilisateur ait eu le temps de changer quoique ce soit dans le userform2
d'ou l'utilité de "suspendre" le code. ce qui est implicite dans le cas des formulaires "modal"

De mon coté, je préfère également le tout "NON modal" qui me permet de garder accès au fichier excel.. ne serait ce que pour vérifier ce que fait le code pendant son execution..
mais.. je ne vais pas etre tout seul à utiliser l'appli....
on a beau dire aux gens qu'il ne faut pas aller cliquer n'importe ou pendant l'execution, les gens sont.. comment dire.....:-D

maintenant, tu parles de prise en charge d'évènement d'un userform par un autre... je suis tout à l'écoute :-D
 

Dranreb

XLDnaute Barbatruc
Ça n'implique pas de suspendre le code dans l'UserForm appelant: ça implique d'en exécuter un autre lorsque l'appelé a fini de faire ce qu'il avait à faire. Et ça, ce dernier peut le faire soit en invoquant une méthode de l'appelant, soit en décrétant un évènement pris en charge par l'appelant.
Il faut savoir qu'un UserForm est en fait un module de classe. Son nom est en fait essentiellement un nom de type, et pas seulement le nom d'un exemplaire par défaut implicitement déclaré:
Public UserForm1 As New UserForm1
Mais s'il porte des instructions Event et RaiseEvent, il faut pour les prendre en charge dans un autre module objet y déclarer :
Private WithEvents UFmX As UserForm1
et l'initialiser par :
Set UFmX = New UserForm1
Moyennant quoi des Private Sub UFmX_QuelqueChose peuvent être installées à l'aide des listes déroulantes qui surmontent la fenêtre de code.
 

vgendron

XLDnaute Barbatruc
... la.. je t'avoue que tu viens de me dire un gros mot 😂 voire.. du chinois :-D

je ne vois pas du tout comment ca se traduirait dans mon exemple du bouton "Non modal"
que faudrait il déclarer exactement? et quel serait l'évènement permettant au userform appelant de savoir que le userform appelé a terminé son travail.
(ce qui.. j'ai l'impression.. revient à comprendre comment les formulaire "Modal" fonctionnent pour se donner la main.. et la reprendre...)

est ce que ca ne reviendrait pas à remplacer dans le formulaire appelant le code "userform2.show " par userform2.show(0) ???
 

patricktoulon

XLDnaute Barbatruc
bonsoir
en modal tu pourrais utiliser ton usf2 en mode responsif
j'en fait la demo dans mon calendrier
tu peux aussi mapper les events de feuille dont tu a besoins dans ton userform modal tu aurais ainsi accès aux feuille
on fait généralement cela avec public get property ou une fonction public dans le userform2 qui sera une reponse pour le usf1
c'est assez simple a mettre en place
 

Dranreb

XLDnaute Barbatruc
Les noms d'évènement obéissent aux même règles que les noms de variables et de procédures.
C'est vrai, ça peut aussi servir: un Worksheet peut aussi être déclaré avec l'attribut WithEvents dans un UserForm et du coup tous ses évènement Worksheet peuvent y être pris en charge.
 

vgendron

XLDnaute Barbatruc
@Dranreb
après reflexion et relecture.. ce que je comprend
à partir du userform2, je peux appeler le userform1_activate, ou userform1.bouton_click...
il me semble l'avoir déjà mis quelque part dans tout mon code..
en déclarant mon userform comme tu l'as indiqué, ca me permettrait de définir mes propres évènements..
pourquoi pas un "userform1_CONTINU"
et dans cet evènement je met le code qui agit selon ce qui a été modifié par mon userform2...
je pressens que ca va me faire pas mal de code à déplacer.... je vais encore réfléchir un peu.. :-D.. mais peut etre pas aujourd'hui..

@patricktoulon
je n'ai pas trouvé ton calendrier.. juste le "Collection fausse boite de dialogue" : je pense pas que ce soit celui dont tu parles, puisque lorsque le calendrier est affiché, la feuille excel est inaccessible...
mais c'est vrai que mettre tout le monde en modal.. je peux m'affranchir des "Me.hide",.show et le code se déroule comme je le souhaite..et QUAND je le souhaite..
 

patricktoulon

XLDnaute Barbatruc
re
non pour l'acces au feuille tu ne peut le faire en mode modal je viens de tester
mais ca change rien l'event peut etre mappé

pour la tamporisation d'une eventuelle macro dans usf1 ce que je t'ai dis ne change pas
de même qu'en variabilisant ce dont tu a besoins tu peux communiquer des données d'un userform à l'autre même en modal
les variables devront être public bien sur
 

patricktoulon

XLDnaute Barbatruc
si je reprend l'exemple de @Dranreb que j'ai oublié de saluer (mille excuses) avec un textbox par exemple
variabiliser l'object textbox en public le rend accessible par le userform fils ou tout autre endroit du classeur
 

Pièces jointes

  • exemple avec variable public.xlsm
    23.5 KB · Affichages: 11

vgendron

XLDnaute Barbatruc
Hello

Je reviens avec mes userforms...
en fait, je pense avoir deux soucis:
1) celui exposé plus haut avec le code qui n'est pas interrompu==> finalement, ca ne concerne que 2 ou 3 formulaires sur les 70 présents dans l'appli... pour l'instant,.. je vais laisser ce pb de coté..


2) c'est la navigation entre les formulaires (tous en NON modal)
Comme vous le voyez dans l'exemple ci joint, j'ai un formulaire de base "Root" point de départ de mon appli
ce formulaire peut appeler 2 parents
et chaque parent peut appeler deux enfants (les memes pour les deux parents)
donc, Child1 et Child2 peuvent etre appelés par Parent1 ou Parent2.

quand un userform est appelé, il a donc besoin de savoir QUI l'a appelé pour pouvoir le rappeler.
j'ai donc utilisé la propriété "tag" de chaque formulaire ==> ainsi, je garde l'historique des ouvertures.

ex:
Chaine d'ouverture:
Root==>Parent1 (tag=root) ==> Child2 (tag=Parent1)

Chaine de fermeture pour revenir au root:
Avant de fermer Child2==> il rappelle le formulaire dont le nom est dans son Tag: Parent1
Parent 1 peut donc etre fermé à son tour et rappeler Root (enfin.. c'est ce que je pensais.....)
Parent 1 ne sait plus qui l'a appelé

pour la chaine d'ouverture, j'utilise le processus
Appelé.tag=me.name ==> je met le nom de l'appelant dans le tag de l'appelé
me.hide ==>je masque l'appelant ==> Normalement; il n'est PAS déchargé
Appelé.show ==>l'appelé n'est pas encore chargé==> donc ca passe par le "appelé_initialize" puis activate

à chaque étape, je vérifie que le tag est correct (bouton "Lire tag")

c'est au retour que ca ne fonctionne pas...
pour la chaine de fermeture, j'utilise le processus
1: Appelant.show => normalement l'appelant n'a PAS été déchargé==> pourtant, ca repasse par l'initialize (du coup.. le tag a été réinitialisé ==> l'appelant ne connait plus son propre appelant....
2: appelé.unload ==> décharge complète du formulaire

Je ne comprend pas comment tout cela fonctionne.....
Pourquoi la méthode SHOW entraine-t-elle un réinitialize d'un formulaire qui n'a pas été déchargé ??
 

Pièces jointes

  • Test Formulaire Modal.xlsm
    34.7 KB · Affichages: 14

Discussions similaires

Statistiques des forums

Discussions
312 146
Messages
2 085 764
Membres
102 967
dernier inscrit
Syl34