XL 2016 VBA - Réduire la largeur de la grille Excel

  • Initiateur de la discussion Initiateur de la discussion Dudu2
  • Date de début Date de début

Boostez vos compétences Excel avec notre communauté !

Rejoignez Excel Downloads, le rendez-vous des passionnés où l'entraide fait la force. Apprenez, échangez, progressez – et tout ça gratuitement ! 👉 Inscrivez-vous maintenant !

Dudu2

XLDnaute Barbatruc
Bonjour,

DataSnipper est un outil commercial ajoutant à Excel des fonctionnalités diverses.
Parmi ces fonctionnalités, la possibilité de visualiser des documents PDF directement dans Excel avec cette particularité (voir image ci-dessous) que la fenêtre Excel est divisée en 2 verticalement. La partie gauche contient la grille Excel, la partie droite contient probablement un Control ActiveX visualisateur PDF, je ne sais pas lequel ? Acrobat ? PDF-XChange Viewer ? Autre ?

La question est: comment est-il possible dans une fenêtre Excel de réduire la largeur de la grille Excel et ses ascenseurs comme le fait ce logiciel ?

1758617247578.png
 
@nullosse, en effet c'est une approche possible qui converge vers la méthode que j'utilise consistant à détecter les nouvelles fenêtres.
Mais attention, comme je l'ai constaté avec ma méthode, une nouvelle fenêtre n'est peut-être pas la bonne car il peut y en avoir une pour le lancement et une finale. Alors avec UIA c'est peut-être différent.

Cette méthode (ainsi que celle que j'utilise) a l'inconvénient d'exiger que le lancement du document créé une nouvelle fenêtre.
Si un Browser (ou autre application) est paramétré pour ouvrir un nouvel onglet et pas une nouvelle fenêtre, on ne trouvera pas de nouvelle fenêtre.

Si l'API GetWindowText() ne rend pas toujours le nom du fichier, et plutôt même rarement, une piste serait Window.Caption ?
Par contre je ne sais pas définir un objet Window à partir de son Handle. A part tout balayer.
c'est exactement ce que je fait avec ma fonction getwindowhandle
je parcours les fille du bureau
bisrépetita
au plus simple tu la transforme en listing
tu lance ton app pour le volet
tu re liste est l'intru c'est la bonne
pas compliqué
cela dit c'est prendre un chemin plus long
alors qu'avec ta version de la fonction findwindowpartTitle par exemple ,si tu gère correctement les timming tu verra que le texte tu l'a
Si l'API GetWindowText() ne rend pas toujours le nom du fichier, et plutôt même rarement, une piste serait Window.Caption ?
Par contre je ne sais pas définir un objet Window à partir de son Handle. A part tout balayer.
et pour définir un window par un handle ,il me semble qu' il i a
VB:
Private Declare PtrSafe Function AccessibleObjectFromWindow Lib "oleacc" ( _
    ByVal hWnd As LongPtr, _
    ByVal dwId As Long, _
    riid As Any, _
    ppvObject As Object) As Long
normalement cet api te renvoie une object window voir dans l'utilisation que j'en fait l'object application
autrement dit par exemple tu peux obtenir l'object application dans le cas de word
et au lieu de t'epoumonner a chercher a closer une window avec l'objet obtenu tu fait un ".Quit"


et pour info quand tu dis que le windowtext ne renvoie rien c'est juste ou mauvaise gestion du timming
car chez moi sur 2013 32 et 2016 64 j'ai bien la classe et le text '
avec bloknot , pdfx_changeviewer , word , edge ,firefox , chrome , notepad ++ , acrobat reader et j'en passe

je te fait une démo ce soir quand je rentre si tu veux
 
Ok pour la démo de la Window par son Handle.
C'est pas la 1ère fois que je suis confronté à cette question et même si ce n'est pas nécessaire dans mon dernier fichier, j'aimerais bien l'avoir en réserve. En fait je voulais tester le Window.Caption au lieu du GetWindowText() mais je suis pas sûr que la propriété .Caption passera.
 
re
bon j'ai pris 5 minutes pour tester
et j'avais raison à 100%
quand on fait setparent l'applicationword a un userform et que l'on setparent le userform a XLDESK on a plus de problème pour reprendre le focus car le userform est non modal donc je te donne dans le mille apres la mise en place le volet est une partie a part entière de la fenêtre excel
et en plus comme je fait je ferme avec ".QUIT" pas besoins de handle
et voila pas de boucle de machin et de truc chouette
VB:
Sub OuvrirWorddefaut2()
    Dim fichier, AppHandle As LongPtr, N$, used As Boolean
    If TaskPaneUsed Then MsgBox " le volet est deja utilisé" & vbCrLf & "Vous devez fermer le volet actuel": Exit Sub
    
    fichier = Application.GetOpenFilename("pdf Files (*.doc*), *.doc*", 1, "ouvrir un fichier")
    If fichier = "Faux" Then Exit Sub
    Set wordxapp = CreateObject("word.application")
    With wordxapp
        .Visible = True
        .documents.Open fichier
    End With
    N = Split(Mid(fichier, InStrRev(fichier, "\") + 1), ".")(0)
    AppHandle = GetWinHandle("OpusApp", N, 10)
    If [D1] = "Vrai" Then SetWindowLong AppHandle, -16, &H16000000
    'docking AppHandle
    Dim AppForm As LongPtr
    If TaskPaneUsed Then MsgBox " le volet est deja utilisé" & vbCrLf & "Vous devez fermer le volet actuel": Exit Sub
    Set usf = plaque
    With usf
        .Show 0
    End With
    AppForm = GetActiveWindow
    If [D1] = "Vrai" Then SetWindowLong AppHandle, -16, &H16000000 'checkbox on vire la caption
    wordxapp.left = 0
    wordxapp.top = 0
    
    SetParent AppHandle, AppForm
    docking AppForm
End Sub


Vous voulez une demo video rapide ?
Pour afficher ce contenu, nous aurons besoin de votre consentement pour définir des cookies tiers.
Pour plus d'informations, consultez notre page sur les cookies.
 
Ok vu.
Vous voulez une demo video rapide ?
9 minutes quand même !😋
J'avais bien compris l'encapsulation de Word dans un UserForm, mais merci pour la démo.

Ton approche est différente de celle de @nullosse et @Dudu2 sur 2 critères principaux:
- N'a pas de bouton de fermeture. La fermeture du "volet" c'est la fermeture du document ouvert.
- Lance un document sans préjuger de l'application. C'est l'application par défaut qui s'ouvre. Les boutons sont juste là pour filtrer la sélection de fichier, ça marche aussi bien avec le bouton générique.
 
- Lance un document sans préjuger de l'application. C'est l'application par défaut qui s'ouvre. Les boutons sont juste là pour filtrer la sélection de fichier, ça marche aussi bien avec le bouton générique.
je sais vraiment pas et comprends encore moins ce que tu raconte

mon bouton pdf defaut lance le pdf avec l'app par defaut et je gère parfaitement bien les classes qui en découle
pour le fun j'ai même installé Chrome aussi
du coup j'ai testé les pdf par defaut avec
  1. chrome
  2. FF
  3. pdf _Xchangeviewer
  4. adobe reader(tous!!!!!!!de la version 9 à celle d'aujourd'hui en DC)
  5. Notepad++
  6. bullzip pdf(celui que j'utilise en temps normal )

bref ça fait pas mal déjà pour un pdf viewer

pour le csv , txt , cmd , bat , vbs et tout les fichiers que l'on ouvre avec bloknote
je les ouvre avec Notepad et Notepad++

et tous tous tous!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! SANS EXEPTION !!!!!
je capte la classe et AU MOINS LE NOM SANS EXTENSION(et plus pour certaines app)
du coup il n'y a pas a s'ennuyer

voici mon bouton pdf par defaut
VB:
Sub OuvrirPDFdefaut()
    Dim AppHandle As LongPtr
    Dim Hnewparent As LongPtr
    Dim He7 As LongPtr
    Dim fichier$
    Dim appPdfDefaut As PdfAppInfo, used As Boolean
    If TaskPaneUsed Then MsgBox " le volet est deja utilisé" & vbCrLf & "Vous devez fermer le volet actuel": Exit Sub
    
    fichier = Application.GetOpenFilename("pdf Files (*.pdf), *.pdf", 1, "ouvrir un fichier")
    If fichier = "Faux" Then Exit Sub
    
    appPdfDefaut = GetPdfDefaultExe 'recherche du chemin de l'exe de l'application par défaut avec ma fonction magic
    
    Select Case appPdfDefaut.ExeName
            'on fait une exeption pour edge et chrome on passe en shell cmd pour ouvrir en << new window  >>
            'comme ca on evite d'avoir plusieurs onglets dans la fenêtre chrome ou edge ou FF
        Case "msedge.exe", "chrome.exe", "firefox.exe"
            Dim pdfURL$, t
            pdfURL = "file:///" & Replace(fichier, "\", "/") ' Format de l'URL pour Edge
         Shell "cmd /c start """ & """" & " " & Replace(appPdfDefaut.ExeName, ".exe", "") & " --new-window """ & pdfURL & """", vbHide
  Case Else: ShellExecute 0, "open", fichier, "", "", 1 ' SW_SHOWNORMAL
    End Select
    
    'on garde que le nom du fichier sans l'extension
    N = Split(Mid(fichier, InStrRev(fichier, "\") + 1), ".")(0)
    
    Select Case appPdfDefaut.ExeName
        Case "Acrobat.exe": AppHandle = GetWinHandle("AcrobatSDIWindow", N, 10)
        Case "PDFXCview.exe": AppHandle = GetWinHandle("DSUI:PDFXCViewer", , 10)
        Case "msedge.exe", "chrome.exe": AppHandle = GetWinHandle("Chrome_WidgetWin_1", N, 10)
        Case "firefox.exe": AppHandle = GetWinHandle("MozillaWindowClass", N, 10)
        Case Else: AppHandle = GetWinHandle("*", N, 10)
    End Select
    If [D1] = "Vrai" Then SetWindowLong AppHandle, -16, &H16000000
    docking AppHandle
End Sub
je n'ai aucun raté à la capture de la classe et du texte avec ma fonction GetWinHandle

et pour la fermeture de mon Volet QUEL QU IL SOIT !!!
VB:
'Cette fonction ferme les fenêtres intégrées dans Excel qui ont une certaine classe
'elle Restaure la largeur la fenêtre de classe "EXCEL7 dans la fenêtre Excel
Sub Fermeture_du_volet_Ouvert()
    'patricktoulon:exercice (docked work pane)
    Dim t, i&, hwnd As LongPtr
    ActiveCell.Select
    'j'ouvre word avec un object application
    'donc je le ferme directe si il existe  et le select case ensuite fermera le userform le contenant par la classe ThunderDFrame pour  la version ouvrirworddefaut2
    If Not wordxapp Is Nothing Then wordxapp.Quit
    t = AllPartExcelWindowList 'liste des composantes prrésente dans excel
    For i = 2 To UBound(t)
        Select Case True
            Case CStr(t(i, 2)) = "ThunderDFrame": hwnd = CLngPtr(t(i, 1)): Unload usf: Exit For
            Case CStr(t(i, 2)) = "Notepad": hwnd = CLngPtr(t(i, 1)): Exit For
            Case CStr(t(i, 2)) Like "Chrome_WidgetWin*": hwnd = CLngPtr(t(i, 1)): Exit For
            Case CStr(t(i, 2)) Like "MozillaWindowClass*": hwnd = CLngPtr(t(i, 1)): Exit For
            Case CStr(t(i, 2)) = "AcrobatSDIWindow": hwnd = CLngPtr(t(i, 1)): Exit For
            Case CStr(t(i, 2)) Like "*Acrobat*": hwnd = CLngPtr(t(i, 1)): Exit For
            Case CStr(t(i, 2)) = "Notepad++": hwnd = CLngPtr(t(i, 1)): Exit For
            Case CStr(t(i, 2)) = "DSUI:PDFXCViewer": hwnd = CLngPtr(t(i, 1)): Exit For
            Case CStr(t(i, 2)) = "OpusApp": hwnd = CLngPtr(t(i, 1)):
                If Not wordxapp Is Nothing Then wordxapp.Quit
                Exit For
                
        End Select
    Next
    If hwnd <> 0 Then
        Call PostMessage(hwnd, &H10, 0, 0)
    Else
        MsgBox "Il n'y a pas de volet en cours d'affichage", vbInformation: Exit Sub
    End If
    'Vx = False
    DoEvents
    splitViewRestaure
    Set wordxapp = Nothing
End Sub
et je n'ai pas d'orphelin que je retrouve dans la liste des composantes excel (apres avoir fermé le volet) comme j'ai avec absolument tout tes fichiers et qui génèrent aléatoirement des erreurs grave puisque c'est la fermeture brutale peut être qu'avec 2013 32 j'y suis plus sensible

et maintenant que j'ai trouvé l'astuce du userform HOSt ça va devenir encore plus simple
 
Bonjour la liste,
Une micro-modif du fichier du Post #165 qui est la 1ère solution, pour n'avoir aucune spécificité au niveau de l'appel de la fonction d'ouverture du fichier et rester 100% générique.
La 2ème solution étant celle de @patricktoulon dont j'attends le fichier (plutôt que des bouts de code épars et des GIF animés) pour la référencer en solution.
 
Dernière édition:
Bonjour @Dudu2 je crois que tu n'a pas compris sur quoi je travaille
pour t'en montrer le contenu
je reprends ton fichier j'ajoute le listing des composantes d'excel
alors:
ouvre le fichier et dans cet ordre
  1. lance le bouton liste(composantes) --> ca va te créer une feuille avec la listes des composantes d'ecel
  2. lance un de tes boutons pour docker un document
  3. ferme ce document
  4. relance la liste(composantes)
et regarde tout ce qui reste en plus de la première fois
chez moi je passe de 36 handle à 54
en ayant essayé le bouton pdf
 

Pièces jointes

D'abord ton code de liste des Handle n'est pas correct.
Il fonctionne la 1ère fois, et les fois suivantes de la même session, il retourne des trucs des fois d'avant parce que ta table Static n'est pas initialisée à l'appel. Voilà comment corriger tes initialisations:
VB:
    If hWnd = 0 Then
        hWnd = Application.hWnd
        i = 0
        Static TbL(1 To 100, 1 To 9) As Variant
        Dim ti As Integer
        Dim tj As Integer
        For ti = 1 To UBound(TbL, 1)
            For tj = 1 To UBound(TbL, 2)
                TbL(ti, tj) = Empty
            Next tj
        Next ti
    End If

Une fois ton code corrigé, on voit qu'il y a des Handles Excel en plus lors de l'affichage du document dont la Parent est XLDESK, normal.
Et une fois le document fermé ces Handles disparaissent et on obtient le même nombre de Handles qu'avant l'affichage.

De toutes façons, quand bien même il y aurait des Handles résiduels (ce qui n'est pas le cas), c'est l'affaire d'Excel non ? C'est pas moi qui vais faire son ménage. Tant qu'ils ne sont pas dans ma valise EsayJet, je ne paie pas de supplément.
 
re
oui peut être une erreur pour le static mais c'est pas ça je viens de découvrir pourquoi
en fait dans ton exemple tu ferme le document par la croix donc pas de problème
mais moi j'ai un bouton pour fermer qui envoie le sendmessage hwnd, commande,constante close
sauf que oui ca ferme bien la fenêtre mais pas tout les procc surtout sur pdf_X_changeviewer
j'ai tout essayé
detroywindow
commande destroy
commande close la souple et la dure
boucle et comparatif sur un tableau avant et apres close des handle orphelin(rien y fait)

obligé de fermer par la croix
ce qui veux dire que le mode postit (sans barre de titre )on oublie
je bataille depui plus de 4 heures a chercher une autre solution
autrement dit la commande close ou close dure ne fait pas la même chose que ce que la croix à la main fait
si je règle ce soucis j'ai fini
en tout cas avec le userform host je n'ai pas de soucis de focus
punaise y a pas un truc qui existe non de dieu !!

et au fait non ta correction n'est pas bonne
quand je lance un appel je lance sans hwnd maitre donc a chaque appels par macro je réinit le T
il n'y a que les appels recursif intra fonction qui envoie un hwnd parent a chaque tours
regarde plus près tu a failli me faire faire une bêtise

d'ailleurs lance la 10 fois 100 fois tu aura le même nombre

VB:
sub test

dim T

for i= 1 to 10

T=AllPartExcelWindowList

debug.print ubound(T) &" handle trouvés"

next

end sub
 
Dernière édition:
quand on fait setparent l'applicationword a un userform et que l'on setparent le userform a XLDESK on a plus de problème pour reprendre le focus car le userform est non modal donc je te donne dans le mille apres la mise en place le volet est une partie a part entière de la fenêtre excel
Salut,
j'ai mis la fenêtre word dans un userform. J'arrive bien à prendre le focus et écrire dans la partie texte mais le souci c'est quand je clique sur le menu Fichier, ça fait planter Word . Le seul moyen que j'ai trouvé pour éviter cela serait de masquer complétement le ruban de word (avec les onglets menu). Cela peut se faire à l'aide d'un modèle .dotm dans lequel on a mis cela pour le ruban :
XML:
<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui">
  <ribbon startFromScratch="true"/>
</customUI>
(je sais que patricktoulon sait le faire avec son outil magique)
En suite lorsqu'on ouvre un document il faut attacher dynamiquement ce modèle exemple :
Code:
Sub OuvrirAvecModeleSansRuban()
    Dim wdApp As Object
    Dim wdDoc As Object
  
    Set wdApp = CreateObject("Word.Application")
    Set wdDoc = wdApp.Documents.Open("C:\chemin\MonDocument.docm")
  
    ' Attache le modèle qui supprime le ruban
    wdDoc.AttachedTemplate = "C:\chemin\ModeSansRuban.dotm"
  
    wdApp.Visible = True
End Sub

Je n'ai pas testé.

Nullosse
 
Bonsoir @nullosse,
J'arrive bien à prendre le focus et écrire dans la partie texte mais le souci c'est quand je clique sur le menu Fichier, ça fait planter Word
Tu le confirmes mais je m'en doutais un peu et j'attendais le fichier de @patricktoulon pour le vérifier qui semble avoir la main dans ce cas.
Après, s'il faut faire bidouiller pour masquer le ruban Word, ça limite les actions réalisables sur Word.

@patricktoulon, tu as essaye d'envoyer un Alt + F4 en Sendkeys après avoir mis la fenêtre du document en 1er plan ?
 
@Dudu2
ben elle l'est déjà au premier plan la fenêtre de n'importe quel document
setwindowsPos(hwnd,-1,left,top,width,heigth,falg=0)
je n'ai pas le soucis que vous avez (peut être une question de version)
mais en vrai ça n'a aucune importance puisque c'est la seule child du userform host (plaque)
 

Pièces jointes

- Navigue sans publicité
- Accède à Cléa, notre assistante IA experte Excel... et pas que...
- Profite de fonctionnalités exclusives
Ton soutien permet à Excel Downloads de rester 100% gratuit et de continuer à rassembler les passionnés d'Excel.
Je deviens Supporter XLD

Discussions similaires

Réponses
9
Affichages
929
Réponses
0
Affichages
2 K
Retour