XL 2016 VBA - Mais dans quel Pane est l'objet ?

Dudu2

XLDnaute Barbatruc
Bonjour,

Petit souci avec les Panes (in the ass en l'occurrence).
Les fonctions PointsToPixelsX (et Y) donnent un résultat qui dépend du Pane de l'objet considéré, car le Pane peut être décalé en Scroll horizontal et vertical.

Dans la fonction du ObjectPane du fichier attaché, on ne peut tester que le Pane.VisibleRange. Il n'existe pas d'autre propriété de l'objet Pane exploitable !

De sorte que si l'objet dont on recherche le Pane (pour avoir un PointsToPixelsX correct) n'est visible dans aucun des Panes, on ne peut pas le localiser !!

Existe-t-il un alternative ?
Merci par avance.
 

Pièces jointes

  • Classeur1.xlsm
    19.1 KB · Affichages: 2
Solution
Bonsoir.
À défaut de trouver un Range dans le VisibleRange d'un des Pane de la collection Panes, vous pouvez toujours vous rabattre sur ActiveWindow.ActivePane, surtout pour ActiveCell: c'est généralement le bon.
Mais à quoi ça peut servir d'autre que positionner un UserForm ? Et si c'est bien ça et si la plage où vous voulez le positionner n'est visible nulle part, il vaudrait mieux renoncer à le repositionner sinon il risquerait de plus être visible non plus, il me semble …

Pour information observez les instructions du Else du If TypeOf Obj Is MSForms.Control de cette méthode de mon UFmCalend :
VB:
Public Sub Posit(ByVal Obj As Object, Optional ByVal X As Double, Optional ByVal Y As Double)
Rem. ——— Méthode. Vous pouvez au préalable...

Dranreb

XLDnaute Barbatruc
Bonsoir.
À défaut de trouver un Range dans le VisibleRange d'un des Pane de la collection Panes, vous pouvez toujours vous rabattre sur ActiveWindow.ActivePane, surtout pour ActiveCell: c'est généralement le bon.
Mais à quoi ça peut servir d'autre que positionner un UserForm ? Et si c'est bien ça et si la plage où vous voulez le positionner n'est visible nulle part, il vaudrait mieux renoncer à le repositionner sinon il risquerait de plus être visible non plus, il me semble …

Pour information observez les instructions du Else du If TypeOf Obj Is MSForms.Control de cette méthode de mon UFmCalend :
VB:
Public Sub Posit(ByVal Obj As Object, Optional ByVal X As Double, Optional ByVal Y As Double)
Rem. ——— Méthode. Vous pouvez au préalable positionner l'UserForm par rapport à quelque chose.
'     Obj: Ce par rapport à quoi vous voulez le positionner. X et Y indiqueront comment :
'     X: -1: Collé au coté gauche, 0: Centré horizontalement, 1: Collé au coté droit.
'     Y: -1: Collé au bord supérieur, 0: Centré verticalement, 1: Collé juste en dessous.
'     Mais si la valeur absolue de X >= 1, Y:=0.9 est une valeur conventionnelle demandant
'        à ce que le bord supérieur du calendrier soit aligné sur celui de Obj.
'     D'autres valeurs entraineront un recouvrement partiel ou un certain éloignement.
'     Mais rien ne vous empêche de rectifier encore ensuite la propriété Left ou Top
'     de l'UFmCalend pour ajouter un interstice en points au bord de l'objet. Mais toujours
'        avant le Show, donc avant utilisation de la méthode Saisie.
'     X et Y sont facultatifs et assumés = 0. Il est donc centré sur l'objet Obj si non précisés.
   Dim Lft As Double, Top As Double, Rgt As Double, Bot As Double, U As Object, UInsWidth As Single, _
      UInsHeight As Single, K As Double, Wnw As Window, P As Long, Pan As Pane, Px72 As Long, Trnq As Long
   If TypeOf Obj Is MSForms.Control Then
      Lft = Obj.Left: Top = Obj.Top: Set U = Obj.Parent ' Normalement UserForm, Frame ou Page.
      Do: UInsWidth = U.InsideWidth: UInsHeight = U.InsideHeight ' Le Multipage n'aura pas de dimensions
         If TypeOf U Is MSForms.Page Then Set U = U.Parent ' intérieures, mais le Page n'avait rien d'autre.
         K = (U.Width - UInsWidth) / 2
         Lft = Lft + U.Left + K
         Top = Top + U.Top + U.Height - K - UInsHeight
         If Not (TypeOf U Is MSForms.Frame Or TypeOf U Is MSForms.MultiPage) Then Exit Do
         Set U = U.Parent: Loop
      Rgt = Lft + Obj.Width: Bot = Top + Obj.Height
   Else
      Set Wnw = ActiveWindow: Set Pan = Wnw.ActivePane
      If Intersect(Pan.VisibleRange, Obj) Is Nothing Then
         For P = 1 To Wnw.Panes.Count: Set Pan = Wnw.Panes(P)
            If Not Intersect(Pan.VisibleRange, Obj) Is Nothing Then Exit For
            Next P
         If P > Wnw.Panes.Count Then Exit Sub ' Abandon si la plage n'est visible nulle part.
         End If
      Px72 = GetDeviceCaps(GetDC(0), 88) ' Nombre de pixels pour 72 points.
      Lft = Obj.Left: Trnq = Int(Lft / 3) * 3
      Lft = Pan.PointsToScreenPixelsX(Trnq) * 72 / Px72 + (Lft - Trnq)
      Px72 = GetDeviceCaps(GetDC(0), 90) ' Nombre de pixels pour 72 points.
      Top = Obj.Top: Trnq = Int(Top / 3) * 3
      Top = Pan.PointsToScreenPixelsY(Trnq) * 72 / Px72 + (Top - Trnq)
      K = Wnw.Zoom / 100: Rgt = Lft + Obj.Width * K: Bot = Top + Obj.Height * K
      End If
   Me.Left = (X * (Rgt - Lft + Me.Width + 6) + Lft + Rgt - Me.Width - 6) / 2 + 3
   If Abs(X) >= 1 And Y = 0.9 Then
      Me.Top = Top
   ElseIf Abs(X) >= 1 And Y = -0.9 Then
      Me.Top = Bot - Me.Height
   Else
      Me.Top = (Y * (Bot - Top + Me.Height + 6) + Top + Bot - Me.Height - 6) / 2 + 3
      End If
   End Sub
Remarque: à tenter peut être si la plage n'est visible nulle part Application.GoTo Rng puis réessayer
 
Dernière édition:

Dudu2

XLDnaute Barbatruc
Bonjour @Dranreb,

En effet, l'ActiveCell est juste ici un exemple d'objet de référence.

Et oui, si l'objet de référence pour placer un UserForm n'est pas visible à l'écran, on peut légitimement se demander si ça vaut la peine, d'autant qu'en Scrollant pour ramener l'objet de référence dans la zone visible, le UserForm ne suivra pas et restera toujours en dehors de la zone visible.

Par contre positionner une TextBox par rapport à une autre peut avoir un sens même si la TexBox de référence est hors zone visible. Elles y seront toutes deux ramenées par un Scroll.

Donc il faut les 2 types de tests:
- L'un pour placer un UserForm en cherchant l'objet de référence dans le .VisibleRange des Panes
- L'autre pour placer un objet de feuille en déterminant le Pane de l'objet de référence (visible ou pas) tout simplement en testant la position de l'objet de référence (ou de sa .TopLeftCell) par rapport à ActiveWindow.SplitColumn et ActiveWindow.SplitRow.

Merci pour ta réponse.
 

Pièces jointes

  • Pane d'un Object de Feuille (Visible ou pas).xlsm
    22.4 KB · Affichages: 0

Membres actuellement en ligne

Aucun membre en ligne actuellement.

Statistiques des forums

Discussions
312 493
Messages
2 088 956
Membres
103 990
dernier inscrit
lamiadebz