Ceci est une page optimisée pour les mobiles. Cliquez sur ce texte pour afficher la vraie page.

XL 2016 VBA - Lister les UserForms du Projet VBA

Dudu2

XLDnaute Barbatruc
Bonjour,

Je n'obtiens aucun résultat avec ce code:
VB:
Sub a()
    Dim Usf As Object
    Dim k As Integer
    
    For Each Usf In VBA.UserForms
        k = k + 1
        MsgBox k & " " & Usf.Name
    Next Usf
End Sub
Auriez-vous une solution ?
Merci par avance.
 

Pièces jointes

  • Classeur1.xlsm
    24.3 KB · Affichages: 4

Dudu2

XLDnaute Barbatruc
Certes, la cohérence fonctionnelle.
Je me suis fait piéger avec ça et j'ai ramé 3+ heures avant de comprendre.

Il faut savoir que:
- si tu fais un UserFormX.Visible il exécute UserForm_Initialize.
- si tu enchaînes avec un UserFormX.Show il passe directement à UserForm_Activate sans passer par UserForm_Initialize. (Normal vu ce qui a été dit).

Et donc si pour préparer le UserFormX.Show tu initialises des variables globales (par exemple) en pensant qu'elles seront valorisées par UserForm_Initialize, t'as gagné si t'as pas fait de UserFormX.Visible avant et t'as perdu sinon. Ça je trouve que c'est trop "fin" comme critère de jeu.

Et moi, j'avais perdu (3 heures au bas mot sans compter cette discussion instructive).
Donc perso, plus jamais le UserForm_Initialize dans des applis complexes.
 
Dernière édition:

Dranreb

XLDnaute Barbatruc
Si, on peut rarement se passer du UserForm_Initialize. Il faut juste savoir qu'il n'est exécuté qu'une fois pour toutes lorsqu'on le mentionne pour quelle que raison que ce soit et pas nécessairement lors d'un Show.
C'est vrai, je n'aurais vraiment pas dû laisser entendre que c'était pour préparer un Show.
J'ai même dans un coin un UserForm qui a pour vocation de ne pas être affiché.
L'UserForm_Initialize n'est plus exécuté non plus si la dernière fermeture s'est faite par Me.Hide et non par Unload Me.
 

patricktoulon

XLDnaute Barbatruc
voici un exemple d'utilisation du initialise de l'userform
alors oui c'est un peu tordu comme démo mais il fallait bien ca pour te montrer l'utilité du initialise
et surtout te montrer jusqu'a quel points quand on maitrise l'event on peut aller plus loin

alors il faut partir du module standard pour comprendre
tout d'abords je crée une new instance "exemplaire" de l'userform
je ne le show pas rien du tout

mon userform je l'ai appelé "menu"

donc dans un module standard
VB:
Dim u As menu
Sub test()
menu.Umodal = 0
Set u = New menu
End Sub
dans le initialise du userform menu
VB:
Private Sub UserForm_Initialize()
    Set RnG = ActiveSheet.[B3:B10,F5:F8]
Set feuille = RnG.Parent
End Sub

j'ai bien évidemment creéé l'event pour feuille entête de module userform
Code:
'*******************************************************
'Démo userform associé a une plage d'une feuille avec event feuille géré dans le MODULE Userform
' patricktoulon
'date:15/06/2021
'*******************************************************

Public WithEvents feuille As Worksheet
Public Umodal As Boolean
Private Sub feuille_BeforeRightClick(ByVal Target As Range, Cancel As Boolean)
    If Not Intersect(RnG, Target) Is Nothing Then
        menu.StartUpPosition = 0
        placementRange menu, ActiveCell
        menu.Show menu.Umodal: Cancel = True
    Else
        Cancel = False
    Unload menu
    End If
End Sub


' ne fonctionne qu'en mode non moadl
Private Sub feuille_SelectionChange(ByVal Target As Range)
 If Intersect(RnG, Target) Is Nothing Then Unload menu
End Sub

j'ai ajouter ma fonction de placement sur range (c'est pas la dernière versions mais bon on fera avec

voila j'ai donc un userform "menu" et je lance la sub test du module standard précedement cité
tu va me dire ben ca fait rien on vois pas le userform rien ne se passe

ben click droite sur les plages non contiguë initiées dans le initialise
surprise surprise

je te l'accorde j'ai poussé un peu
cet exemple tu le retrouve ici
 

Pièces jointes

  • exemple pour dudu2 2.xlsm
    19.9 KB · Affichages: 2

Dudu2

XLDnaute Barbatruc
De toutes façons, ne t'inquiète pas, j'ai parfaitement compris de quoi il s'agissait sur tous les points abordés. Et surtout, j'en ai tiré les leçons pour construire du code qui évite ces écueils.
 

Dudu2

XLDnaute Barbatruc
A savoir, pour le lecteur de passage et pour (ma) mémoire (défaillante ):
  • UserForm_Initialize() n'est pas une initialisation applicative pour l'affichage d'un UserForm.
    C'est une initialisation "de classe" qui définit des éléments utiles à l'existence du UserForm.
    Dans le cas d'une utilisation classique / standard d'un UserForm, il n'y a RIEN à y placer.

  • Le UserForm_Initialize() peut être déclenché par une référence à une propriété du UserFrom (ex UserFormX.Visible, UserFormX.Name, UserFormX.Caption, etc...), un Load UserFormX , un Unload UserFormX si pas déjà loadé, et bien sûr par UserFormX.Show.

    Et surtout UNIQUEMENT s'il n'a pas déjà été exécuté auparavant par l'une ou l'autre de ces mêmes actions (sauf le Unload).

  • L'utiliser comme une initialisation applicative du UserFormX.Show est potentiellement dangereux.
    En effet, si un UserFormX.Visible (par exemple) précède un UserFormX.Show, le UserForm_Initialize exéctué sur le UserFormX.Visible ne le sera pas/plus sur le UserFormX.Show et des variables globales qui y seraient valorisées lors du UserFormX.Visible sont potentiellement candidates à modification avant le UserFormX.Show.

  • Une initialisation applicative pour l'affichage d'un UserForm n'est sûre que si elle est codée dans le UserForm_Activate selon une méthode du type de celle du Post #25.

  • Pour tester si un UserForm est visible ou pas, en évitant le chargement et l'initialisation de celui-ci, utiliser une fonction du type de celle du Post #18.
 
Dernière édition:

patricktoulon

XLDnaute Barbatruc
a ce que je vois et à te lire tu commence a comprendre la notion de module classe/userform

l'initialisation de variable (enfant de classe(userform) doivent être forcement public ))

les variable peuvent être modifiée dans des fonction codée dans le module userform
attention cependant (et je le dis pour l'avoir testé)
quand on se sert d'un module userform comme classe et!! userform
toute les variables doivent être préfixées par le parent en terme clair c'est à dire le nom du userform

cela est nécessaire quand on crée plusieurs instance
à moins que l'on désire que la variable ai une valeur propre à chacune des instances

alors il est vrai que j'ai pu constater sur certaines version 2016 que ce n’était plus la peine de préfixer

Attention aussi au mot "Me" qui représente le parent (l'userform) aussi bien dans un module userform qu'un autre module classe d'ailleurs
en effet dans le userform (et c'est la ou le bas blesse ) vba va declencher une erreur car me il ne connait pas dans les fonctions codées dans le userform
démonstration largement faite dans mon calendrier et toute les dialog perso que j'ai pu distribuer

conclusion
il est vrai que l'peut se perdre dans ce principe sachant que dans un meme module on code l'applicatif du userform et on code aussi un module classe
faire le yoyo entre les deux peut être déconcertant
ne pas oublier de préfixer explicitement en dur c'est tout

a savoir
imaginons une fonction codé en classe dans le userform qui appellerait éventuellement une autre fonction ou sub d'ailleurs
deja
elles sont public
et là le prefixage des variable est obligatoire SURTOUT SUR 2007
même si ces même sub ou fonctions peuvent être appeler par un bouton par exemple (donc par l'applicatif)

pour la simple et bonne raison que
une sub ou fonction de classe appellera toujours la version de la fonction de la même classe

pour bien comprendre ce principe il suffit d'imaginer une photocopieuse copiant x exemples du module
chaque copie a ses fonctions propres

je fait une demo si c'est pas comprit
 
Dernière édition:

patricktoulon

XLDnaute Barbatruc
re
ben tu peux te la faire pour la prochaine fois en exportant la cle modifier ce qu'il y a apres le "=" a la fin en mettant tout simplement "-"
et en effet c'est 7.1 même pour moi c'est parce que je l'avais fait avec 2013 classique et maintenant j'ai 2013 pro plus

bonne livraison
 

Discussions similaires

Réponses
4
Affichages
439
Les cookies sont requis pour utiliser ce site. Vous devez les accepter pour continuer à utiliser le site. En savoir plus…