variables communes à plusieurs documents

Bonjour

Voici une nouvelle question envoyée à l'aide du formulaire de demande d'aide (http://fr.libreoffice.org/get-help/poser-une-question/).
Si vous répondez, merci de penser à utiliser la fonction "répondre à tous" de votre logiciel de courrier électronique de façon que le demandeur reçoive une copie de votre réponse.

Email:: gestion.amiante37@gmail.com
Sujet:: variables communes à plusieurs documents
OS:: Linux
Version:: 5.1.x
Question:: Bonjour,
nous rédigeons des dossiers composés de plusieurs documents libreoffice de type texte ou calc et il nous serait pratique de pouvoir créer des variables (Champs, Variables, définir une variable) accessible pour l'ensemble des documents du dossier. Est ce possible ?

Bonjour,

nous rédigeons des dossiers composés de plusieurs documents
libreoffice de type texte ou calc et il nous serait pratique de
pouvoir créer des variables (Champs, Variables, définir une variable)
accessible pour l'ensemble des documents du dossier. Est ce possible
?

Vous ne précisez pas l'étendue du besoin : partager les seules déclarations ou aussi les contenus des variables dans l'état où elles se trouvent après utilisation dans un document ?

Je vois plusieurs solutions.

1. Déclarez-les comme globales

Global MaVar As String

Une variable (ou constante) globale est disponible de façon... globale.

Les variables /!\ et leurs contenus /!\ sont alors communs pendant toute la session.

Restriction : (danger) si seules les déclarations vous intéressent, alors il faut vous assurer, à l'exécution d'un nouveau document, que le contenu de chaque variable est cohérent.

Restriction : fonctionne pour autant qu'on ne referme pas la session LibreOffice pour ouvrir un autre document.

2. Créez une bibliothèque dédiée dans Mes macros (voire dans Macros LibreOffice mais là il faudra les installer sous un compte d'administration)

Dans cette bibliothèque, créez un/plusieurs modules dans lesquels vous placez les déclarations qui vont bien. Il vous suffit ensuite d'ouvrir cette bibliothèque au lancement de vos outils pour accéder à son contenu.

Je préfère cette 2e méthode mais elle implique d'organiser les développements et la distribution des documents sur les postes des utilisateurs (p.ex. une macro d'installation pour assurer la cohérence sur chaque poste).

Restriction : si vous voulez partager non seulement les déclarations des variables mais aussi leurs contenus, il faudra trouver un moyen de mémoriser ces contenus d'une session à l'autre.

Si vous répondez, merci de penser à utiliser la fonction "répondre à
tous" de votre logiciel de courrier électronique de façon que la liste
reçoive une copie de votre réponse.

Bien cordialement,

Bonjour,

(message déjà envoyé ce matin mais qui ne semble pas avoir été
réellement transmis)

nous rédigeons des dossiers composés de plusieurs documents
libreoffice de type texte ou calc et il nous serait pratique de
pouvoir créer des variables (Champs, Variables, définir une variable)
accessible pour l'ensemble des documents du dossier. Est ce possible
?

Vous ne précisez pas l'étendue du besoin : partager les seules
déclarations ou aussi les contenus des variables dans l'état où elles se
trouvent après utilisation dans un document ?

Je vois plusieurs solutions.

1. Déclarez-les comme globales

Global MaVar As String

Une variable (ou constante) globale est disponible de façon... globale.

Les variables /!\ et leurs contenus /!\ sont alors communs pendant toute
la session.

Restriction : (danger) si seules les déclarations vous intéressent,
alors il faut vous assurer, à l'exécution d'un nouveau document, que le
contenu de chaque variable est cohérent.

Restriction : fonctionne pour autant qu'on ne referme pas la session
LibreOffice pour ouvrir un autre document.

2. Créez une bibliothèque dédiée dans Mes macros (voire dans Macros
LibreOffice mais là il faudra les installer sous un compte d'administration)

Dans cette bibliothèque, créez un/plusieurs modules dans lesquels vous
placez les déclarations qui vont bien. Il vous suffit ensuite d'ouvrir
cette bibliothèque au lancement de vos outils pour accéder à son contenu.

Je préfère cette 2e méthode mais elle implique d'organiser les
développements et la distribution des documents sur les postes des
utilisateurs (p.ex. une macro d'installation pour assurer la cohérence
sur chaque poste).

Restriction : si vous voulez partager non seulement les déclarations des
variables mais aussi leurs contenus, il faudra trouver un moyen de
mémoriser ces contenus d'une session à l'autre.

Si vous répondez, merci de penser à utiliser la fonction "répondre à
tous" de votre logiciel de courrier électronique de façon que la liste
reçoive une copie de votre réponse.

Bien cordialement,

Bonjour,
merci pour votre réponse. Celle ci sous entends d'utiliser la programmation
dans libreoffice.
Dans ma question, j'ai précisé la manière de créer les variables via le
menu Champs, Variables, définir une variable, dans Writer, et je souhaite
ne pas avoir à programmer, simplement déclarer une variable.
Un exemple :
dans le document 1, crée à partir d'un modèle contenant une variable
"maitredouvrage" et une variable "adrMO", je définie la valeur de
"maitredouvrage à "M Duchemole", et celle de "adrMO" à "Av Gen de Gaulle
Paris" et je souhaite que dans le document 2 , créer à partir d'un autre
modèle qui contient aussi ces variables, les voir prendre pour valeur "M
Duchemole" et "Av Gen de Gaule Paris".
Si cela n'est pas possible sans programmer, mais possible en programmant,
je suis aussi preneur ! (en langage libreoffice ou python).

Cordialement.

Belle journée.

François BRUYANT - Gestion commerciale et financière - 02 47 58 94 55
AMIANTE 37 - 9 rue des Cordeliers 37220 L’île Bouchard.

Bonjour,
Une autre possibilité, insérer des champs d'une Base de données dans la quelle ont été entrées les coordonnées des Maitres d'ouvrage.
Documents 1, 2 etc sont connectés à cette Base de données.
Pour afficher l'enregistrement d'un chantier particulier, faire Ctrl+F4 pour visualiser la Table, sélectionner l'enregistrement puis imprimer (après avoir éventuellement cliqué sur l"icône Données dans les champs si on veut être sûr de sa sélection).

Que je comprenne bien. Vous voulez que le document B créé à partir d'un
modèle spécifique contienne les mêmes informations que le document A
créé à partir d'un autre modèle et qu'il se mette à jour en fonction des
informations du document A c'est cela ?

Question intéressante. Je ne vois pas trop comment faire ça
automatiquement en passant par les champs. Si on insère un lien DDE, ce
qui est la façon la plus simple de procéder, il faudra actualiser les
liens vers le document "source" (le ressaisir en double-cliquant sur le
lien et en faisant Éditer pour indiquer un autre fichier source). À
moins que vous ne modifiez le contenu des champs sur le modèle (ou le
document source lié).

L'une ou l'autre solution pourrait convenir, en fonction de vos besoins,
ou pas du tout. Désolée, la programmation, j'en suis aux balbutiements
(premières pages pages du livre de Marcelly et Godart Programmation
OpenOffice.org et LibreOffice pour tout dire).

Bonjour,
Une autre possibilité, insérer des champs d'une Base de données dans la quelle ont été entrées les coordonnées des Maitres d'ouvrage.
Documents 1, 2 etc sont connectés à cette Base de données.
Pour afficher l'enregistrement d'un chantier particulier, faire Ctrl+F4 pour visualiser la Table, sélectionner l'enregistrement puis imprimer (après avoir éventuellement cliqué sur l"icône Données dans les champs si on veut être sûr de sa sélection).

Bonsoir,

(j'ai un pb avec les listes : je reçois les messages avec un "certain" retard...)

Bonjour,
Une autre possibilité, insérer des champs d'une Base de données dans la
quelle ont été entrées les coordonnées des Maitres d'ouvrage.
Documents 1, 2 etc sont connectés à cette Base de données.
Pour afficher l'enregistrement d'un chantier particulier, faire Ctrl+F4
pour visualiser la Table, sélectionner l'enregistrement puis imprimer
(après avoir éventuellement cliqué sur l"icône Données dans les champs
si on veut être sûr de sa sélection).

... et je n'ai toujours pas reçu votre message cité par Jean-Mi...

Bonjour,
merci pour votre réponse. Celle ci sous entends d'utiliser la programmation
dans libreoffice.
Dans ma question, j'ai précisé la manière de créer les variables via le
menu Champs, Variables, définir une variable, dans Writer, et je souhaite
ne pas avoir à programmer, simplement déclarer une variable.
Un exemple :
dans le document 1, crée à partir d'un modèle contenant une variable
"maitredouvrage" et une variable "adrMO", je définie la valeur de
"maitredouvrage à "M Duchemole", et celle de "adrMO" à "Av Gen de Gaulle
Paris" et je souhaite que dans le document 2 , créer à partir d'un autre
modèle qui contient aussi ces variables, les voir prendre pour valeur "M
Duchemole" et "Av Gen de Gaule Paris".
Si cela n'est pas possible sans programmer, mais possible en programmant,
je suis aussi preneur ! (en langage libreoffice ou python).

Argh ! Je n'avais pas bien lu /o\

En dehors de la proposition de Jean-Michel, je ne vois qu'une macro pour injecter les champs d'utilisateur (c'est comme ça que ça s'appelle) d'un document vers un autre.

Voici les primitives que j'utilise (la doc est dans le code) :

8< -----------------------------------------------------

Public Const MFLD_USERSERVICE = "com.sun.star.text.fieldmaster.User."
Public Const MFLD_USERINSTANCE = "com.sun.star.text.fieldmaster.User"

'masterfield type identifiers
Public Const MFLD_TYPEUSERID = ".User."

'------------------

Function ExportMasterFields(ByRef pTargetDoc As Object, Optional pSourceDoc As Object) As Boolean
'Exports user fields to some other Writer document.
'Input:
'-- pTargetDoc: the target Writer document
'-- pSourceDoc: (optional) the source document.
' Defaults to the current document.
'Output: True if the process went well, otherwise False

  Dim lo_MastersSrc As Object 'the masterfields container in the source document
  Dim l_MasterName As String 'the current masterfield name
  Dim l_Value As Variant 'the current masterfield value
  Dim l_OK As Boolean 'the process flag
  Dim i As Long
  
  l_OK = False
  If IsMissing(pSourceDoc) Then pSourceDoc = ThisComponent

  On Local Error Goto FuncEnd:

  lo_MastersSrc = pSourceDoc.TextFieldMasters
  For i = LBound(lo_MastersSrc.ElementNames()) To UBound(lo_MastersSrc.ElementNames())
    l_MasterName = lo_MastersSrc.ElementNames(i)
    'we just export users' masterfields (but not sequence fields)
    If IsMasterFieldUser(l_MasterName) Then
      'read the masterfield name in the source document
      l_MasterName = GetMasterFieldNameOnly(l_MasterName)
      'get its value
      l_Value = GetMasterFieldValue(l_MasterName, pSourceDoc)
      'create it within the target document
      CreateMasterField(l_MasterName, l_Value, pTargetDoc)
    End If
  Next
  l_OK = True
  
  FuncEnd:
  ExportMasterFields = l_OK
End Function 'ExportMasterFields

Function CreateMasterField(ByRef pFieldName As String, Optional pValue As Variant, Optional pDoc As Object) As Boolean
'Creates a user field (aka MasterField in a Writer document).
'Input:
'-- pFieldName: the master field name
'-- pValue: if provided, sets the initial value for the created master field.
'-- pDoc: the document in which the master field is to be created.
' If not specified, the current document is assumed.
'Output: True if the operation was successful otherwise False.

  Dim lo_Masters As Object 'the masterfields in the target document
  Dim lo_Master As Object 'a masterfield
  Dim l_OK As Boolean 'the process flag
  
  l_OK = False
  If IsMissing(pDoc) Then pDoc = ThisComponent

  On Local Error Goto ErrHandler
  lo_Masters = pDoc.TextFieldMasters
  If Not lo_Masters.hasByName(MFLD_USERSERVICE & pFieldName) Then
    lo_Master = pDoc.createInstance(MFLD_USERINSTANCE)
    lo_Master.Name = pFieldName
  End If
  
  If Not IsMissing(pValue) Then
    lo_Master = lo_Masters.getByName(MFLD_USERSERVICE & pFieldName)
    lo_Master.Content = pValue
  End If

  ErrHandler:
    l_OK = Not Err
  
  CreateMasterField = l_OK
End Function 'CreateMasterField

Function GetMasterFieldNameOnly(ByRef pMasterName As String) As String
'Returns the field name alone, as seen in the UI.
'Input:
'-- pMasterName: the full field name (incl. the MFLD_SERSERVICE part)
'Output: the name alone.

  Dim l_Name As String
  Dim l_arrParts() As String
  
  l_Name = ""
  'we look for the last part of the passed name (separator is a dot)
  l_arrParts = Split(pMasterName, ".")
  l_Name = l_arrParts(UBound(l_arrParts))
  
  GetMasterFieldNameOnly = l_Name
End Function 'GetMasterFieldNameOnly

Function GetMasterFieldValue(ByRef pFieldName As String, Optional pDoc As Object) As Variant
'returns the value of a master field or Nothing if the field is not found.
'Input:
'-- pFieldName: the master field name
'-- pDoc: the document in which the master field is searched.
' If not specified, the current document is assumed.
'Output: the value of the field or Nothing if not found.

  Dim lo_Masters As Object
  Dim lo_Master As Object
  Dim l_Result As Variant

  l_Result = Nothing
  If IsMissing(pDoc) Then pDoc = ThisComponent
  
  lo_Masters = pDoc.TextFieldMasters
  lo_Master = lo_Masters.getByName(MFLD_USERSERVICE & pFieldName)
  IF Not IsNull(lo_Master) Then
    l_Result = lo_Master.Content
  End If

  GetUserFieldValue = l_Result
End Function 'GetMasterFieldValue

Function IsMasterFieldUser(ByRef pMasterFieldName As String) As Boolean
'Checks whether a masterfield is a user one or not.
'Input:
'-- pMasterFieldName: the masterfield name to check
'Output: True is its name contents a ".User." part, otherwise False

  Dim l_IsUser As Boolean
  
  l_IsUser = (InStr(pMasterFieldName, MFLD_TYPEUSERID) > 0) 'other possibility is: "SetExpression"

  IsMasterFieldUser = l_IsUser
End Function 'IsMasterFieldUser

------------------------------------------------------------- >8

La fonction à appeler est ExportMasterFields() en lui passant, a minima, l'objet document cible (par défaut le document source est le document courant).

Les autres sous-programmes sont appelés par ExportMasterFields().

Attention : ce code n'est pas complètement à l'épreuve des balles... Je sais 2-3 endroits où des vérifications seraient utiles mais pas le temps de les ajouter pour le moment.

Conseil de nommage des champs d'utilisateur à exporter : vous pouvez améliorer/sécuriser les choses en adoptant une convention de nommage de vos champs d'utilisateur, en les préfixant de façon uniforme. De cette manière, vous pourriez ne recopier que ceux qui vous intéressent en vérifiant les préfixes lors de l'export (-> modifiez ExportMasterFields() en conséquence).

Bien cordialement,

Une autre possibilité : les sections liées.

Dans le premier document ("source"), créer une section qui contient les variables "utiles" (cette section peut être masquée).

Créer, dans chacun des documents suivants, une section (masquée et) liée
à la précédente qui, partant, répercute les infos du document "source", donc incorpore les variables qui y sont déclarées.

Je viens de tester et ça fonctionne :slight_smile:

-> Attention ! J'ai découvert que, dans cette situation, il faut utiliser des *Variables* et non pas des champs d'utilisateur (la mise à jour de ces derniers ne se fait pas entre documents).

Limitation : ce processus implique qu'il y a un ordre dans la gestion des différents documents.

Si vous répondez, merci de penser à utiliser la fonction "répondre à
tous" de votre logiciel de courrier électronique de façon que la liste
reçoive une copie de votre réponse.

Bien cordialement,

Grand merci à tous.
Je vais étudier ces macros et le langage macro par la même occasion ...

Belle journée.

François BRUYANT - Gestion commerciale et financière - 02 47 58 94 55
AMIANTE 37 - 9 rue des Cordeliers 37220 L’île Bouchard.

Hello Jean-François,

Moi, ce qui m'intéresserait est de savoir où tu vas pêcher tout ça ! Car, là, ça ne s'improvise plus…

:wink:

Thierry

Bonjour,

Un solution sans macros ?
ça sert à quoi que les documents maîtres se décarcassent :slight_smile:

Je crée un document sans texte avec tous les champs que je veux et je le
nomme "champs.odt" (que je place dans le dossier avec tous les docs qui
doivent hériter...)
Je crée un document maître (Fichier - nouveau - document maitre) - j'y
insère en premier mon document "champs.odt" et je l'enregistre dans le
dossier.

En utilisant ce document maitre,
Les champs sont ainsi "partagés" par tous les documents qui utilisent ce
document maitre. la seule contrainte étant qu'on doive utiliser ce document
maitre.
Les champs restent modifiables de manière simple (en utilisant la méthode
de Jean-François sur les sections masquées, on peut même les afficher
explicitement dans le document "champs.odt" avec leur description et les
masquer dans le document maître. ).
La seule étant qu'on doivent enregistrer sous pour ne pas effacer ce
"modèle" :wink: .

Yves

Bonjour Thierry,

Moi, ce qui m'intéresserait est de savoir où tu vas pêcher tout ça ! Car, là, ça ne s'improvise plus…

tout vient du besoin de réaliser, tout simplement. Au cas présent, j'ai développé un document qui transmet ses informations à un autre en utilisant les champs d'utilisateur. De cette façon ça évite à l'utilisateur de saisir 2 fois les mêmes données. J'ai donc écrit ces primitives dans ce but (je n'ai donné que le code des sous-programmes directement utiles à François). Mais dans mon cas l'enchaînement des deux documents est le fonctionnement standard.

<ma vie>
En fait, au fil de mes développements, je cherche toujours à factoriser, à généraliser et à abstraire. Je collecte les sous-programmes et classes ainsi réalisés (et à l'occasion j'en écris d'autres rattachés au domaine mais non utiles immédiatement) de façon à pouvoir les réutiliser dans d'autres contextes par la suite. J'ai donc maintenant un petite collection de bibliothèques de primitives (150 primitives et 3 classes) commencée il y a 4-5 ans et qui grossit un peu chaque jour... :slight_smile:
</ma vie>

En fait, j'ai beaucoup appris de cette manière-là (souvent en essayant de comprendre le code trouvé sur le web). C'est tout.

Amicalement,

Bonjour Jean-François,

A chaque fois que je lis ton code je retrouve ce que tu décris, clarté, structure, pertinence. D'où ma proposition que tu le publies, si ça entre dans ta conception des choses. Les routines que tu m'avais données pour mes AutoTextes ont bien demandé un petit coup de tournevis, mais c'était très simple à faire. Je dois d'ailleurs te les redonner, je le fais en MP.

A mon sens, ta librairie pourrait être au moins aussi utile que le travail des grands anciens, Marcelly et Pitoniak, en illustrant l'approche à utiliser pour étendre LO. Il n'y a sans doute pas grand chose à y ajouter si tout est du tonneau que j'ai pu voir, les routines sont auto-documentées, peut-être une brève introduction contextuelle par domaine…

Tu combles un manque dans le monde de LibreOffice, car tu ne restes pas à la surface du pilotage de la suite, mais tu donnes une vue claire de certains de ses arcanes. En tout cas pour moi ça complète parfaitement les ouvrages des deux pré-cités, partant d'un thème et approfondissant jusqu'à la racine.

<La mienne>
J'ai bossé quelque 25 ans comme consultant informatique dans une grande banque privée de Genève. J'y ai été développeur, architecte, support troisième niveau, standardisateur, nounou de développeurs, poisson-pilote, j'y ai entre autres introduit Delphi toujours utilisé aujourd'hui pour les projets stratégiques,...
J'ai surtout lu et maintenu des centaines de milliers de lignes de code écrites par les générations précédentes et parfois par la mienne (et c'était pas forcément mieux). Je ne crois pas exagérer. Je suis intervenu sur à peu près tout ce qui tournait dans la maison, dont une partie venait d'un système IBM des années 70… Avec cela je suis devenu bon juge de la qualité de ce que je vois.
</La mienne>

Donc, si j'affirme qu'il ne faut pas laisser perdre ce que tu produis, tu peux me faire confiance et les autres potentiellement intéressés aussi.

Il serait bon que la fondation s'en rende compte et t'approche pour te proposer quelque chose de concret, ne serait-ce qu'un hébergement dans un endroit intelligent du WiKi, par exemple si c'est pertinent. Ou mieux, quelque chose sur GitHub, qui permettrait de peaufiner les choses au fur et à mesure qu'elles seraient testées. Ne connaissant ni tes préférences, ni les usages dans le monde de LibreOffice je m'arrête là. Simplement je contribuerai volontiers si je peux être utile à ce travail.

Bonne fin de journée, à tout bientôt, et encore merci de nous faire bénéficier de ton boulot.

Thierry