XL 2016 VBA - Comment savoir dans le code d'un UserForm s'il a été ouvert en vbModal ou vbModeless ?

Dudu2

XLDnaute Barbatruc
Bonjour,

La question est dans le titre.

Merci pour toute indication.

Bonne journée.
 
Dernière édition:
Solution
Tu as mis le doigt sur quelque chose d'inattendu !
Si Obj est un Frame TypeOf Obj Is UserForm = True !!!

Je trouve cela très étrange et je ne sais pas si cela fait sens mais je dirais que c'est un bug car le TypeOf Frame existe bel et bien.

Le bon code est donc:
VB:
'-------------------------------------
'Mode d'affichage du UserForm
'
'- Obj est soit un Control du UserForm
'          soit un UserForm
'
'- Return: vbModal (1)
'          vbModeless (0)
'          Erreur (-1)
'-------------------------------------
Function UserFormShowMode(ByVal Obj As Object) As Integer
    On Error Resume Next
    
    'Cherche l'objet au sommet de la hiérarchie
    Do While Err.Number = 0
        Set Obj =...

patricktoulon

XLDnaute Barbatruc
STOP!! STOP !! STOP!!!
bon alors je t’arrête tout de suite
je viens de tester et le résultat est bien erroné comme je le pensais
j'ai testé pour le doute (mais je le savais déjà)
je met le userform en non modal
1628405680463.png


comme tu vois la frame2 est enfant de frame1

je fait un test simple
VB:
Private Sub CommandButton1_Click()
MsgBox UserFormShowMode(Frame2)
MsgBox UserFormShowMode(Frame1)
MsgBox UserFormShowMode(Me)
End Sub

je lance
demo7.gif


voila comme tu peux le voir seul le msgbox avec "Me" donne un résultat vrai les autres sont erronés

faire attention avec les frames si tu doit travailler avec la fonction .parent et certaines autres ;)

c'est bien pour ca que sur certaines version ou config que quand on fait par exemple textbox1="toto" et que le textbox est enfant d'une frame ca marche et des fois ca ne marche pas il faut faire frame1.textbox1="toto"
 

patricktoulon

XLDnaute Barbatruc
re
oui après tests et retest c'est définitivement pas bon
je pense même que typeof déraille un peu et comme il n'y a pas de gestion d'erreur en amont sur cette fonction le principe de "-1" des le départ n'est pas bon

c'est pas pour rien que j'ai galéré hier avec cette gestion d'erreur et que j'ai préféré utiliser typename(obj)
 

patricktoulon

XLDnaute Barbatruc
re
oui oui c'est bien le post 14 que j'ai testé (celui qui est pointé comme solution )
et non ça ne fonctionne pas j'ai "1" a tout les coups que l'usf soit modal ou pas
c'est ce que je disais plus haut selon les versions ou config ( je sais pas je n'ai jamais réussi a identifier le problème) l’accès frame est différent

ma version est un peu plus compliquée mais elle va jusqu'au bout du principe
mais de toute maniere ,les deux ont un soucis
typeof ; bon ça tu l'a vu
et typename; a des soucis quand l'userform porte un autre nom que celui d'origine à la création dans VBE
ben c'est pas gagné 🤣 🤣
 

patricktoulon

XLDnaute Barbatruc
ok typeof plante sur un multipage ou alors c'est le or frame qui arrete avant la fin et donc exit la function

comme tu peux le voir il n'est pas listé le multipage
1628419846164.png


maintenant la meme avec typename
1628419965783.png


et là on voit bien le problème de typename avec un userform qui porte un autre nom que "Userform" & x on voit bien que la boucle s'arrete apres la 2d relance du userform car il n'y a plus de parent
si je debug le err.number on voit clairement le problème
1628420603251.png


je viens de tester sur 2007 et c'est pareil donc ta version ne fonctionne que sur 2016 et plus peut être
 
Dernière édition:

Dudu2

XLDnaute Barbatruc
Tu t'amuses à prendre le code en défaut en ajoutant des objets Page... sans le préciser explicitement !
Tu devrais dire, si un objet Page est dans la hiérarchie ça ne marche pas et la solution est ... au lieu de tourner autour du pot.
 

patricktoulon

XLDnaute Barbatruc
a ben ouii je met des controls et oui un multipage
il ne faut pas s’arrêter a des frames ou userform sinon le code est pas complet ou non efficient a 100%
de toute façon même sans multipage avec ton code ça s’arrête a la frame et me sort 1 alors que je suis en vbmodeless
ça c'est du a la gestion des fenêtre 2016 "MDI"
les version 2007 | 2010/2013 | 2016 ont une gestion différente des fenêtres
et j'ai une autre idéee bien plus simple encore mais je vais tester d'abords
 

patricktoulon

XLDnaute Barbatruc
tiens que pense tu de ça
VB:
Sub testNonModal()
    TOTOUSF.Show 0
End Sub
Sub testModal()
    TOTOUSF.Show
End Sub
Sub test_avec_un_control_du_userform()    'le meme test est efectué au click sur le bouton dans le userform  en modal
    MsgBox UserFormShowMode(UserForm1.CommandButton1)
End Sub



Function UserFormShowMode(ByVal Obj As Object) As Integer
    Dim errNum&, I&, previousOBJ As Object

    'Init Return Value
    Do While errNum = 0
        On Error Resume Next
        Set previousOBJ = Obj: Set Obj = Obj.Parent
        errNum = Err.Number
        Debug.Print "previous object " & previousOBJ.Name & " - object parent " & Obj.Name & "  error : " & Err.Number
        Err.Clear
    Loop
    MsgBox TypeOf previousOBJ Is UserForm
    MsgBox TypeOf Obj Is UserForm
End Function
 

patricktoulon

XLDnaute Barbatruc
Bon ben voila là ca fonctionne partout
le principe est simple finalement
la boucle plante quand il n'y a plus de parent
on memorise l'obj et le parent a chaque tours
on laisse filer et des que l'on est a l'erreur(438) obj = le précédent obj (variable previousOBJ)
la ligne debug.print démontre bien le principe et le raisonnement
et là il n'y a plus de doute on a bien l'userform
voir les tests dans le userform dans tous les sens
VB:
Sub testNonModal()
    TOTOUSF.Show 0
End Sub
Sub testModal()
    TOTOUSF.Show
End Sub
Sub test_avec_un_control_du_userform()    'le meme test est efectué au click sur le bouton dans le userform  en modal
    MsgBox UserFormShowMode(UserForm1.CommandButton1)
End Sub

Function UserFormShowMode(ByVal Obj As Object) As Integer
    Dim errNum&, I&, previousOBJ
    Do While errNum = 0
        On Error Resume Next
        Set previousOBJ = Obj: Set Obj = Obj.Parent
        errNum = Err.Number
        Debug.Print "previous object " & previousOBJ.Name & " - object parent " & Obj.Name & "  error : " & Err.Number
        If Err.Number > 0 Then Set Obj = previousOBJ: Err.Clear: Exit Do
        Err.Clear
    Loop
    Obj.Show 0 'on tente le show vbmodeless
   
    If Err.Number = 0 Then UserFormShowMode = 0 Else UserFormShowMode = 1
    On Error GoTo 0
End Function

le fichier sur le quel je test en piece jointe
mille excuse on se croise je vien de voir un new message je regarde ton fichier
 

Pièces jointes

  • dudu2 usf modal ou pas v PAT testé sur 2007 et 2013 .xlsm
    21.1 KB · Affichages: 3

Discussions similaires

Statistiques des forums

Discussions
312 206
Messages
2 086 222
Membres
103 158
dernier inscrit
laufin