Macros

From The Document Foundation Wiki
< Macros‎ | Writer
Jump to: navigation, search

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

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].

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 LibODoc as object, LibODocHandler as object, LibONomTable 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 CommenterTableauxDDE
'********************************************************************************

dim LibOContenu as object, LibOFlux as object
dim LibOSaxParser as object, LibODocEventsHandler as object, LibOInputSource  as object

LibODoc = ThisComponent

' Ne travaille que sur les documents texte...

if LibODoc.supportsService("com.sun.star.text.TextDocument") or _
        LibODoc.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 LibODoc.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 LibODoc.ismodified then
                        msgbox "Le document doit être enregistré", 64, "Commenter la source des tableaux DDE"
                else     
                        LibOContenu = LibODoc.DocumentStorage.GetByName("content.xml")
                
                        LibOFlux = LibOContenu.GetInputStream()   
                        
                   ' Creation Sax parser Xml 
                   LibOSaxParser = 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

                        LibODocHandler = CreateUnoListener( "DocHandler_", "com.sun.star.xml.sax.XDocumentHandler" )
                        LibOSaxParser.setDocumentHandler( LibODocHandler )
                   
' Creation de la structure cf. :
'http://api.libreoffice.org/common/ref/com/sun/star/xml/sax/InputSource.html

                        LibOInputSource = createUnoStruct( "com.sun.star.xml.sax.InputSource" )
                        LibOInputSource.aInputStream = LibOFlux
        
        ' Demarrer l'analyse syntaxique (parser) qui va lire le content.xml
        ' Les méthodes - cf. procedures DocHandler_ - seront appelées selon l'evenement correspondant
        
                        LibOSaxParser.parseStream( LibOInputSource )
                        LibOFlux.closeInput()
                        
                        msgbox "Fin du traitement" , 64, "Commenter la source des tableaux DDE"
                end if
        else
        msgbox "Ne peut travailler sur ce type de document" , 64, "Commenter la source des tableaux DDE"
        end if
else
        msgbox "Ne peut travailler sur ce type de document" , 64, "Commenter la source des tableaux DDE"
end if

end sub

' 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 LibOTable as object, LibOCurseur as object, LibOAnnot as object

dim LibODateHeure as new com.sun.star.util.DateTime

' Si l'element est un tableau, memorisation de son nom

if cName = "table:table" then
        LibONomTable = 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
        LibOTable = LibODoc.TextTables.getByName(LibONomTable)

' Creation d'un curseur dans la premiere cellule du tableau
        LibOCurseur = LibOTable.getCellByPosition(0, 0).createTextCursor

' Creation d'un commentaire
        LibOAnnot = LibODoc.createInstance("com.sun.star.text.textfield.Annotation")

' Recupere la date et heure courante        
        with LibODateHeure
                .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 LibOAnnot
                .Author = "Source : Lien DDE"
                .Content = oAttributes.getValueByName("office:dde-item") & chr(13) &_
                        oAttributes.getValueByName("office:dde-topic")
                .DateTimeValue = LibODateHeure
        end with

' Inserer effectivement le commentaire dans la cellle       
        LibOAnnot.attach(LibOCurseur.start)
end if

End Sub

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