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é
Supporter XLD
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
tiens j'ai corrigé un peu
VB:
Type Xmlelement
    id As String
    label As String
    indent As Long
    parentId As String
    TagName As String
    vu As Boolean
End Type
Public AllElements() As Xmlelement
Dim element As Xmlelement

Sub init()
    ReDim Preserve AllElements(0 To 0)
End Sub

Function Appendchild(parent As Xmlelement, enfant As Xmlelement)    'attribut d'affiliation
    enfant.parentId = parent.id
End Function

Function createElement(TagName) As Xmlelement    'creation d'un element(tout type argument "Tagname" pour le type )
    Dim elem As Xmlelement
    elem.TagName = TagName
    ReDim Preserve AllElements(UBound(AllElements) + 1): AllElements(UBound(AllElements)).TagName = TagName: createElement = AllElements(UBound(AllElements))
End Function

Function GetelementById(idx As String) As Xmlelement    'fonction pour rechercher un element portant un id précis(utile pour plus tard quand on construire dynamico
    For i = 1 To UBound(AllElements)
        If AllElements(i).id = idx Then GetelementById = AllElements(i): Exit Function
    Next
End Function

Function getValidId(TagName)    ' fonction pour determiner un id valide et non utilisé(variante de mon creator adapté pour la circonstance)
    Dim e&, x As Boolean, i&
    For e = 1 To 1000
        vid = TagName & "_" & e
        x = False
        For i = 0 To UBound(AllElements)
            If AllElements(i).id = vid Then x = True: Exit For
        Next
        If x = False Then getValidId = vid: Exit For
    Next
End Function
Sub test()
    init
    Dim ParentX As Xmlelement
    'creation du père de tous ( le patron)
      element = createElement("père")
    With element
        .id = getValidId(.TagName)
        .indent = 0
        .label = "Robert"
        ParentX = GetelementById("")    'le père n'a pas de parent
        Appendchild ParentX, element
        .indent = ParentX.indent + 1
      AllElements(UBound(AllElements)) = element
    End With


    'maintenant  je vais créer le fils
    element = createElement("fils")
    With element
        .id = getValidId(.TagName)
        .label = "jean"
        ParentX = GetelementById("père_1")    'je choisi le parent a qui je veux l'affilier
        Appendchild ParentX, element
        .indent = ParentX.indent + 1
        AllElements(UBound(AllElements)) = element
    End With


    'maintenant  je vais créer le fils2
    element = createElement("fils")
    With element
        .id = getValidId(.TagName)
        .label = "Luc"
        ParentX = GetelementById("père_1")    'je choisi le parent a qui je veux l'affilier
        Appendchild ParentX, element
        .indent = ParentX.indent + 1
        AllElements(UBound(AllElements)) = element
    End With


    'maintenant pour l'exemple je vais créer le petit fils qui sera le fils du fils 1
    'creation du petit fils
    element = createElement("petitfils")
    With element
        .id = getValidId(.TagName)
        .label = "kevin"
        ParentX = GetelementById("fils_1")    'je choisi le parent a qui je veux l'affilier
        .indent = ParentX.indent + 1
        Appendchild ParentX, element
        AllElements(UBound(AllElements)) = element
    End With

    'la voiture du  du fils 1
    'creation du petit fils
    element = createElement("voiture")
    With element
        .id = getValidId(.TagName)
        .label = "Renault"
        ParentX = GetelementById("fils_1")    ' je choisi a qui est la voiture
        .indent = ParentX.indent + 1
        Appendchild ParentX, element
        AllElements(UBound(AllElements)) = element
    End With


    lecture
End Sub
Sub lecture()
    For i = 1 To UBound(AllElements)
        Dim e As Xmlelement
        e = AllElements(i)
        Debug.Print "<" & e.TagName & " id=""" & e.id & """" & " label=""" & e.label & """" & _
                  " parentID=""" & e.parentId & """" & " indent=""" & e.indent & """"

    Next
    Debug.Print "***************************************"
    GenerateCodXmL
End Sub

Function GenerateCodXmL(Optional i As Long = 0)
    Dim e As Xmlelement, a&
    Static codeXml As String
    e = AllElements(i)
    If i = 0 Then PartCod = "": codeXml = ""
    If e.vu = False Then
        If " voiture petitfils " Like "* " & e.TagName & " *" Then fin = "/>" Else fin = ">"
        PartCod = String(e.indent, vbTab) & "<" & e.TagName
        PartCod = PartCod & " id = """ & e.id & """"""
        If e.label <> "" Then PartCod = PartCod & " label=""" & e.label & """"
          PartCod = PartCod & fin
        'codeXml = codeXml & PartCod & vbCrLf
        Debug.Print PartCod
        With AllElements(i): .vu = True: End With
    End If
    For a = i + 1 To UBound(AllElements)
        If AllElements(a).vu = False Then
            If AllElements(a).parentId = e.id Then
                GenerateCodXmL a
            End If
        End If
    Next
    If " père fils " Like "* " & e.TagName & " *" Then
        Debug.Print String(e.indent, vbTab) & "</" & e.TagName & ">"
        'codeXml = codeXml & String(e.indent, vbTab) & "</" & e.TagName & ">" & vbCrLf
    End If
    If i = 0 And codeXml <> "" Then Debug.Print codeXml

    GenerateCodXmL = codeXml
End Function
 

RyuAutodidacte

XLDnaute Impliqué
Supporter XLD
tu a compris le truc magic avec la fonction generateXML?
Hi Patrick,
j'ai regardé vite fais en diagonale car il était tard et avec mon taf today ca va être un peu compliqué de m'y penché, je regarderai en détails ce soir (peut être pendant ma pause dèj si je peux), mais ça à l'air franchement top 👍
 
Dernière édition:

RyuAutodidacte

XLDnaute Impliqué
Supporter XLD
tu a compris le truc magic avec la fonction generateXML?
re,
ok tu enregistres si l'id est un père ou un enfant
si c'est un enfant tu spécifie l'id du père
et tu fais en même temps les indentations
quand tu boucle sur chaque éléments tu vérifies père / fils et fais les appels selon les id pour écrire le xml dans le bon ordre … grâce à la récursion
 
Dernière édition:

RyuAutodidacte

XLDnaute Impliqué
Supporter XLD
Re Patrick,

il y a une question que je me pose qd même, avec Function getValidId(TagName) on vérifie si l'id peut être valide ou pas pour un élément, mais je ne vois pas de code qui vérifie si le xml une fois écris est valide (un élément qui n'a pas sa place à la position où il est …) ?
ou j'ai loupé un épisode … ?
 

patricktoulon

XLDnaute Barbatruc
re
et oui c'est la que je vois que tu comprends pas bien le principe de la récursivité car c'est avec elle que je remet tout en place
qui me permet avec une seule boucle de replacer les éléments à leur place a partir du moment ou le premier élément du tableau est à sa place

alors je vais essayer simplifier l'explication autant que je peux
supposons que nous avons les elements qui suivent

element 1 = papa robert
element 2 =petit fils kevin fils de jean qui le 2d fils de robert
element 3 =le fils jeorge qui est le fils de robert
element 4 =jean fils de robert

la fonction generateXML comment fonctionne t elle ?
et bien je lui envoie l'index 1
function generateXml lit le 1er donc robert
ensuite je fait une boucle sur tout les éléments
et si un ou plusieurs des elements sont enfants directs de robert et bien je relance la fonction avec l'index de l'enfant trouvé et ainsi de suite quand elle "a fini elle revient l'instance qui a été lancé précé demment
c'est le principe de la poupée russe

autrement dit
elle va lire robert
boucle et elle trouvre jeorge on la relance et elle lit george
boucle elle trouve plus rien
elle revient a l'ancienne session qui etait la lecture de robert
et elle passe au 2d fils trouvé jean
boucle sur jean
elle trouve kevin
elle boucle sur kevin
elle trouve plus rien
elle revient donc à jean
elle trouve plus rien
elle revient donc a robert
elle trouve plus rien c'est terminé


et maintenant si je prend le surligneur et que je met les prénom en couleur dans ce que je viens de t'expliquer
demo.gif
 
Dernière édition:

RyuAutodidacte

XLDnaute Impliqué
Supporter XLD
re
et oui c'est la que je vois que tu comprends pas bien le principe de la récursivité car c'est avec elle que je remet tout en place
qui me permet avec une seule boucle de replacer les éléments à leur place a partir du moment ou le premier élément du tableau est à sa place

alors je vais essayer simplifier l'explication autant que je peux
supposons que nous avons les elements qui suivent

element 1 = papa robert
element 2 =petit fils kevin fils de jean qui le 2d fils de robert
element 3 =le fils jeorge qui est le fils de robert
element 4 =jean fils de robert

la fonction generateXML comment fonctionne t elle ?
et bien je lui envoie l'index 1
function generateXml lit le 1er donc robert
ensuite je fait une boucle sur tout les éléments
et si un ou plusieurs des elements sont enfants directs de robert et bien je relance la fonction avec l'index de l'enfant trouvé et ainsi de suite quand elle "a fini elle revient l'instance qui a été lancé précé demment
c'est le principe de la poupée russe

autrement dit
elle va lire robert
boucle et elle trouvre jeorge on la relance et elle lit george
boucle elle trouve plus rien
elle revient a l'ancienne session qui etait la lecture de robert
et elle passe au 2d fils trouvé jean
boucle sur jean
elle trouve kevin
elle boucle sur kevin
elle trouve plus rien
elle revient donc à jean
elle trouve plus rien
elle revient donc a robert
elle trouve plus rien c'est terminé


et maintenant si je prend le surligneur et que je met les prénom en couleur dans ce que je viens de t'expliquer
Regarde la pièce jointe 1174162

si j'ai bien compris le récursif, mais j'ai re regardé l'ensemble du code et ma réponse est dans le sub test …
donc oui on peut les mettre dans le désordre car dans le Sub test() tout est spécifié qui va où…

Mais dans ton creator, tu fais fais le même principe ou pas qd tu rajoutes un éléments … ?
car visuellement dans la partie "Arborescence du XML" on voit déjà les éléments bien agencé …
 

RyuAutodidacte

XLDnaute Impliqué
Supporter XLD
re
a ben non dans mon creator j'ai le domdocument qui est lui même dans l'ordre automatiquement
car les éléments sont identifiable en tant qu'object
c'est ce que l'on peut pas faire avec MAC puisque pas de DOMDOM ;)

je te fait une demo dans l'après midi
en parallèle de ce que tu me montres et m'apprends (top cool)
je tente une autre approche (mais comme j'en suis au début, je ne vais pas vraiment en parler avant d'avoir fait tous les tests possible)
 
Dernière édition:

RyuAutodidacte

XLDnaute Impliqué
Supporter XLD
Re Patrick,

les 1er tests mais c'est loin d'être fini

en me basant dans le principe sur :
VB:
    previousElement = "button"
    currentElement = "group"

résulats avec plusieurs éléments previousElement et currentElement :
Code:
button n'est pas un parent de group
group est un parent de button
group a button comme enfant

------------------------

tab n'est pas un parent de splitButton
splitButton n'est pas un parent de tab
splitButton n'a pas tab comme enfant

------------------------

menu est un parent de menuSeparator
menuSeparator n'est pas un parent de menu
menuSeparator n'a pas menu comme enfant

------------------------

menu n'est pas un parent de separator
separator n'est pas un parent de menu
separator n'a pas menu comme enfant

------------------------

group est un parent de button
button n'est pas un parent de group
button n'a pas group comme enfant

------------------------

button n'est pas un parent de group
group est un parent de button
group a button comme enfant

tu peux m'en proposer si tu veux et je te donne le résultats, tu pourras me piéger ;)
previousElement = ?
currentElement = ?
 
Dernière édition:

patricktoulon

XLDnaute Barbatruc
RE
si tu le dis
moi je crois que non
previouselement et l’élément précédent du meme parent je vois pas l'intérêt de faire le test parent

imaginons
PERE
FILS
PETITS FILS
ARIRERE PETIT FILS

COMMENT TU FAIT POUR
déterminer le pere pour l'arriere petit fils

c'est ce que je te montre avec le parentiD ET LA FONCTION RECURSIVE qui me remet tout en ordre
 

RyuAutodidacte

XLDnaute Impliqué
Supporter XLD
Là il ne s'agit pas de cela, le but est de vérifier une suite d'élément valide selon les résultats
et comme je te l'ai dit j'en suis au début
là je joue sur :
previousElement
currentElement
mais ca va bien plus loin par la suite
tant que j'ai pas qq chose de présentable comme tu le fais ne me narguant 😜 🤣 🤣
je le mettrai dès que je serai arrivé au but … sur cette partie là
 

patricktoulon

XLDnaute Barbatruc
j'aurais envie de te dire d'arrêter mais je sais que tu est tenace (et qui sait peut être)
mais dans tout les cas tu va te heurter a un probleme de "LET"
car en effet dans les modules classes les variables public tableau dimensionnée ne peuvent exister
et comme on va certainement dans les étages tu sera bloqué là
la seule solution c'est de travailler avec variable tableau oui public redimensionné dans le initiate oui
mais linéaire donc element 1, element 2,element 3 ,etc....sans distinction parent/enfant autre qu'avec une variable ou property
ce qui dans ce cas rend obsolète le besoins d'une classe puisque c'est la même chose que moi en fait

il me reste une solution et je dis bien UNE SEULE !! que je n'ai pas testé
c
'est les poupées russes
 

Statistiques des forums

Discussions
312 502
Messages
2 089 047
Membres
104 011
dernier inscrit
dfr