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

XL 2019 gestion du presse papier

ESCOUGER2022

XLDnaute Nouveau
Bonjour,
De retour sur ce forum si instructif après quelques années d'interruption!
Je suis en but à un souci concernant l'effacement du presse-papier excel avec excel 2019.
J'ai vu et essayé de nombreuses formules proposées dans ce forum pour effacer le presse-papier, mais malheureusement l'effacement ne s'effectue pas.
J'ai un tableau dans lequel je fais de nombreux copier/ coller ou couper/ coller via des macros VBA. (textes, shapes, pictures...)
Cela fonctionne mais j'ai constaté une dégradation nette du temps de réponse lorsque je travaille longtemps sur ce tableau.
Il arrive même parfois que excel affiche un message m'informant qu'il avait des difficultés avec le presse-papier. (désolé je n'ai pas noté le texte en détail de ce message).
En affichant le presse-papier je constate qu'il ne se vide jamais, et je pense qu'il sature.
Ce que je voudrais serait de vider ce presse-papier (après chacun des "paste" par exemple) ou à des endroits appropriés de mon code.
Mais peut-être n'ai-je pas compris comment fonctionne ce clipboard, ou que je confonde avec le clipboard de windows?
Pour afficher le clipboard je pars du menu accueil, puis clique sur la petite croix "presse-papiers"
Voici ce que j'ai essayé qui n'efface jamais ce presse-papier:

Declare Function OpenClipboard Lib "user32" (ByVal hwnd As Long) As Long
Declare Function EmptyClipboard Lib "user32" () As Long
Declare Function CloseClipboard Lib "user32" () As Long
Public Function ClearPressePapier()
With CreateObject("htmlfile").parentWindow.clipboardData.clearData("Text"): End With
End Function
--------------------------------------------------------------------------------------------------------------

Sub EffacerPressePapier()
' effacer le presse papier de excel
Application.CutCopyMode = False
Application.CutCopyMode = True
End Sub
-----------------------------------------------

Sub EffacerPressePapier1() 'appelé par call EffacerPressePapier1
OpenClipboard 0
EmptyClipboard
CloseClipboard
End Sub

------------------------------------------------
Sub viderPressePapier()
'nécéssite d'activer la référence Microsoft Form 2.0 Object Library? OUI Il EST ACTIF
Dim Cible As DataObject
Set Cible = New DataObject
Cible.SetText ""
Cible.PutInClipboard
Set Cible = Nothing
End Sub
----------------------------------------------------------------------------------------------------------------------------------------
Merci d'avance de vos conseils éclairés
 

ESCOUGER2022

XLDnaute Nouveau
Bonsoir à tous
La seule solution qui fonctionne parfaitement chez moi en excel 2019 est celle de Jurrasik Pork à 8H26.
Je ne suis pas en mesure de tout comprendre de vos échanges, mais suis une fois de plus admiratif de vos connaissances.
Bravo.
Je continuerai de suivre ce cas...pour le plaisir de découvrir vos discussions!
 

jurassic pork

XLDnaute Impliqué
Hello,
comme j'ai vu ceci :
Note The accNavigate method is deprecated and should not be used. Clients should use other methods and properties such as AccessibleChildren, get_accChild, get_accParent, and IEnumVARIANT.
je me suis penché sur une autre façon de naviguer dans les éléments d'interface utilisateur et j'ai vu que l'on pouvait utiliser UIAutomation qui est plus moderne et qui est présent dans les Windows depuis Windows 7.
Cela m'a l'air pas mal et on peut faire beaucoup de choses avec (je suis sûr que cela va plaire à Patricktoulon pour les rubans en particulier).
Comme il n'y a pas beaucoup de codes concernant son utilisation en VBA, en glanant des infos à droite à gauche j'ai fini par trouver comment l'utiliser dans notre cas de figure : "Effacer tout le presse-papiers Office"
Pour l'utiliser en VBA il faut tout d'abord dan Outils/références cocher UIAutomationClient. Si on ne le voit pas il faut faire parcourir et choisir :
Windows\System32\UIAutomationCore.dll pour un Excel 64 bits sur un O.S 64 bits ou pour un Excel 32 bits sur un O.S 32 bits.
Windows\SysWow64\UIAutomationCore.dll pour un Excel 32 bits sur un O.S 64 bits.

Voici un code qui fonctionne chez moi pour effacer le presse-papiers sur un Excel 2016 32 bits :
VB:
Sub ClearPressePapiersOffice3()
    Dim maCmdBar As IAccessible
    Dim oUIA As New CUIAutomation, oUIAelem As IUIAutomationElement, oElem As IUIAutomationElement
    Dim oCondition As IUIAutomationCondition, ipClicBtn As IUIAutomationInvokePattern
    'On Error Resume Next
    Set maCmdBar = Application.CommandBars("Office Clipboard")
    maCmdBar.Visible = True
    DoEvents: DoEvents
    Set oUIAelem = oUIA.ElementFromIAccessible(maCmdBar, 0)
    Set oCondition = oUIA.CreatePropertyCondition(UIAutomationClient.UIA_NamePropertyId, "Effacer tout")
    Set oElem = oUIAelem.FindFirst(TreeScope_Descendants, oCondition) 'chercher l'élément dans les descendants
    Set ipClicBtn = oElem.GetCurrentPattern(UIA_InvokePatternId)
    ipClicBtn.Invoke ' clic sur le bouton
End Sub

Voici un code pour afficher tous les descendants d'un élément :
VB:
Sub AfficherDescendants()
    Dim maCmdBar As IAccessible, bouton As IAccessible
    Dim oUIA As New CUIAutomation, oUIAelem As IUIAutomationElement, i As Integer
    Dim allElem As IUIAutomationElementArray, oCondition As IUIAutomationCondition
    'On Error Resume Next
    Set maCmdBar = Application.CommandBars("Office Clipboard")
    maCmdBar.Visible = True
    Set oUIAelem = oUIA.ElementFromIAccessible(maCmdBar, 0)
    Set oCondition = oUIA.CreateTrueCondition
    Set allElem = oUIAelem.FindAll(TreeScope_Descendants, oCondition)
    For i = 0 To allElem.length - 1
        Set oUIAelem = allElem.GetElement(i)
        Debug.Print oUIAelem.CurrentName & " - " & oUIAelem.CurrentClassName _
                    & " - " & CBool(oUIAelem.CurrentIsEnabled)
    Next i
End Sub

Et voici un code pour afficher les dimensions d'un élément :
VB:
Sub GetDimFenetreExcel()
Dim c As New CUIAutomation, oExcel As IUIAutomationElement, rect As UIAutomationClient.tagRECT
Dim oDesktop As IUIAutomationElement, oCondition As IUIAutomationCondition
Set oCondition = c.CreatePropertyCondition(UIAutomationClient.UIA_ClassNamePropertyId, "XLMAIN")
Set oDesktop = c.GetRootElement
Set oExcel = oDesktop.FindFirst(TreeScope_Children, oCondition)
rect = oExcel.CurrentBoundingRectangle
Debug.Print "top: " & rect.top & " - left: " & rect.left & _
            " - right: " & rect.Right & " - bottom: " & rect.bottom
Debug.Print "width: " & (rect.Right - rect.left) & " - height: " & (rect.bottom - rect.top)
End Sub

Cela n'est qu'une infime partie de ce qu'on peut faire avec UIAutomation mais peut servir comme point de départ.

Ami calmant, J.P
 

patricktoulon

XLDnaute Barbatruc
re
Bonjour @jurassic pork je connais
UIautomationclient est au moins tout aussi vieux que oleacc
je m'en sert pour cliquer sélectionner ,etc.. sur des fenêtres externes a la place des api + des sendkeys bien pourries
d'ailleurs j'avais repris notre exercice pdf to ... sur le quel on avait travailler avec @Dudu2 avec uiautmationClient ce qui est bien plus propre (ha!!! là je vois l'ampoule qui s'allume au dessus de la tête à dudu)

c'est vrai qu'il est puissant mais assez verbeux quand même mais en tout cas efficace
 

Dudu2

XLDnaute Barbatruc
Bonjour à vous,
Oui c'est vrai que ça m'intéresse si ça peut replacer des SendKeys pour cliquer sur des boutons.
Mais je dois avouer que tout ce qui concerne les UIAutomation m'est pour l'instant totalement étranger et que je suis surpris et admiratif que vous arriviez à naviguer dans cet univers.
 

patricktoulon

XLDnaute Barbatruc
@Dudu2 ben en fait c'est vrai que la doc est pauvre c'est pour ça que l'on travaille en early binding (pour l'auto completion dans le VBE ) il est impossible de tout retenir a part les bases
mon premier exercice si je me souviens bien c'est la gestion du blob de téléchargement dans une page web avec IE (ouvrir/enregistrer/annuler) mais ça date j'avais moins de rides

@jurassic porck Ta sub de vidage clipboard marche très bien chez moi
j'ai ajouté le visible false à la fin pour fermer la fenêtres presse-papiers
c'est même un couilla plus rapide qu'avec Iaccessible
 

patricktoulon

XLDnaute Barbatruc
Attention cependant!!
exécuté depuis le vbe il y a des ratés et c'est normal car uiautomationclient doit être exécuté fenêtre accessible
a moins de passer par l'application et descendre javec un treescope jusqu'a la commandbar et don un uiautomation element fromhandle etc .....

il s’éclate le cochon vieux là
 

jurassic pork

XLDnaute Impliqué
Hello,

Patrick je ne crois pas que cela soit possible de faire du Late Binding avec UIAutomation (voir ici
CUiAutomation pas de ProgId et ClsId ne marche pas non plus)
J'ai un peu avancé sur l'utilisation de UiAutomation.
Voici par exemple du code pour afficher les positions par UiAutomation de quelques fenêtres (fenêtre Excel, UserForm, Cellule Excel, Barre des tâches)
VB:
Sub LireInfos()
    Dim oExcel As IUIAutomationElement, rect As UIAutomationClient.tagRECT
    Dim oDesktop As IUIAutomationElement, oCondition As IUIAutomationCondition
    Dim oUIA As New CUIAutomation, oUIAelem As IUIAutomationElement, i As Integer, res
    Dim allElem As IUIAutomationElementArray
    res = res + vbCrLf + "======================= Fenêtre Excel ============================"
    Set oCondition = oUIA.CreatePropertyCondition(UIAutomationClient.UIA_ClassNamePropertyId, "XLMAIN")
    Set oDesktop = oUIA.GetRootElement
    Set oExcel = oDesktop.FindFirst(TreeScope_Children, oCondition)
    res = res + LireInfosElem(oExcel) + vbCrLf
    res = res + vbCrLf + "======================= Cellule A1 ============================"
    Set oCondition = oUIA.CreatePropertyCondition(UIAutomationClient.UIA_NamePropertyId, "A1")
    Set oUIAelem = oExcel.FindFirst(TreeScope_Descendants, oCondition)
    res = res + LireInfosElem(oUIAelem) + vbCrLf
    res = res + vbCrLf + "======================= UserForm1 ============================"
    Set oCondition = oUIA.CreatePropertyCondition(UIAutomationClient.UIA_NamePropertyId, "UserForm1")
    Set oUIAelem = oExcel.FindFirst(TreeScope_Descendants, oCondition)
    res = res + LireInfosElem(oUIAelem) + vbCrLf
    res = res + vbCrLf + "======================= Barre des Tâches ============================"
    Set oCondition = oUIA.CreatePropertyCondition(UIAutomationClient.UIA_ClassNamePropertyId, "Shell_TrayWnd")
    Set oUIAelem = oDesktop.FindFirst(TreeScope_Children, oCondition)
    res = res + LireInfosElem(oUIAelem) + vbCrLf
    UserForm1.TextBox1 = res
End Sub
Function LireInfosElem(Elem As IUIAutomationElement) As String
Dim rect As UIAutomationClient.tagRECT, res As String
rect = Elem.CurrentBoundingRectangle
res = vbCrLf & Elem.CurrentName & " - " & Elem.CurrentClassName & _
                   " -> top: " & rect.top & " - left: " & rect.left & _
                   " - right: " & rect.Right & " - bottom: " & rect.bottom & " - " & CBool(Elem.CurrentIsEnabled)
LireInfosElem = res
End Function

et voici du code pour déplacer une fenêtre (ici le formulaire correspond au bouton GotoA1) :
VB:
Sub GotoCellA1()
    Dim oExcel As IUIAutomationElement, rect As UIAutomationClient.tagRECT, A1Left, A1Top
    Dim oDesktop As IUIAutomationElement, oCondition As IUIAutomationCondition, iMoveWindow As IUIAutomationTransformPattern
    Dim oUIA As New CUIAutomation, oCellA1 As IUIAutomationElement, oUserForm As IUIAutomationElement
    Set oCondition = oUIA.CreatePropertyCondition(UIAutomationClient.UIA_ClassNamePropertyId, "XLMAIN")
    Set oDesktop = oUIA.GetRootElement
    Set oExcel = oDesktop.FindFirst(TreeScope_Children, oCondition)
    Set oCondition = oUIA.CreatePropertyCondition(UIAutomationClient.UIA_NamePropertyId, "A1")
    Set oCellA1 = oExcel.FindFirst(TreeScope_Descendants, oCondition)
    rect = oCellA1.CurrentBoundingRectangle
    A1Left = rect.left
    A1Top = rect.top
    Set oCondition = oUIA.CreatePropertyCondition(UIAutomationClient.UIA_NamePropertyId, "UserForm1")
    Set oUserForm = oExcel.FindFirst(TreeScope_Descendants, oCondition)
    Set iMoveWindow = oUserForm.GetCurrentPattern(UIA_TransformPatternId)
    iMoveWindow.Move A1Left, A1Top
End Sub

Voici ce que cela donne :


Comme on peut le constater la fenêtre d'Excel est un peu en dehors de l'écran et la fenêtre UserForm1 ne se positionne pas exactement en haut de la cellule A1.
Si on regarde avec l'outil opensource FlaUInspect qui affiche la position et les propriétés des éléments d'interface utilisateurs:

on constate que dans la fenêtre du formulaire il y a une zone invisible ce qui crée cette impression de décalage.
Pour envoyer du texte c'est plus délicat car il y a peu de contrôle utilisateur qui accepte que l'on écrive dedans directement.
Cependant comme Il y a le SetFocus sur tout élément on peut utiliser le SendKeys .
Voici le code du bouton EcrireConsole de l'animation :
VB:
Sub EcrireConsole()
    Dim oUIA As New CUIAutomation, oConsole As IUIAutomationElement, oText As IUIAutomationElement
    Dim oDesktop As IUIAutomationElement, oCondition As IUIAutomationCondition
    Dim Utils As Object
    Set oCondition = oUIA.CreatePropertyCondition(UIAutomationClient.UIA_NamePropertyId, "Invite de commandes")
    Set oDesktop = oUIA.GetRootElement
    Set oConsole = oDesktop.FindFirst(TreeScope_Children, oCondition)
    Set oCondition = oUIA.CreatePropertyCondition(UIAutomationClient.UIA_ClassNamePropertyId, "TermControl")
    Set oText = oConsole.FindFirst(TreeScope_Descendants, oCondition)
    oText.SetFocus
    DoEvents
    SendKeys "coucou", True
End Sub

Ami calmant, J.P
 

patricktoulon

XLDnaute Barbatruc
on devrait ouvrir une autre discussion sur UIautomationclient
car la on pollue grave la discussion
elle s sont belles tes démos ce serait dommage qu'elles se perdent dans une discussion
on fait une ressource en équipe si tu veux toi dudu et moi
pour le latebinding pas si sur je cherche pourquoi ca ne fonctionne pas chez moi
mais normalement createobject(Uiautmationcore.CUIautomation) devrait fonctionner
 

jurassic pork

XLDnaute Impliqué
Hello Dudu2,
en pièce jointe un classeur avec 3 macros uiAutomation qui fonctionnent chez moi. Il n'y a que UiAutomationClient qui est coché.
Ami calmant, J.P
 

Pièces jointes

  • TestUIAutomation.xlsm
    37.2 KB · Affichages: 1

Discussions similaires

Les cookies sont requis pour utiliser ce site. Vous devez les accepter pour continuer à utiliser le site. En savoir plus…