Comment repérer les tableaux fondés sur un lien DDE ?

    From The Document Foundation Wiki
    < Macros‎ | Writer
    This page is a translated version of the page Macros/Writer/002 and the translation is 100% complete.


    Other languages:

    Description

    Le menu Édition ▸ Liens permet de connaître les liens figurant dans un document :

    • Fichier source (Url)
    • Élément (plage)
    • Type (soffice)
    • Actualiser (automatique / manuel)

    En revanche ni cette commande, ni le navigateur ne permettent de savoir quels sont les tableaux concernés (nom ou position dans le document).

    L'objet du programme présenté ici est de repérer les tableaux créés par lien DDE.[1]

    Le programme insère dans la première cellule du tableau un commentaire comprenant :

    • la source (Url du classeur par exemple),
    • la plage utilisée dans la source.

    La gestion des commentaires n'est pas détaillée ici. Se reporter à Comment insérer un commentaire par programme.

    La collection TextFieldMasters permettrait de retrouver uniquement les informations affichées par le menu Édition ▸ Liens et TextTables ne nous renseigne pas davantage.

    La connexion DDE des données des tables est contenue dans un élément <office:dde-source>[2].

    Nous pouvons donc parcourir le fichier content.xml à la recherche de ces éléments. Le programme commence par vérifier que le document courant dispose bien de ce fichier puis il procède à sa lecture.

    Nous utilisons pour cela le service com.sun.star.xml.sax.Parser.[3] associé à un listener com.sun.star.xml.sax.XDocumentHandler[4].

    Code

    En LibreOffice Basic:

    Option Explicit
    
    ' This library is Copyright (C) 2012 Pierre-Yves Samyn, except otherwise indicated
    ' Purpose: Frame the selection or create an empty frame if no selection
    
    ' This program is free software: you can redistribute it and/or modify
    ' it under the terms of the GNU General Public License as published by
    ' the Free Software Foundation, either version 3 of the License, or
    ' (at your option) any later version.
    ' This program is distributed in the hope that it will be useful,
    ' but WITHOUT ANY WARRANTY; without even the implied warranty of
    ' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    ' GNU General Public License for more details.
    ' You should have received a copy of the GNU General Public License
    ' along with this program.  If not, see <http://www.gnu.org/licenses/>.
     
    Dim oDoc As Object
    Dim oDocHandler As Object
    Dim oTableName As String
    
    
    ' Procedure principale
    
    ' Contexte :  document Writer
    ' Objet    :  repérer les tableaux créés par lien DDE
    ' Fonction :  insérer un commentaire comprenant la source (Url classeur par ex.) et la plage
    
    ' Source pour l'utilisation UNO's XML sax parser via the API :
    ' http://www.oooforum.org/forum/viewtopic.phtml?t=4907
    
    Sub Comment_DDE_Table()
    
        Dim oContent As Object
        Dim oFlux As Object
        Dim oSaxParser As Object
        Dim oDocEventsHandler As Object
        Dim oInputSource As Object
    
        oDoc = ThisComponent
    
        ' Ne travaille que sur les documents texte...
        If oDoc.supportsService("com.sun.star.text.TextDocument") Or _
            oDoc.supportsService("com.sun.star.text.GlobalDocument") Then
    
            ' On veut lire le content.xml, donc verifie que thiscomponent fait reference à un objet disposant de ce fichier
            If oDoc.DocumentStorage.HasByName("content.xml") Then
            
                ' Test si le document a été modifié : on va lire le content.xml donc on demande
    ' l'enregistrement pour être sûr de travailler sur le contenu mis à jour
                If oDoc.ismodified Then
                    MsgBox "Le document doit être enregistré!", 64, "Comment_DDE_Table()"
                Else 
                    oContent = oDoc.DocumentStorage.GetByName("content.xml")
                    oFlux = oContent.GetInputStream()   
                            
                    ' Creation Sax parser Xml
                    oSaxParser = createUnoService( "com.sun.star.xml.sax.Parser" )
                    
                    ' Creation gestionnaire evenements
                    ' Les procedures associees reprennent le nom donné ici suivi du nom des
                    ' evenements de l'interface cf. :
                    ' http://api.libreoffice.org/common/ref/com/sun/star/xml/sax/XDocumentHandler.html
                    oDocHandler = CreateUnoListener( "DocHandler_", "com.sun.star.xml.sax.XDocumentHandler" )
                    oSaxParser.setDocumentHandler( oDocHandler )
                       
                    ' Creation de la structure cf.:
                    ' http://api.libreoffice.org/common/ref/com/sun/star/xml/sax/InputSource.html
    
                    oInputSource = createUnoStruct( "com.sun.star.xml.sax.InputSource" )
                    oInputSource.aInputStream = oFlux
            
                    ' Demarrer l'analyse syntaxique (parser) qui va lire le content.xml
                    ' Les méthodes - cf. procedures DocHandler_ - seront appelées selon l'evenement correspondant
                    oSaxParser.parseStream( oInputSource )
                    oFlux.closeInput()
                            
                    MsgBox "Fin du traitement" , 64, "Comment_DDE_Table()"
                End If
            Else
                MsgBox "Ne peut travailler sur ce type de document (doit etre odt Writer)" , 64, "Comment_DDE_Table()"
            End If
    
            Else
            MsgBox "Ne peut travailler sur ce type de document (doit etre odt Writer)" , 64, "Comment_DDE_Table()"
        End If
    
    End Sub ' Comment_DDE_Table
    
    
    ' Ci-dessous les procedures du listener, correspondants aux evenements :
    ' http://api.libreoffice.org/common/ref/com/sun/star/xml/sax/XDocumentHandler.html
    
    Sub DocHandler_startDocument()
    End Sub
    
    Sub DocHandler_endDocument()
    End Sub
    
    Sub DocHandler_startElement( cName As String, oAttributes As com.sun.star.xml.sax.XAttributeList )
    
        Dim oTable As Object
        Dim oCursor As Object
        Dim oComment As Object
    
        Dim oDateHour As New com.sun.star.util.DateTime
    
        ' Si l'element est un tableau, memorisation de son nom
        If cName = "table:table" Then
            oTableName = oAttributes.getValueByName("table:name")
        End If   
    
        ' Cf. OASIS Open Document Format for Office Applications :
        ' http://docs.oasis-open.org/office/v1.2/os/OpenDocument-v1.2-os.html
        ' The DDE connection data of tables is contained in an <office:dde-source> element. 
        ' The usage of this element differs between spreadsheet and text document tables. 
        ' For text document tables, the element is contained within the table's <table:table> 
        ' element directly.
        ' Donc test si tableau lien DDE...
        If cName = "office:dde-source" Then
    
            ' Acces au tableau
            oTable = oDoc.TextTables.getByName(oTableName)
    
            '  Creation d'un curseur dans la premiere cellule du tableau
            oCursor = oTable.getCellByPosition(0, 0).createTextCursor
    
            ' Creation d'un commentaire
            oComment = oDoc.createInstance("com.sun.star.text.textfield.Annotation")
    
            '  Recupere la date et heure courante
            With oDateHour
                .Minutes = minute(now)
                .Hours = hour(now)
                .Day = day(now)
                .Month = month(now)
                .Year = year(now)
            End With
             
            ' Renseigne le commentaire avec la source DDE et la plage
            With oComment
                .Author = "Source: DDE link"
                .Content = oAttributes.getValueByName("office:dde-item") & chr(13) &_
                    oAttributes.getValueByName("office:dde-topic")
                .DateTimeValue = oDateHour
            End With
    
            ' Inserer effectivement le commentaire dans la cellle
            oComment.attach(oCursor.start)
        End If
    
    End Sub ' DocHandler_startElement
    
    
    Sub DocHandler_endElement( cName As String )
    End Sub
    
    Sub DocHandler_characters( cChars As String )
    End Sub
    
    Sub DocHandler_ignorableWhitespace( cWhitespace As String )
    End Sub
    
    Sub DocHandler_processingInstruction( cTarget As String, cData As String )
    End Sub
    
    Sub DocHandler_setDocumentLocator( oLocator As com.sun.star.xml.sax.XLocator )
    End Sub

    Notes

    1. DDE : "Dynamic Data Exchange", échange dynamique de données. DDE permet de lier les objets par référence au fichier, mais non de les incorporer.
    2. Cf.la norme OASIS Open Document Format for Office Applications l'usage de cet élément diffère entre le tableur et le traitement de textes. Pour les documents texte, l'élément est contenu directement à l'intérieur de l'élément <table:table>.
    3. Voir la documentation de l'API
    4. Voir la documentation de l'API