XL 2019 utilsation d'un userform dans plusieurs fichiers

vmatthieu

XLDnaute Occasionnel
bonjour à tous,
j'utilisais un fichier avec une macro sous excel 2003 (oui ça existe encore) qui me permetait d'ouvrir un userform et d'utiliser celui çi sur n'importe quels autres fichiers excel ouverts( grace à la propriété modal false).

je suis maintenant sous windows 11 sous office 2019 , la propriété modal reste bien en false mais quand je change de fichier excel, l'userform disparait. Il n'est utlisable qu'avec le classeur dans lequel il est. Du coup je suis marron.

l'un de vous sait t'il comment on peut procéder pour que (comme avant) une fois l'userform ouvert, il reste utilisable sur n'importe quel autre fichier excel ouvert?

merci d'avance
bonne journée
 

herve62

XLDnaute Barbatruc
Supporter XLD
Bonsoir
Là il ma semble qu'il y a un blême ?
Car MS a toujours fait en sorte que tout ce qui est antérieur fonctionne normalement , j'ai du VBA de 2000 avec USF qui fonctionne toujours ( la version Windows n'a rien à voir avec Office)
En plus là je pige pas bien ta problématique ?? comme :
qui me permetait d'ouvrir un userform et d'utiliser celui çi sur n'importe quels autres fichiers excel ouverts
faudrait apporter du concret car je n'ai jamais vu un USF inter actif sur d'autres fichiers ?? mis à part l'extraction ou le report de données en arrière plan en précisant bien celui-ci
 

Dranreb

XLDnaute Barbatruc
Bonsoir.
Non, j'ai aussi eu le même problème un beau jour. Et je n'ai rien trouvé à y faire : quand on active un autre classeur l'UserForm disparaît. J'avais bien trouvé un moyen de faire en sorte qu'il reste au moins affiché
VB:
Private Declare PtrSafe Function GetForegroundWindow Lib "user32" () As Long
Private Declare PtrSafe Function SetWindowPos Lib "user32" (ByVal hWnd As Long, ByVal hWndInsertAfter As Long, _
   ByVal X As Long, ByVal Y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long
…
Private Sub UserForm_Activate()
   SetWindowPos GetForegroundWindow, -1, 0, 0, 0, 0, 3: End Sub
Mais ça ne résout rien car dès qu'on le sollicite il réactive le classeur qui était actif au moment du Show. On n'arrive plus à avoir un UserForm non modal indépendant de tout classeur. En tout cas je n'ai jamais trouvé comment le faire comme c'était possible sur les anciennes versions de Windows.
Ça rend d'ailleurs paitiquement inutilisable une Private WithEvents AppXL As Application pour réagir aux activations de classeurs etc. au niveau application.
 
Dernière édition:

herve62

XLDnaute Barbatruc
Supporter XLD
Bonsoir Bernard
Bizarre ?? , tu as la même configuration W11 et Office 2019 pour comparer ??
Tu sais très bien que l'OS n'a rien a voir avec le soft !! ? donc cela ne peut provenir que de Office
Enfin je ne vois pas bien vos fichiers tarabiscoté qui arrivent à laisser un Usf ouvert permettant de travailler avec des autres ???????????
 

job75

XLDnaute Barbatruc
Bonsoir vmatthieu, herve62, Bernard,

C'est un très bon problème, je n'avais pas remarqué que les choses avaient changé sur Excel 2019.

Pour y remédier voyez le fichier joint avec ce code dans Module1 :
VB:
Public ouvert As Boolean 'mémorise la variable

Sub USF()
UserForm1.Show 0 'non modal
End Sub
Dans l'UserForm : :
VB:
Private Sub UserForm_Initialize()
ouvert = True
End Sub

Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
ouvert = False
End Sub
Et dans ThisWorkbook :
VB:
Private Sub Workbook_Deactivate()
If ouvert Then Unload UserForm1: USF 'ferme et rouvre l'UserForm
End Sub
A+
 

Pièces jointes

  • UserForm(1).xlsm
    19.5 KB · Affichages: 19

Dranreb

XLDnaute Barbatruc
Ben non, je ne vais pas décharger mon UserForm si je vient d'y copier la couleur d'un pixel d'un autre classeur quelconque … Mais même si j'ai lancé le Show (par un classeur de macros) alors que je venais de voir que ma couleur était dans ce classeur lambda, je ne veux pas qu'il disparaisse quand je reviens dans celui où je veux la mettre.
 

job75

XLDnaute Barbatruc
Si l'on veut que l'UserForm soit constamment ouvert on peut utiliser l'artillerie lourde, voyez ce fichier (2).

Dans ThisWorkbook :
VB:
Private Sub Workbook_Open()
Application.OnTime 1, "Affiche"
End Sub

Private Sub Workbook_BeforeClose(Cancel As Boolean)
On Error Resume Next
Application.OnTime t, "Affiche", , False
End Sub
Dans Module1 :
VB:
Public fichier$, t 'mémorise les variables

Private Sub Affiche()
If ActiveWorkbook.Name <> fichier Then
    fichier = ActiveWorkbook.Name
    Unload UserForm1
    UserForm1.Show 0 'non modal
End If
t = Now + 1 / 86400
Application.OnTime t, "Affiche"
End Sub
 

Pièces jointes

  • UserForm(2).xlsm
    20.4 KB · Affichages: 9

Dranreb

XLDnaute Barbatruc
Non, on ne voudrait pas qu'ils soit toujours constament ouvert, on voudrait seulement que son comportement soit toujours complètement indépendants des activations et désactivations de classeurs, surtout qu'il est affiché par un projet vba indépendant, celui d'un xlam, non visible. Pourquoi diable ont-ils subitment rendu ça complètement impossible ? Moi je crois que c'est un bogue, qu'ils ne se sont pas rendu compte qu'en affichant un UserForm ils conduisaient Windows à le considérer comme une fenêtre fille de la fenêtre du classeur actif au lieu d'une fenêtre indépendante ou au moins liée seulement à toute l'application. Ça va être impossible de leur faire corriger ça, à mon avis …
 
Dernière édition:

Dranreb

XLDnaute Barbatruc
Haha ! Je crois bien que j'ai trouvé quelque chose d'intéressant en ajoutant cette API :
VB:
Private Declare PtrSafe Function SetWindowLong Lib "user32" Alias "SetWindowLongA" _
   (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Et :
VB:
Private Sub UserForm_Activate()
   SetWindowPos GetForegroundWindow, -1, 0, 0, 0, 0, 3 ' Pour le forcer à rester affiché.
   SetWindowLong GetForegroundWindow, -8, 0 ' Pour le rendre indépendant de toute autre fenêtre.
   End Sub
Avec ça, non seulement l'UserForm ne disparaît plus mais il apparaît même dans la barre des tâches !
Ce n'était pas vraiment voulu mais je préfère qu'il dépende de la barre des tâche que de quoi que ce soit d'autre !
Je répète toutes les API impliquées :
VB:
Private Declare PtrSafe Function GetForegroundWindow Lib "user32" () As Long
Private Declare PtrSafe Function SetWindowPos Lib "user32" (ByVal hWnd As Long, ByVal hWndInsertAfter As Long, _
   ByVal X As Long, ByVal Y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long
Private Declare PtrSafe Function SetWindowLong Lib "user32" Alias "SetWindowLongA" _
   (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
 
Dernière édition:

vmatthieu

XLDnaute Occasionnel
Haha ! Je crois bien que j'ai trouvé quelque chose d'intéressant en ajoutant cette API :
VB:
Private Declare PtrSafe Function SetWindowLong Lib "user32" Alias "SetWindowLongA" _
   (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Et :
VB:
Private Sub UserForm_Activate()
   SetWindowPos GetForegroundWindow, -1, 0, 0, 0, 0, 3 ' Pour le forcer à rester affiché.
   SetWindowLong GetForegroundWindow, -8, 0 ' Pour le rendre indépendant de toute autre fenêtre.
   End Sub
Avec ça, non seulement l'UserForm ne disparaît plus mais il apparaît même dans la barre des tâches !
Ce n'était pas vraiment voulu mais je préfère qu'il dépende de la barre des tâche que de quoi que ce soit d'autre !
Je répète toutes les API impliquées :
VB:
Private Declare PtrSafe Function GetForegroundWindow Lib "user32" () As Long
Private Declare PtrSafe Function SetWindowPos Lib "user32" (ByVal hWnd As Long, ByVal hWndInsertAfter As Long, _
   ByVal X As Long, ByVal Y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long
Private Declare PtrSafe Function SetWindowLong Lib "user32" Alias "SetWindowLongA" _
   (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
merci à tous pour vos commentaires et plus particulièrement à Danreb qui a bien compris ma problématique.

j'essaye maintenant d'exploiter ton code mais avec bien du mal (je n'ai pas le niveau malheureusement)

pour le private sub userform activate, ok je sais ou le rentrer, par contre pour
VB:
Private Declare PtrSafe Function SetWindowLong Lib "user32" Alias "SetWindowLongA" _
   (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
on le mets dnas un module ou ailleurs ?

et pour tous le reste

VB:
Private Declare PtrSafe Function GetForegroundWindow Lib "user32" () As Long
Private Declare PtrSafe Function SetWindowPos Lib "user32" (ByVal hWnd As Long, ByVal hWndInsertAfter As Long, _
   ByVal X As Long, ByVal Y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long
Private Declare PtrSafe Function SetWindowLong Lib "user32" Alias "SetWindowLongA" _
   (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long

dans un module aussi ou ailleurs? (parce que pour l'instant tout bug , mais je répète je n'ai pas le niveau ...
merci d'avance
bonne journée
 

vmatthieu

XLDnaute Occasionnel
ok merci, par contre j'ai ce vilain message d'erreur, et je ne comprends pas le pourquoi, si je peux abuser de ta bonté .... :)
1640514210757.png
 

Discussions similaires

Statistiques des forums

Discussions
312 201
Messages
2 086 174
Membres
103 152
dernier inscrit
Karibu