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

XL 2016 VBA - Exact Visible Range

Dudu2

XLDnaute Barbatruc
Bonjour,

VBA nous donne un Window.VisibleRange qui inclut les dernières colonne et ligne pas forcément complètement visibles.
C'est souvent handicapant quand on veut avoir un Window.ExactVisibleRange qui exclut les parties non visibles des dernières colonne et ligne.

J'ai dû faire un code sans trop d'API pour tenter de définir cet ExactVisibleRange mais hélas, j'ai aussi dû utiliser des constantes qui semblent valides chez moi. Mais le sont-elles chez vous ?
VB:
Const VerticalScrollBarBordersPixels As Long = 2 * 2.5    'Borders around the Vertical Scroll Bar
Const HorizontalScrollBarBordersPixels As Long = 2 * 4    'Borders around the Horizontal Scroll Bar
Const StatusBarHeightPixels = 26

Merci par avance de tester ce code pour vérifier qu'en toutes configurations de fenêtre (maximisée et réduite), la Shape Rectangle s'affiche bien aux limites basses de la partie visible.
Si ce n'est pas le cas, un petit screenshot et des infos sur la version Window et Office (versions et bits)



Fichier: voir plus loin
 
Dernière édition:

Dudu2

XLDnaute Barbatruc
Bonjour (je repost suite à introduction du DisplayScale)

Nouvelle journée de quête du Graal de l'Exact Visible Range.
J'ai tout essayé, mais je ne tire rien des UsableWidth/Height. Chez moi ça ne donne rien.
Avec des corrections de 28 et 22 (100%) 36 et 26 (125%) pixels qui ne sont pas identifiable.


Le mieux que j'arrive à faire c'est ça (à essayer chez vous):
Code:
With ActiveWindow
    Set Shape = ActiveSheet.Shapes.AddShape(msoShapeRectangle, _
                                            .VisibleRange.Left + CXDLGFRAME - 2 * CXBORDER, _
                                            .VisibleRange.Top + CYDLGFRAME - 2 * CYBORDER, _
                                            .Width - (.Width - .UsableWidth) - 27.4 * DisplayScale * PixelToPoint, _
                                            .Height - (.Height - .UsableHeight) - 21.2 * DisplayScale * PixelToPoint)
End With

En plus, je sais maintenant ce qui diffère entre nos configurations.
J'ai une mise à l'échelle à 125% et vous êtres à 100%.
Pour coller à vos configs, il faut que je me mette à 100%
La mise à l'échelle à 125% peut introduire des petites distorsions de l'ordre de 1 à 2 pixels c'est pourquoi je dois travailler à 100% pour le positionnement.

D'ailleurs j'ai une question...
Ce chiffre de 96 (dpi ou je ne sais quoi), il vient d'où ? Y a-t-il une constante pour le décrire ?
 

Pièces jointes

  • Usable.xlsm
    27.7 KB · Affichages: 1
Dernière édition:

TooFatBoy

XLDnaute Barbatruc
Ce chiffre de 96 (dpi ou je ne sais quoi), il vient d'où ? Y a-t-il une constante pour le décrire ?
Oui, là ce sont bien des dpi, ou plus exactement des "ppi" (pixels per inch).

Je pense que ce 96 vient du fait qu'autrefois tous les moniteurs avaient des tubes catholiques avec la même résolution, et qu'en utilisant cette valeur les caractères avaient la bonne taille (ni trop gros ni trop petits) pour une bonne lisibilité.
 

TooFatBoy

XLDnaute Barbatruc
J'aimerais bien trouver en VBA une constante ou une méthode pour le récupérer, mais nada !
Trouver cette constante, je ne sais pas si c'est possible. Mais une méthode l'est probablement.

Par exemple tu récupères les "dpi" actuels de ton affichage selon Microsoft, tu récupères le facteur de zoom du Bureau, et tu fais une règle de trois.


Mais, pour moi, actuellement c'est une valeur qui sert de base à tous les calculs et est donc immuable. Du coup tu peux utiliser ce 96 sans aller le chercher dans le système d'exploitation.
 
Dernière édition:

patricktoulon

XLDnaute Barbatruc
re
et oui mais @Dudu2 fonctionne avec les drivers génerique de MS pour son graphique
ce qui fait que si il change la résolution en modifiant la taille par exemple il change le dpi simulé
tandis que nous visiblement qui fonctionnons avec des drivers signés WHQL
que nous zoomons windows ou pas on reste avec un dpi de 96
soit pour pixel 4/3 ce qui est immuable
je le sais j'ai fonctionné comme ça pendant des années avec win 7 jusqu'au jour ou j'ai découvert le poteau rose

je viens de lire dans une une page web en cherchant dpi et vba
(si je traduit bien)
que selon la puissance de la carte graphique la simulation bloqué à 96 soit dpifactor 100 sera impossible
ça explique bien pourquoi quand j'ai changé ma carte graphique j'ai pu le faire alors que pendant des années j’étais en 125% soit dpifactor 120 pour pouvoir avoir une taille suffisante pour une lisibilité aisée

@Dudu2 a tu essayé mon fichier ?
 

Dudu2

XLDnaute Barbatruc
tu es sérieux @Dudu2?
msgbox GetDpiForwindow(application.hwnd)
Oui je suis sérieux, enfin il me semble. Et je ne crois pas à la responsabilité des drivers, sinon ce serait le chaos total.

Cette fonction GetDpiForwindow me rend 96 quand je suis en échelle d'affichage 100% et 120 quand je suis en échelle d'affichage 125%, ce qui est normal puisque ce sont les points par inch de l'affichage que l'échelle d'affichage modifie (120/96 = 1.25).

Elle me permet donc de calculer ce que j'ai appelé le DisplayScale: (l'échelle de l'affichage)
VB:
Function DisplayScale() As Double
    With Application
        DisplayScale = GetDpiForWindow(.hwnd) / 96
    End With
End Function

Donc j'ai toujours 96 dans le calcul et rien pour remplacer cette valeur en dur, ce qui me plait moyennement.
 

TooFatBoy

XLDnaute Barbatruc
Donc j'ai toujours 96 dans le calcul et rien pour remplacer cette valeur en dur, ce qui me plait moyennement.
Logiquement il devrait effectivement y avoir une constante dans Windows qui te donnerait ce 96.

Mais tant qu'on ne saura pas où elle est il te faudra, soit utiliser ce 96 qui est actuellement immuable, soit faire la règle de trois dont je parle plus haut.
 

Dudu2

XLDnaute Barbatruc
@patricktoulon,
Avec ton code chez moi tu n'es pas très loin.
Juste les .Left et .Top, c'est plutôt 1 pixel / 0.75 points (la taille des BORDER = 1 pixel).

Et pour l'ajustement Width & Height j'ai dû retiré des points
VB:
With ActiveSheet.Shapes("jaune")
        .Top = 0.75
        .Left = 0.75
        If .width <= 200 Then
            .width = dims.width - IIf(ActiveWindow.DisplayVerticalScrollBar, 5, 4)
            .height = dims.height - IIf(ActiveWindow.DisplayHorizontalScrollBar, 5, 10)
        Else

De mon coté, je retire toujours les éléments 1 à 1 et je cherche toujours une solution qui semble s'approcher mais ...
 

patricktoulon

XLDnaute Barbatruc
re
cette fonction devrait te donner dpifactor
VB:
Sub test()
    MsgBox DpiFactor
End Sub

Function DpiFactor()
    Dim ItP&, ImmuAble#, PtoPx#
    ItP = Application.InchesToPoints(1)
    ImmuAble = 4 / 3
    With ActiveWindow.Panes(1)
        PtoPx = (.PointsToScreenPixelsX(ItP * (.Parent.Zoom / 100)) - .PointsToScreenPixelsX(0)) / ItP
    End With
    DpiFactor = PtoPx / ImmuAble
End Function
 

Dudu2

XLDnaute Barbatruc
Bon, voilà comment j'ai travaillé.
1 - Je suis passé en échelle d'affichage 100% pour avoir la même config que vous.
2 - J'ai viré les ScrollBars H & V et la Status Bar et les Headings pour n'avoir aucun perturbateur en hauteur et largeur
3 - J'ai cadré au mieux la Shape sur la feuille sans perturbateurs (à ce stade c'est la base du cadrage)
4 - J'ai ajouté progressivement les ScrollBars H & V, la Status Bar et les Headings en vérifiant le cadrage à chaque étape

Dans l'affaire il me reste quand même ces constantes qui peuvent ne pas être correctes dans toutes les configs mais je n'ai le choix:
VB:
Const VerticalScrollBarBordersPixels As Long = 2 * 2.5    'Borders around the Vertical Scroll Bar
Const HorizontalScrollBarBordersPixels As Long = 2 * 5    'Borders around the Horizontal Scroll Bar
Const StatusBarHeightPixels = 22

@TooFatBoy et @patricktoulon, merci d'essayer chez vous, si ce n'est pour du "fine tuning", ce sera la dernière expérience et on restera sur un échec. Ce qui n'est pas dans nos habitudes !
 

Pièces jointes

  • ExactVisibleRangeSize.xlsm
    55.8 KB · Affichages: 3

patricktoulon

XLDnaute Barbatruc
re
toujours pareil en mode maximisé sans les displays, tu est trop large de 10 points a peu près
tu avais de meilleurs résultats quelques versions en arrière

après j'ai peu être trouvé une autre solution je peaufine
 
Les cookies sont requis pour utiliser ce site. Vous devez les accepter pour continuer à utiliser le site. En savoir plus…