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
Histoire de faire quelques progrès, j'apprécierais que Job75 m'envoie le fichier dans lequel figure le code ci-dessous:

Si la feuille active est une feuille de calcul exécutez :
VB:
Sub ViderPP()
With [A1].MergeArea
.Copy .Cells
.Merge
End With
End Sub

Je voudrais l'executer pas à pas avec le debogage pour comprendre ce qui se passe.

Même question pour dudu2 concernant le programme présenté dans le post de 15H22

Merci d'avance à tous les deux.

Bonne année à tous
 

job75

XLDnaute Barbatruc
Bonjour ESCOUGER2022, le forum,

Voyez le fichier joint et les macros.

Cliquez sur le 1er bouton => Messages "Cette image est trop grande et va être tronquée".

Cliquez sur le 2ème bouton => Plus de messages.

Je suis sur Excel 2019.

A+
 

Pièces jointes

  • Copier.xlsm
    19.4 KB · Affichages: 2

jurassic pork

XLDnaute Impliqué
Hello
j'avais déjà parlé de l'excellente bibliothèque VBA stdVba et bien dedans il y a un module de classe qui gère les IAccessibles (stdAcc.cls)
Avec cette classe la gestion des IAccessibles est grandement simplifiée.
On peut créer une instance de cette classe à partir d'une fenêtre, d'un IAccessible, de la souris etc...
Voici un exemple de comment l'utiliser pour effacer tout dans le presse-papiers Office :
VB:
Sub ClearPressePapiersOffice()
    Dim maCmdBar As IAccessible, bHidden As Boolean
    Dim monStdAcc As stdAcc, monBouton As stdAcc
    On Error Resume Next
    Set maCmdBar = Application.CommandBars("Office Clipboard")
    bHidden = maCmdBar.Visible
    maCmdBar.Visible = True
    DoEvents: DoEvents
    Set monStdAcc = stdAcc.CreateFromIAccessible(maCmdBar)
'        monStdAcc.PrintChildTexts ' affiche les enfants
'        monStdAcc.PrintDescTexts ' affiche tous les descendants
        ' Set monBouton = monStdAcc.CreateFromPath("1.4.1.4.1.4.2").name 'utiliser le Path trouvé dans PrintDescTexts
    Set monBouton = monStdAcc.FindFirst(stdLambda.Create("$1.name=""Effacer tout"""))
    monBouton.DoDefaultAction
    maCmdBar.Visible = bHidden 'on restitue l'état de la CmdBar
End Sub

La documentation est ici.
Pour pouvoir utiliser la classe stdAcc.cls il faut aussi importer la classe stdICallable.cls et si on utilise les Find la classe stdLambda.cls.
Voici une macro qui affiche les propriétés IAccessible de tous les boutons qui vont se trouver sous la souris :
VB:
Sub DetectIAccessible()
While True
    Dim obj As stdAcc
    Set obj = stdAcc.CreateFromMouse()
'    If Not obj Is Nothing Then Debug.Print obj.name & " - " & obj.Role
    'Pour détecter tous les boutons
     If Not obj Is Nothing And obj.Role = "ROLE_PUSHBUTTON" Then
        Debug.Print obj.name & " - " & obj.Role
     End If
    DoEvents
Wend
End Sub
En pièce jointe un classeur de test.
Je suis sûr que patricktoulon va bien s'amuser avec cette classe.
Ami calmant, J.P
 

Pièces jointes

  • TestClipBoardOffice.xlsm
    149.4 KB · Affichages: 3
Dernière édition:

patricktoulon

XLDnaute Barbatruc
re
Bonjour @jurassic pork
ben bien sur que je vais m'amuser avec je vais la tordre dans tout les sens

cependant je ne comprends pas pourquoi ma fonction perso ne fonctionne pas
si tu le fait avec l'api "alloac" on devrait pouvoir le faire avec le com puisque le Iaccessible est parfaitement intégré dans VBA
un exemple un peu ancien mon calendrier dans le ruban
j'ai deux combobox (mois et année)
quand je change une des deux dans les callback j'appelle une procédure qui va cliquer sur la gallery pour qu'elle se développe toute seule sans que j'ai à le faire

je reste persuadé que l'on peut le faire sans passer par l'api
 

Pièces jointes

  • control calendrier dans le ruban customui 62-64 bits.xlsm
    25.8 KB · Affichages: 0

jurassic pork

XLDnaute Impliqué
Raoul , ta fonction FindChildByRoleOrName du post #28 fonctionne.
Avec ce code :
VB:
Sub ClearPressePapiersOffice2()
    Dim maCmdBar As IAccessible, bouton As IAccessible
    On Error Resume Next
    Set maCmdBar = Application.CommandBars("Office Clipboard")
    Set bouton = FindChildByRoleOrName(maCmdBar, "Effacer tout", 43, True) ' 43 = ROLE_PUSHBUTTON
    Debug.Print bouton.accName(ByVal 0&)
    Call bouton.accDoDefaultAction(ByVal 0&)
End Sub
J'arrive à effacer le presse-papier Office
Il y a cependant un truc louche le paramètre pChildRole est un string tandis que le accRole semble renvoyer un entier (c'est pour cela que j'ai mis 43 ).
 
Dernière édition:

patricktoulon

XLDnaute Barbatruc
chez moi ça ne fonctionne pas
VB:
Sub ClearPressePapiersOffice2()
    Dim maCmdBar As IAccessible, bouton As IAccessible
    'On Error Resume Next
    Set maCmdBar = Application.CommandBars("Office Clipboard")
    Set bouton = FindChildByRoleOrName(maCmdBar, "Effacer tout", 43, True) ' 43 = ROLE_PUSHBUTTON
   ' Debug.Print Not bouton Is Nothing
    'Call bouton.accDoDefaultAction(ByVal 0&)
End Sub
' Fonction privée pour rechercher d'un objet accessible à partir de son parent, son role et son nom
Private Function FindChildByRoleOrName(pParent As IAccessible, Optional pChildName As String = "*", Optional pChildRole As String = "*", Optional pRecursif As Boolean = False) As IAccessible
    Dim lName As String, lRole As Long
    Dim oChild As IAccessible
    Const NAVDIR_FIRSTCHILD = &H7&
    Const NAVDIR_NEXT = &H5&
    On Error GoTo gestion_erreurs
    Do
        If oChild Is Nothing Then
            Set oChild = pParent.accNavigate(NAVDIR_FIRSTCHILD, ByVal 0&)
            Debug.Print oChild.accName(ByVal 0&) & "---" & oChild.accRole(ByVal 0&)
        Else
            Set oChild = oChild.accNavigate(NAVDIR_NEXT, ByVal 0&)
            Debug.Print oChild.accName(ByVal 0&) & "---" & oChild.accRole(ByVal 0&)
        End If
        If pChildName <> "*" Then lName = oChild.accName(ByVal 0&)
        If pChildRole <> "*" Then lRole = oChild.accRole(ByVal 0&)
        If lRole Like pChildRole And lName Like pChildName Then
            Set FindChildByRoleOrName = oChild
            Exit Do
        End If
        If pRecursif Then
            Set FindChildByRoleOrName = FindChildByRoleOrName(oChild, pChildName, pChildRole, pRecursif)
            If Not FindChildByRoleOrName Is Nothing Then Exit Do
        End If
    Loop
gestion_erreurs:
    If Err.Number <> 0 Then
        Set FindChildByRoleOrName = Nothing
    End If
End Function
dans le debug
Presse-papiers---9
Presse-papiers---10
Collecte et collage 2.0---9
Collecte et collage 2.0---38
 

jurassic pork

XLDnaute Impliqué
ben 2016 ou 2021 par exemple.
En tout cas j'ai désactivé le On Error dans ta fonction pour voir et cela semble être le récursif qui ne fonctionne pas
j'ai une erreur 424 objet requis sur cette ligne :
VB:
Set oChild = pParent.accNavigate(NAVDIR_FIRSTCHILD, ByVal 0&)
et si je mets le gestionnaire d'erreur je n'ai que ces deux lignes :
Volet Office---contrôle
Options du volet des tâches---57
qui sont les descendants directs je n'ai pas l'arborescence
 

patricktoulon

XLDnaute Barbatruc
encore une découverte
quand le volet presse papier fermé
Volet Office---contrôle
Options du volet Office---57

quand il est ouvert (affiché)
Presse-papiers---9
Presse-papiers---10
Collecte et collage 2.0---9
Collecte et collage 2.0---38
 

jurassic pork

XLDnaute Impliqué
c'est vrai que j'ai oublié de rendre visible le volet du presse-papiers avant de l'utiliser -> ça marche beaucoup mieux si il est visible .
Maintenant avec ce code :
VB:
Sub ClearPressePapiersOffice2()
    Dim maCmdBar As IAccessible, bouton As IAccessible
    On Error Resume Next
    Set maCmdBar = Application.CommandBars("Office Clipboard")
    maCmdBar.Visible = True
    DoEvents: DoEvents
    Set bouton = FindChildByRoleOrName(maCmdBar, "Effacer tout", 43, True) ' 43 = ROLE_PUSHBUTTON
    Call bouton.accDoDefaultAction(ByVal 0&)
End Sub
j'ai cela dans le debug :
Presse-papiers---9
Presse-papiers---9
---9
---10
Presse-papiers---9
Presse-papiers---38
Coller tout---43
Effacer tout---43
et le presse-papiers est bien effacé (excel 2016 32 bits)
Patrick tu testes avec quel Excel ?
 

Discussions similaires

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