XL 2016 affichage userform avec 2 ou + ecrans

roby

XLDnaute Occasionnel
Bonjour le forum,

Lorsqu'on lance un fichier Excel sur un poste avec plusieurs écrans, à chaque fois les userform s'affichent sur un autre écran que l'écran ou est affiché excel.
y a-t-il une parade pour que cet userform s'affiche dans la même fenêtre que excel ?

je joint le même fichier solutionné dernièrement pour le test.

Merci encore.
 

Pièces jointes

  • Roby1.xlsm
    19.8 KB · Affichages: 16

Dudu2

XLDnaute Barbatruc
mais pourquoi une tel usine à gaz
Une usine à gaz ?! Et c'est toi qui me dit ça ! J'aime beaucoup tes retours positifs.
Moi ça me semble structuré, modularisé et d'une grande simplicité de lecture et surtout d'utilisation.
Mais si tu trouves que c'est une usine à gaz, je vais tenter de fournir l'Allemagne après l'attentat du Nord Stream
1666109456723.gif
.

Si tu veux, je te commente ton code dans le fichier que tu m'as envoyé ?
Non, je ne fais pas ça, je prends ce qui est bien et je l'utilise pour moi.
 

patricktoulon

XLDnaute Barbatruc
ben en lecture non je suis désolé c'est pas si simple
et c'est le brouilon public que je t'ai donné pas la version finale
mais tu peux commenter ça me dérange pas je sais que ma méthode fonctionne all version excel
je t'ai dis que ça marche c'est l'essentiel non

bon nous reste un problème de taille à régler
a savoir

le pane de l'oleobject ou shapes cliqué sans qu'il soit précisé
j'ai bien mis une solution au point mais elle ne me plait pas car elle utilise une autre api
déjà que je me sert de la dwmapi.dll a mon grand regret je ne veux pas l'alourdir
si tu a des idées là oui je suis preneur
comme tu peux le voir dans cette capture je suis obligé de selectionner une cellule dans la pane pour que le placement se fasse dans la bonne panne au click sur object
demo sans areo.gif
 

Dudu2

XLDnaute Barbatruc
A partir du moment où il faut une API pour la fonction du DWM, ça ne me dérange plus d'en ajouter autant que nécessaire, y compris pour les Pixel To Point qui sont plus précises comme ça. Car j'ai remarqué que la méthode sans API génère des décimales variables (certes peu significatives) avec les changements de Zoom.

Pour le positionnement sur une Shape, tu peux t'inspirer de ma fonction ObjectPane() qui détermine le Pane d'un objet, que ce soit une cellule, une Shape ou autre. Car comme le dit la fonction de positionnement PositionUserFormSurObjetFeuille(), tu peux désigner un objet de feuille quelconque.
Démo avec ce fichier.
ObjectPane() fait partie de l'usine à gaz
1666113093416.gif
😂
 

Pièces jointes

  • VBA Positionnement UserForm sur Objet d'une feuille.xlsm
    52.5 KB · Affichages: 1

patricktoulon

XLDnaute Barbatruc
veux tu que je t'explique pourquoi sur certains point tu fait une usine à gaz
par exemple j'ai vu que tu utilise la m'éthode que l'on a élaboré avec rolland_M il y a 3 ans avec les splitrow et splitcolumn etc...... alors que la chose est beau........coup plus simple
si tu en a envie je te l'explique
 

Dudu2

XLDnaute Barbatruc
Je pense que tu fais référence à cette séquence:
VB:
        With ActiveWindow
            If .SplitRow = 0 Then
                PosRow = 1
            Else
                If Rng.Row <= .SplitRow Then PosRow = 2 Else PosRow = 3
            End If
        
            If .SplitColumn = 0 Then
                PosColumn = 1
            Else
                If Rng.Column <= .SplitColumn Then PosColumn = 4 Else PosColumn = 5
            End If

            Select Case PosRow * PosColumn
                Case 1, 2, 4, 8
                    Set Pan = .Panes(1)
                Case 3, 5, 10
                    Set Pan = .Panes(2)
                Case 12
                    Set Pan = .Panes(3)
                Case 15
                    Set Pan = .Panes(4)
            End Select
        End With
Si tu as une méthode plus simple pour déterminer le Pane de l'objet, alors envoie.
De toutes façons, ces SplitRow et SplitColumn ne constituent pas un aberration de programmation. Enfin de mon point de vue.
 

Dudu2

XLDnaute Barbatruc
Tu cherches toujours un truc à critiquer dans les moindre recoins. Soit plus positif !
A lieu de critiquer, propose quelque chose de mieux en disant "au lieu de faire ça, tu pourrais faire ceci".

Sinon j'attends ta méthode non-usine-à-gaz pour déterminer le Pane de l'Object.
 

Dudu2

XLDnaute Barbatruc
Autre chose...
j'ai vu que tu utilise la m'éthode que l'on a élaboré avec rolland_M il y a 3 ans avec les splitrow et splitcolumn
Je n'ai rien pompé du tout sur Dupond ou Durant ou toi ou Rolland pour faire ce code de détermination du Pane de l'Objet. Je suis assez grand pour l'avoir fait tout seul. Quand je pompe quelque chose j'en mets la référence.
Faut arrêter de pense que tout vient de toi. Tu as l'égo d'un informaticien qui sort de l'école.
 

patricktoulon

XLDnaute Barbatruc
je ne critique pas quand je critique je suis plus virulent

alors je propose de tester ce fichier vite fait comme ça et tu pourra constater que je ne compte pas les splitrow ou splitcolumn * l'un ou l'autre comme dans ton model d'ailleurs il n'y a même pas d'expression numeriques dans le code

tout simplement parce qu'il y a que!!! dans une feuille avec figés que activepane donne la dernière panes libre au lieu de l'activepane
dans tout les autres fractionné et normal activepane donne la bonne


parti de là si tu veux developper une petite fonction
la position en point de la cellule sera
leleft = ((LABONNEPANE . PointsToScreenPixelsX(Int(Cell.Left)) / PtsToPxX)) * ZoomX 'left en point
letop= = ((LABONNEPANE . PointsToScreenPixelsY(Int(Cell.Top)) / PtsToPxX)) * ZoomX 'top en point


ZoomX étant le zoom/100
PtsToPxX etant le coeff de conversion points to pixel

APRÈS POUR TES CONVERSION TU PEUX UTILISER LES API SI TU VEUX
mais entre nous chez moi ta méthode ou la mienne même défaut de rien du tout a peine chiffrable et encore même en zoom 200 je vois pas la différence

je t'expliquerais apres pourquoi (avec une demo visuelle plus que parlante ) on ne peut faire de l'exact avec excel

et j'ai pas dis que tu avais pompé j'ai dis que tu utilisais la même méthode
 
Dernière édition:

Dudu2

XLDnaute Barbatruc
C'est ça ta méthode ?
VB:
Function getpane(cell As Range)
    With ActiveWindow
        If .FreezePanes = True Then
            For i = 1 To .Panes.Count
                If Not Intersect(cell, .Panes(i).VisibleRange) Is Nothing Then getpane = .Panes(i).Index
            Next
        Else
            getpane = .ActivePane.Index
        End If
    End With
End Function

Si c'est ça je vois pas ce que vient faire ni le test If .FreezePanes = True Then (car freezé ou pas les Panes sont là) et encore moins le Else qui suppose que la cellule concernée est dans le Pane actif, ce qui est non-sens.
De plus tu ne travailles qu'avec le Panes(i).VisibleRange qui est un sous ensemble du Pane affiché à l'instant T.
Ton code ne me convient absolument pas !

Au final on ne va pas commencer à passer en revue chacune de mes séquences de code et les tiennes en prime. Tu codes comme tu veux, j'en m'en inspire pour ce qui me convient et je laisse le reste sans en faire des tartines de commentaires négatifs.
Fais pareil avec moi.
 
Dernière édition:

Dudu2

XLDnaute Barbatruc
Cher @patricktoulon, ton aide m'est précieuse et tu m'as sorti de l'embarras plus d'une fois.
Grâce à toi (et d'autres experts du Forum aussi) j'ai pu faire des choses que je n'aurais pu faire seul.
Et en l'occurrence, sur ce sujet, sans ta référence à la fonction du DWM, jamais je n'aurais pu écrire un code qui fonctionne. Et je te remercie pour toutes les solutions que tu m'as apportées et que tu m'apporteras encore.

Mais il faut que tu me laisse coder comme je l'entends et c'est pas grave si c'est pas comme tu le fais.
Et si tu as des suggestions d'amélioration, pas de problème, je prends !
 

patricktoulon

XLDnaute Barbatruc
re
@TooFatBoy disons que l'on est 4 (me semble t il) 3 jusqu'au bout qui avons sorti une fonction qui fonctionne certes comme je l'ai dis indirectement il y avait pas mal d'inutilité comme cell que j'ai cité précédemment

@Dudu2 c'est pas ta facon de coder quoi que je m'y perds mais bon chacun son truc
je veux juste te dire qu'il y a beaucoup d'inutilité
et si je me permet de te le dire c'est par ce que d'une part
  1. même si on est pas d'accords on s'entend bien sur plusieurs projet et ça me fait avancer moi aussi
  2. je te connais suffisamment rigoureux maintenant pour aller plus loins qu'un étalage de code qui somme toute requiert quand même certaines connaissances (c'est pas à la portée de tous )

et pour te prouver a quel points la chose est simplissime
voici le fichier que je t'ai donné tout a l'heure avec une fonction de position ultra allégé pour l'exemple
reste a rajouter ma fonction ecart ou la tienne comme tu veux avec l'api dwmapi.dll
et faire la fonction Ppx avec tes api ou garder ma méthode comme tu veux

regarde a quel point il faut pas grand chose
tu a le principe de base
et ça fonctionne sur toute les circonstances (freezpane figé,fractionnés )

regarde en tout est pour tout la fonction de position
et je t'ai fait ça en 2/2 tellement la logique est simple
VB:
'**********************************************************************
'patricktoulon
'demonstration du principe ULTRA SIMPLIFIE
'tu peux faire la foncion << Ppx >> avec les api si tu veux
'RESTE PLUS QU'A RAJOUTER MA FONCTION << ECART >> AVEC L API DWMAPI.DLL

Function PpX()
'ma méthode
' With ActiveWindow.Panes(1): PpX = (.PointsToScreenPixelsX(72) - .PointsToScreenPixelsX(0)) / 72: End With
'ou
'la methode api 'blablabla....
'ou
'pour l'exemple vite fait comme  ça ,on l'ecrit en dur
    PpX = 1.33333333333333
End Function


Function getposition(cell As Range)
    Dim PaN As Pane, ZoomX#, i, G#, D#
    With ActiveWindow
        If .FreezePanes = True Then
            For i = 1 To .Panes.Count
                If Not Intersect(cell, .Panes(i).VisibleRange) Is Nothing Then Set PaN = .Panes(i)
            Next
        Else
            Set PaN = .ActivePane
        End If
        ZoomX = .Zoom / 100
        G = (PaN.PointsToScreenPixelsX(cell.Left) / PpX) * ZoomX
        D = (PaN.PointsToScreenPixelsY(cell.Top) / PpX) * ZoomX
    End With
    getposition = Array(G, D)
End Function

'ET C'EST TOUT

et dans les feuilles
VB:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    Dim pos
    pos = getposition(Target)
    With UserForm1
        .StartUpPosition = 0
        .Left = pos(0): .Top = pos(1)
        .Show 0
    End With
End Sub
 
Dernière édition:

Discussions similaires

Réponses
2
Affichages
440

Statistiques des forums

Discussions
312 504
Messages
2 089 082
Membres
104 023
dernier inscrit
zerarka mohamed