Microsoft 365 Création d'un nouvel onglet du ruban en vba et y attacher 4 macros complémentaires (MAC et PC)

RyuAutodidacte

XLDnaute Impliqué
Bonjour,

j'ai beau chercher partout mais je ne trouve de solution pour le moment …

Comme l'onglet "Acceuil" qui existe dans le ruban, je cherche à pourvoir créer par vba un nouvel onglet "TOTO" et y insérer 4 macros, provenant d'un complément Excel d'un fichier xlam déjà insérer par macro :
VB:
Sub Add_AddIn() 'version Mac (peut être PC aussi pouvez vous confirmer SVP)
Dim addInPath As String
    addInPath = "MonChemin/TEST.xlam"
    AddIns.Add addInPath
    AddIns("TEST").Installed = True '
End Sub
Le but est de pourvoir faire une automatisation d'installation sur plusieurs utilisateurs Mac et PC

merci d'avance pour vos réponses

Ryu
 

patricktoulon

XLDnaute Barbatruc
re et pour aller plus loin dans les règles


<splitbutton><--!attribut size "autorisé--!>
<menu><--!attention ici contrairement à un menu ailleurs pas d'icône pas de label--!>
<button><!--Attention pas d'attribut size autorisé -->
= bon

on met l'attribut itemsize "large" au menu pour grossir les boutons descendants

et il y en a un paquet de règles comme ça
tu crois toujours y arriver "avec une chaine string ? 🤣 🤣 🤣
 

patricktoulon

XLDnaute Barbatruc
demo.gif

XML:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<customUI azerty="http://schemas.microsoft.com/office/2009/07/customui" onLoad="CustomUIOnLoad">
    <!--creatorRiBBonX application V 4.9.7 developed BY patricktoulon  a 10-06-2023-->
    <!--project Ribbon name :ryuauto-->
    <ribbon startFromScratch="false">
        <tabs>
            <tab id="tab_1" label="Onglet Perso">
                <group id="group_0" label="Groupe N° 1">
                    <!--ce splitbutton est d"ans un group l'attribut size est autorisé-->
                    <splitButton id="splitButton_1" size="large">
                        <!--cemenu est le conteneur des bouton du splitButton donc pas de label pas d icone-->
                        <menu id="menu_1" itemSize="large">
                            <button id="button_1" onAction="button_1_Click" imageMso="NameCreateFromSelection" label="toto" tag="toto"/>
                            <button id="button_2" onAction="button_2_Click" imageMso="PageBorderAndShadingDialog" label="titi" tag="titi"/>
                            <button id="button_3" onAction="button_3_Click" imageMso="SaveAll" label="riri" tag="riri"/>
                        </menu>
                    </splitButton>
                </group>
            </tab>
        </tabs>
    </ribbon>
</customUI>
 

RyuAutodidacte

XLDnaute Impliqué
Regarde la pièce jointe 1174298
XML:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<customUI azerty="http://schemas.microsoft.com/office/2009/07/customui" onLoad="CustomUIOnLoad">
    <!--creatorRiBBonX application V 4.9.7 developed BY patricktoulon  a 10-06-2023-->
    <!--project Ribbon name :ryuauto-->
    <ribbon startFromScratch="false">
        <tabs>
            <tab id="tab_1" label="Onglet Perso">
                <group id="group_0" label="Groupe N° 1">
                    <!--ce splitbutton est d"ans un group l'attribut size est autorisé-->
                    <splitButton id="splitButton_1" size="large">
                        <!--cemenu est le conteneur des bouton du splitButton donc pas de label pas d icone-->
                        <menu id="menu_1" itemSize="large">
                            <button id="button_1" onAction="button_1_Click" imageMso="NameCreateFromSelection" label="toto" tag="toto"/>
                            <button id="button_2" onAction="button_2_Click" imageMso="PageBorderAndShadingDialog" label="titi" tag="titi"/>
                            <button id="button_3" onAction="button_3_Click" imageMso="SaveAll" label="riri" tag="riri"/>
                        </menu>
                    </splitButton>
                </group>
            </tab>
        </tabs>
    </ribbon>
</customUI>
c'est un pb que je peux régler, mais on en reparlera en détails pour le splitButton
Si tu as d'autres particularités comme celle-là à tester je veux bien, car je pense que ma méthode est ok à 97-99%
J'ai l'impression que c'est le seul pb pour l'instant
en plein taf pas le temps de regarder en détails
PS : méthode à 100% si j'ai toutes les particularités que j'intègre à mon code
 
Dernière édition:

patricktoulon

XLDnaute Barbatruc
un autre exemple qui ressort souvent comme erreur
la gallery pas d'attribut getitemcount , getitemlabel si la gallery a des enfants <item>

les boutons size uniquement si c'est dans un group

menu itemsize à large pour grossir les boutons qui sont dedans

la comboBox pas de callback getitemID
les dropDown oui
voir les videos je montre les différences des deux même si elles se ressemblent

la comboBox et editbox le sizestring c'est en nombre de lettre et non en nombre

le split button pas de label pas d'icône

dynamicMenu getcontent e invalidatecontrolonDrop
le content c'est du code xml dynamique vba


et j'en passe et des meilleurs avec les autres call back
 

RyuAutodidacte

XLDnaute Impliqué
un autre exemple qui ressort souvent comme erreur
la gallery pas d'attribut getitemcount , getitemlabel si la gallery a des enfants <item>

les boutons size uniquement si c'est dans un group

menu itemsize à large pour grossir les boutons qui sont dedans

la comboBox pas de callback getitemID
les dropDown oui
voir les videos je montre les différences des deux même si elles se ressemblent

la comboBox et editbox le sizestring c'est en nombre de lettre et non en nombre

le split button pas de label pas d'icône

dynamicMenu getcontent e invalidatecontrolonDrop
le content c'est du code xml dynamique vba


et j'en passe et des meilleurs avec les autres call back
Re Patrick,
désolé, mais là je ne fait pour le moment que les éléments pas les attributs
Les attributs viendront après, je sais qu'il y a des particularités selon les cas même si je ne connais pas ça par cœur ;)

et il y en a un paquet de règles comme ça
tu crois toujours y arriver "avec une chaine string ? 🤣 🤣 🤣
Je te rappelle que l'on fait un CustomUICreator pour Mac sans DomDocument
 
Dernière édition:

RyuAutodidacte

XLDnaute Impliqué
Re MS donne cette exemple, peux tu m'expliquer stp car tu disais que ca ne se fait pas :
XML:
 <splitButton id="splitButton" size="large" >
  <button id="button" imageMso="HappyFace" label="Split Button" />
  <menu id="menu">
   <button id="button1" label="Button 1" />
   <button id="button2" label="Button 2" />
  </menu>
 </splitButton>
on dirait que c'est possible, mais que l'on peut mettre qu'un seul button après le splitButton

en attendant je regarde ta viédo ;)
 

patricktoulon

XLDnaute Barbatruc
exemple 2007 ca fonctionne pas sur 2013
je m'en servait comlme ca sur 2007 pour avoir l'icon
mais maintenant l'icone du split c'est le premiier bouton du menu soit le même résultat
ca servait aussi a empecher le clic sur l'icone du split avec un bouton sans onAction
de toute facon ca ne marche plus 2013 demain j'essaie sur 2016 mais j'ai un doute
 

RyuAutodidacte

XLDnaute Impliqué
Merci pour la dédicace vidéo ;)
C'est super intéressant t'es explication, mais qd tu parles de simplicité, elle est de ton coté toi qui pratique le XML depuis x temps.
Surtout que la tu es dans la logique et le mécanisme de construction d'un XML comme si on avait en qq sorte un domDocument … et tu sais bien que j'y connais rien 🤣
il va me falloir un peu de temps avant de m'y habituer …
En tout cas je suis ravi de t'avoir motivé pour la mise à jour de ton Creator et que tu prennes du plaisir avec ce challenge Mac ;)
Ne connaissant pas tout ça je n'y suis pas allé de la même logique mais mon instinct me dit que ca peut marcher
je reviens pour te présenter une partie …
 

patricktoulon

XLDnaute Barbatruc
oui de toute facon o peut toujours arriver a faire un truc qui marche mais a quel prix
c'est ça le truc
après que ce soit du xml ou autre quand on parle de hiérarchie on parle d'object quel qu’il soit
un panier
panier appendchild pomme
panier appendchild poire
panier appendchild orange
etc...
ça se vérifie dans tout les cas


on développe donc en mode object surtout que pour le coup vba est très permissif sur ce point
c'est le B à BA

développez une hiérarchie ou ne serait ce que sa représentation en string ne sera jamais perenne il y aura toujours des trucs qui clochent

rien qu'avec ses 3 fruits combien d’après toi il y a de possibilités d'erreur
panier panier = erreur
poire poire = erreur
pomme pomme = erreur
poire pomme = erreur
pomme poire = erreur
pomme panier= erreur
poire panier = erreur
et si je rajoute le test de l'orange ca nous fait 24 possibilité
alors imagine avec la 15 aine d'element xml du customUI sans compter ses règles
 

RyuAutodidacte

XLDnaute Impliqué
  1. Le principe est de vérifier la validité du customUI en parcourant les éléments qui se suivent
    (le résultat que tu as vu est sur un code de test)
    Bien sur il serait possible aussi de le faire à la volée qd on rajoute un élément
    Hors mis le cas du splitButton => pas encore corrigé
  2. Si il trouve une erreur alors il indique quel est l'erreur et ce qui est possible de faire pour la suite
  3. Si les éléments vérifiés sont valides on peut alors construire le customUI
  4. Quand c'est valide : Selon les éléments checker (différent cas selon les éléments qui se suivent)
    il propose les attributs adaptés aux éléments sur la feuille Excel, (libre à nous de les utiliser ou pas)
    PS : Pour la présentation je verrai plus tard
  5. Une fois les attributs définis, on construit le customUI
Patrick ,Tient puisque j'y pense, je pourrai viré le button du splitButton pour corriger … on est d'accord ?? je vais tester … heu non … il faut que je sache comment cela se passe pour les toggleButton …
Si c'est le même principe que pour button alors il faut que je le vire

En résultat, ca donnerai cela :
VB:
SuiteElems = Array("tab", "group", "button", "button", "splitButton", "menu", "button", "button", "splitButton", "menu", "button", "button")
Code:
tab  |  Vrai/Vrai
group  |  Vrai/Vrai
button  |  Vrai/Faux
button  |  Vrai/Faux
splitButton  |  Vrai/Vrai
menu  |  Vrai/Vrai
button  |  Vrai/Faux
button  |  Vrai/Faux
splitButton  |  Vrai/Vrai
menu  |  Vrai/Vrai
button  |  Vrai/Faux
button  |  Vrai/Faux

Re @patricktoulon j'ai enfin corrigé mon code en prenant compte de ta remarque sur splitButton et button (j'ai considéré qu'il en était de même pour toggleButton avec splitButton… confirme le moi stp … ?)

Donc je fais finir ce post :)

avec :
VB:
SuiteElems = Array("tab", "group", "button", "button", "splitButton", "button", "splitButton", "menu", "button", "button")
Code:
tab  |  Vrai/Vrai
group  |  Vrai/Vrai
button  |  Vrai/Faux
button  |  Vrai/Faux
splitButton  |  Vrai/Faux
button  |  Faux/Faux
splitButton  |  Faux/Vrai
menu  |  Vrai/Vrai
button  |  Vrai/Faux
button  |  Vrai/Faux
Donc à partir du moment ou l'on a Faux/Faux (button | Faux/Faux), le customUI ne sera pas valide, donc on ne génère pas le XML et on préviens sur quoi est le problème ou les problèmes
PS : comme je l'ai dit cela pourrait se faire à la volée qd on insère un élément

Mon code test :
VB:
Sub getMyElements()
    Dim inputList
    'SuiteElems = Array("tab", "group", "button", "button", "splitButton", "button", "button", "group", "button", "separator", "button")
'    SuiteElems = Array("tab", "group", "button", "button", "splitButton", "menu", "button", "button", "splitButton", "menu", "button", "button")
    SuiteElems = Array("tab", "group", "button", "button", "splitButton", "button", "splitButton", "menu", "button", "button")
   
    CheckElemUI SuiteElems, "tabs"

End Sub

Mes vrais codes dont je vais me servir :
VB:
Function CheckElemUI(ByVal arr As Variant, ByVal preElem As String)
Dim Elems As New ElemUI, getElemConteneur As New Collection, ElemsParents As String

   ElemsParents = "ribbon | tabs | tab | group | box | buttonGroup | splitButton | menu | dynamicMenu | comboBox | dropDown | gallery"

    For i = LBound(arr) To UBound(arr)
        CheckP = Not IsError(Application.Match(preElem, Elems.GetParentElem(arr(i)), 0))
        On Error Resume Next
            CheckC = Not IsError(Application.Match(arr(i + 1), Elems.GetChildElem(arr(i)), 0))
            If Err Then
                CheckC = False
            End If
        On Error GoTo 0
        If ElemsParents Like "*| " & arr(i) & " |*" Then
            If getElemConteneur.Count = 0 Then
                getElemConteneur.Add arr(i), arr(i)
            Else
                On Error Resume Next
                    getElemConteneur.Add arr(i), arr(i), preElem
                    If Err Then
                        getElemConteneur.Remove arr(i)
                        getElemConteneur.Add arr(i), arr(i), preElem
                    End If
                On Error GoTo 0
            End If
        End If
        Debug.Print arr(i) & "  |  " & CheckP & "/" & CheckC
        preElem = getElemConteneur.Item(1)
    Next

End Function

Mon module de classe du nom de ElemUI (tu y verras ma correction):
VB:
Option Explicit

Private parentElem As Collection
Private childElem As Collection

Public Function GetParentElem(ByVal key As String) As Variant
    GetParentElem = parentElem(key)
End Function

Public Function GetChildElem(ByVal key As String) As Variant
    GetChildElem = childElem(key)
End Function

Private Sub Class_Terminate()
    Set parentElem = Nothing
    Set childElem = Nothing
End Sub

Private Sub Class_Initialize()
    Set parentElem = New Collection
    Set childElem = New Collection
   
    parentElem.Add Array("ribbon"), "tabs"
    parentElem.Add Array("tabs"), "tab"
    parentElem.Add Array("tab"), "group"
    parentElem.Add Array("group", "box"), "box"
    parentElem.Add Array("group", "box"), "buttonGroup"
    parentElem.Add Array("group", "box", "buttonGroup", "menu", "splitButton"), "menu"
    parentElem.Add Array("buttonGroup", "menu"), "dynamicMenu"
    'parentElem.Add Array("group", "box", "buttonGroup", "dropDown", "gallery", "menu", "splitButton"), "button"
    parentElem.Add Array("group", "box", "buttonGroup", "dropDown", "gallery", "menu"), "button"
    parentElem.Add Array("group", "box", "buttongroup", "menu"), "splitButton"
    parentElem.Add Array("group", "box", "menu"), "checkBox"
    parentElem.Add Array("group", "box"), "comboBox"
    parentElem.Add Array("group", "box"), "dropDown"
    parentElem.Add Array("group", "box", "buttonGroup", "menu"), "gallery"
    parentElem.Add Array("comboBox", "dropDown", "gallery"), "item"
    parentElem.Add Array("group", "box"), "labelControl"
    parentElem.Add Array("group"), "separator"
    parentElem.Add Array("menu"), "menuSeparator"

    childElem.Add Array("tabs"), "ribbon"
    childElem.Add Array("tab"), "tabs"
    childElem.Add Array("group"), "tab"
    childElem.Add Array("box", "button", "buttonGroup", "checkBox", "comboBox", "control", "dialogBoxLauncher", "dropDown", "dynamicMenu", "editBox", "gallery", "labelControl", "menu", "separator", "splitButton", "toggleButton"), "group"
    childElem.Add Array("box", "button", "buttonGroup", "checkBox", "comboBox", "control", "dropDown", "dynamicMenu", "editBox", "gallery", "labelControl", "menu", "splitButton", "toggleButton"), "box"
    childElem.Add Array("button", "control", "dynamicMenu", "gallery", "menu", "splitButton", "toggleButton"), "buttonGroup"
    childElem.Add Array("menu"), "splitButton"
    'childElem.Add Array("button", "menu", "toggleButton"), "splitButton"
    childElem.Add Array("button", "checkBox", "control", "dynamicMenu", "gallery", "menu", "menuSeparator", "splitButton", "toggleButton"), "menu"
    childElem.Add Array("button", "checkBox", "control", "dynamicMenu", "gallery", "menu", "menuSeparator", "splitButton", "toggleButton"), "dynamicMenu"
    childElem.Add Array("item"), "comboBox"
    childElem.Add Array("button ", "item"), "dropDown"
    childElem.Add Array("button ", "item"), "gallery"
End Sub

Mon module de classe pas encore utilisé IndentationManager :
VB:
Private indentation As Integer
Private IndentationSpace As Integer

Public Sub Initialize(ByVal space As Integer)
    indentation = 0
    IndentationSpace = space
End Sub

Public Sub IncreaseIndentation()
    indentation = indentation + IndentationSpace
End Sub

Public Sub DecreaseIndentation()
    If indentation >= IndentationSpace Then
        indentation = indentation - IndentationSpace
    End If
End Sub

Public Function GetCurrentIndentation() As String
    GetCurrentIndentation = space(indentation)
End Function

• La suite que je dois travaillé par rapport à mes résultat et selon les types d'éléments qui s'imbriquent et de faire correspondre exactement les attributs à chaque éléménts

•Il me restera le problème des CallBacks

• Et je dois créer l'écriture du XML customUI
, mais je ne pense pas que cela soit un problème puisque j'ai déjà réussi à le faire correctement (et je n'avais pas fait ces codes à l'époque)
 
Dernière édition:

RyuAutodidacte

XLDnaute Impliqué
re
perso je veux bien mais pour la suite tu te heurte à plein de choses
et comme je le dis dans la vidéo tu va droit dans le mur

je te fait les fonctions passerelles getElementById voir même la fonction getElementsBytagname
et je te donnerais le fichier
Re Patrick,
j'étais mort de rire 🤣 avec ton franc parlé, mais ne t'inquiète pas je suis de très très loin d'être heurté 😜

Tes explications sont beaucoup plus abordable, et j'ai mieux compris le principe même si je suis loin de le maitriser.
C'est super intéressant je sens que je vais apprendre de nouvelles choses :cool: :D
Ce qui est sur c'est que je vais pas m'en sortir tout seul avec ta méthode, et ton aide est très apprécié ;)
mais du coup il faut mettre toutes les "Case" pour checker si tel élément est ok qd on l'insère …
Enfin il faut que je vois tout en détails de ce que tu me proposes déjà pour le comprendre complètement
Mais là j'ai vraiment des explications plus abordables et c'est top 👍👍👍👍👍
 

Statistiques des forums

Discussions
315 131
Messages
2 116 571
Membres
112 791
dernier inscrit
Jean-Marc YOT