From 6b377719c10d5ab3343fd5221f99a4a21008e25a Mon Sep 17 00:00:00 2001 From: Sébastien Dailly Date: Thu, 14 Mar 2024 08:26:58 +0100 Subject: Initial commit --- readme.rst | 668 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 668 insertions(+) create mode 100644 readme.rst (limited to 'readme.rst') diff --git a/readme.rst b/readme.rst new file mode 100644 index 0000000..ab7b5df --- /dev/null +++ b/readme.rst @@ -0,0 +1,668 @@ +.. -*- mode: rst -*- +.. -*- coding: utf-8 -*- + +.. role:: toml(code) + :language: toml + +.. default-role:: toml + +============================================ +Outil de construction des fichiers d’imports +============================================ + +.. raw:: html + + + + + + +.. contents:: + :depth: 2 + +L’application permet de construire un fichier d’import à partir d’une série de +règles indiquant comment assembler les données. L’outil est capable d’aller +chercher les données dans plusieurs fichiers différents et appliquer des règles +simples pour mettre en forme le résultat. + +Invocation +========== + +--conf + + Le chemin vers le fichier de configuration. Cet argument est obligatoire. + +--print-conf + + Écrit la configuration chargée sur la sortie courante et selon la dernière + syntaxe de l’application. + +.. --no-bom +.. +.. Ne pas insérer un BOM_ dans le fichier CSV. Cet indicateur permet +.. d’informer Excel que le fichier CSV est en UTF-8, ce qui devrait être le +.. cas. Dans le cas où cette chaine de caractère pose problème, il est +.. possible de désactiver ce mécanisme. +.. +.. .. _BOM: https://fr.wikipedia.org/wiki/Indicateur_d%27ordre_des_octets + +Sortie +====== + +L’exécution du programme va générer trois fichiers, qui sont tous basés sur le +nom du fichier de configuration : + + +sortie.csv + + Il s’agit du fichier produit par l’application, et dont les colonnes sont + celles définies dans le fichier de configuration. + +sortie.sqlite + + Il s’agit d’une base de données reprenant toutes les données utilisées pour + construire le résultat. + +sortie_error.csv + + Il s’agit d’un fichier CSV généré si l’application rencontre des erreurs. + Celles-ci concernent les liaisons entre les différents fichiers qui n’ont + pas pu être réalisées + +Fichier de configuration +======================== + +Les informations générales +-------------------------- + +version + Il s’agit de la version de la syntaxe du fichier de configuration. Valeur + attendue : `1` + +source + La clef `source` indique quel est le fichier source : pour chaque ligne + présente dans ce fichier, une ligne sera générée en sortie. + + :file: le fichier à charger + :tab: optionnellement l’onglet concerné + :name: le nom sous lequel le fichier sera associé. + + + +Le chargement des dépendances +----------------------------- + +La recherche de valeurs dans d’autres fichiers Excel nécessite de déclarer les +fichiers à charger. La liste `externals` décrit tous les fichiers qui doivent +être chargés, et comment les données doivent être associée avec le fichier +source. + +.. code:: toml + + [externals.target] + intern_key = ":source.A" + extern_key = ":A" + file = "financial.xlsx" + allow_missing = false + +Les clefs suivantes sont nécessaires pour lier les données venant d’un autre +fichier : + +intern_key + Il s’agit de la colonne servant à faire la liaison dans la source. +file + Le fichier à charger +tab + optionnellement l’onglet concerné +extern_key + Il s’agit de la colonne servant à faire la liaison dans le fichier devant + être lié. La clef doit doit etre unique, l’application supprimera les + doublons pour ne garder qu’une seule valeur par clef. Il n’est donc pas + possible de faire un produit cartésien. +allow_missing + Cette clef optionnelle indique s’il faut autoriser les valeurs manquantes + lors dans une liaison. Déclarer `allow_missing` va également autoriser les + doublons sur les valeurs de clef. + +Une fois la dépendance vers un fichier externe déclaré, il est possible +d’utiliser les colonnes de ce fichier en les référençant directement. Cela +revient à faire un `RECHERCHEV` dans Excel à chaque fois. + +Il est possible d’utiliser une référence externe dans une autre source externe, +afin de construire des chemins sur plusieurs niveaux : + +.. code:: toml + + [externals.acheteur_annuaire] + intern_key = ":I" + extern_key = ":A" + file = "ANNUAIRE.xlsx" + + [externals.acheteur_societe] + intern_key = ":acheteur_annuaire.BJ" + extern_key = ":A" + file = "SOCIETES.xlsx" + + +Les valeurs présentes dans ces colonnes sont pré-traitées pour éviter les +erreurs générales lors des imports : les espaces en fin de texte sont +supprimés et le texte est passé en capitale. + +Définition des colonnes +----------------------- + +Une fois les différents fichiers chargés, il est possible de construire le +schéma du fichier de sortie en listant toutes les colonnes à générer : + +.. code:: toml + + """function + ( :A ^ '_' ^ :target.E + , :E + )""" + +======================= ======================================= ====================== +Type d’élément Interprétation Exemple +======================= ======================================= ====================== +Texte Un texte libre. Celui-ci doit être `'_'` + placé entre quote (`'` ou `"`). + +Un nombre La valeur correspondante `1234` + +Une référence Une colonne. Celle-ci peut être définie `:A` + via un fichier externe ou directement + par rapport au fichier source. `:target.E` + + Elle ne doit pas être placée entre + quote. Le nom du fichier peut être omis + (et est alors considéré comme étant le + fichier source) + +Opérateur `^` Concaténation d’éléments `"contract_" ^ :A` + +Opérateur mathématique `+` `-` `/` `=` `<>` `:Q + 1` + `:A = 2000` + +Fonction Applique la fonction sur les `nvl(:I, :N, "Defaut")` + éléments donnés. La fonction ne doit + pas être placée entre quote `trim(:N)` + + La fonction prend en paramètre + les arguments sous forme de `trim("prefixe_" ^ :C)` + liste, séparés par des virgules. + +======================= ======================================= ====================== + + +.. class:: collapse + + :Operator: `+` | `-` | `<` | `>` | `/` | `^` + :Equality: `=` | `<>` + + :Reference: + | `:`\ COLUMN + | `:`\ TABLE\ `.`\ COLUMN + + :Expression: + | LITERAL + | NUMERIC + | *Reference* + | *Expression* *Operator* *Expression* + | *Expression* *Equality* *Expression* + | *Expression* *Equality* *Group* + | IDENTIFIER `(` *Expression*\ + `)` + | IDENTIFIER `(` *Expression*\ , *Group*, *Group* `)` + | IDENTIFIER `(` *Group*, *Group* `)` + :Group: + | `[` Expression* `]` + +Tri des données +--------------- + +.. code:: toml + + sort = [ + ":mouvements.B", + ":lib_titres.B", + "date('%d/%m/%Y', :mouvements.C)", + ":A", + ] + +Les données peuvent être triées à l’aide de la section `sort`. Il est possible +de définir plusieurs critères de tri qui seront traités par ordre de priorité. +Des fonctions peuvent également être utilisées (dans l’exemple ci-dessus, nous +avons un tri sur des dates au format dd/mm/yyyy, si la donnée n’était pas +convertie en date, elle serait triée sur le jour avant d’être triée sur +l’année). + +Filtrer les données +------------------- + +.. code:: toml + + filters = [ + ":t_operation.B <> ['Cession', 'Restitution', 'Prêt de titres']", + ":lib_titres.B <> 0", + ":societe.A <> 0", + ] + +Un filtre peut être mis en place pour ne conserver que les lignes souhaitées. +Les conditions doivent être toutes validées pour que la ligne soit retenue. + +.. note:: + + Il est possible de mettre une fonction de groupe dans les filtres, pour + n’extraire par exemple que la première ligne d’une série. Toutefois, cette + fonctionnalité est encore expérimentale. L’application peut lever une + erreur si la fonction est trop complexe pour etre interprétée. + + Si une fonction de groupe est présente, l’application ordonnera les + évaluations selon l’ordre suivant : + + 1. En premier lieu tous les filtres *simples* pour ne conserver que les + lignes correspondantes. + 2. Ensuite seulement la fonction de groupe présente dans la section `filter` + +Exemple complet +=============== + +Cet exemple (issu d’un cas réel), crée un fichier des personnes morales à +partir de plusieurs tables. + +- Le fichier source donne des identifiants pour les formes juridiques (qu’il + faut donc aller dans une table à part) et les devises + +- le numéro de TVA communautaire doit être chargé dans la table + immatriculation, la colonne A doit correspondre au code de la société, et la + colonne D doit avoir la valeur `4` + +- l’adresse est reconstituée en concaténant cinq colonnes depuis la table + annuaire. + +- la ville et le code postal peuvent être présent sur deux tables : la table + annuaire si l’adresse n’a pas été modifiée depuis la saisie initiale de la + fiche, ou la source qui contient la dernière valeur, mais peut être nulle si + celle-ci n’a pas été modifiée… + +.. code:: toml + + version = 1 + + [source] + file = "20220222_SOCIETES.xlsx" + name = "société" + + # Des commentaires peuvent etre ajoutés tout au long du fichier. + # Ici la table actif permet de faire une correspondance entre les valeurs + # du client et nos valeurs : + # 1 -> Actif + # 0 -> Inactif + [externals.actifs] + intern_key = ":E" + file = "actifs.xlsx" + extern_key = ":A" + allow_missing = false + + [externals.legalform] + intern_key = ":J" + file = "mapping.xlsx" + tab = 2 + extern_key = ":A" + allow_missing = false + + [externals.currency] + intern_key = ":BF" + file = "mapping.xlsx" + tab = 6 + extern_key = ":A" + allow_missing = false + + # le fichier annuaire contient des informations supplémentaires + [externals.annuaire] + intern_key = ":A" + file = "20220222_ANNUAIRE.xlsx" + extern_key = ":BJ" + allow_missing = false + + # La table des immatriculations. + # Seules les lignes avec la colonne D = 4 nous intéressent + [externals.immat] + intern_key = ":A ^ '_4'" + file = "20220222_SO_IMMATRICULATION.xlsx" + extern_key = ":B ^ '_' ^ :D" + allow_missing = true + + [sheet] + columns = [ + "'companyDirectory_' ^ :A", + ":G", + "'internalExternalList_Internal'", + ":actifs.B", + ":H", + ":I", + "", + ":legalform.S", + ":annuaire.I", + ":T", + ":BP", + ":currency.D", + "", + ":annuaire.CC", + ":CQ", + ":CO", + ":immat.C", + # Utilise la fonction join pour assembler les éléments + # De cette manière, si l’un des éléments est vide, il n’y aura pas de + # double espace (' ') dans le résultat + "join(' ', :annuaire.CP, :annuaire.CQ, :annuaire.CR, :annuaire.L, :annuaire.M)", + "nvl(:CM, :annuaire.N)", + "nvl(:CS, :annuaire.AB)", ":CR" + ] + filters = [] + sort = [] + uniq = [] + +Comparaison des valeurs +======================= + +Comparaison par groupe +---------------------- + +.. code:: toml + + ":t_operation.B <> ['Cession', 'Restitution', 'Prêt de titres']" + +Les opérateurs de comparaison `=` et `<>` peuvent accepter un groupe de valeur +plutot qu’une valeur unique. Dans ce cas, la condition est vraie si l’une des +valeurs est présente. + +Le cas des cellules vides +------------------------- + +.. code:: toml + + ":B > 0", + "'prefix_' ^ :B", + +Les cellules vides peuvent apparaitres dans des colonnes où l’on s’attend à +trouver des champs texte, ou des nombres. L’application va traiter ces valeurs +vides en fonction du contexte et les considérer comme `0` si elles sont +associées avec un numérique, ou `""` si elles sont associées à un texte. + + +Fonctions disponibles +===================== + +Liste non exhaustive. + +`if` + Choisi la valeur de la cellule en fonction d’une condition : + + .. code:: toml + + """if( + :E = 1 + , 'Vrai' + , 'Faux' + )""" + +`nvl` + Sélectionne la première valeur non nulle de la liste + + .. code:: toml + + "nvl(:I, :N, 'Defaut')" + +Fonctions sur les nombres +------------------------- + +`abs` + Renvoie la valeur absolue d’un nombre. + +`int` + Transforme une valeur en nombre entier. + +Fonctions sur le texte +---------------------- + +`join` + .. code:: toml + + "join('-', :A, :target.E, :B)" + + Concatène tous les champs en utilisant le premier paramètre comme + séparateur. Les valeurs vides sont ignorées, et dans ce cas le séparateur + n’est pas répété. + +`match` + Extrait un motif sur la base d’une `expression régulière`_. + + .. code:: toml + + "match('hello ([A-Za-z]+)', ':B')" + +.. _expression régulière: + https://fr.wikipedia.org/wiki/Expression_r%C3%A9guli%C3%A8re#Op%C3%A9rateurs + +`substring` + Extrait une sous-chaine en indiquant la position et la longueur. + + .. code:: toml + + "substring(:H, 1, 5)" + +`trim` + Supprime les espaces en début et fin de chaine + + .. code:: toml + + "trim(:C)" + +`upper` + Passe le texte en capitale + + .. code:: toml + + "upper(:A)" + +Fonctions sur les dates +----------------------- + +Normalement, les dates sont représentées dans Excel comme un nombre. On peut +donc utiliser les opérations standard (addition…) sans avoir à se poser de +question sur leur résultat. Toutefois, il est parfois nécessaire de faire des +opérations avancées. + + +`date` + Converti une date depuis le format texte. Le résultat de la fonction est le + nombre de jours écoulés depuis le 31 décembre 1899 (`1` correspond au 1er + janvier 1900). Cela correspond à la manière dont Excel enregistre une + valeur de type date. + + .. code:: toml + + "date('%d/%m/%Y', :B)" + + +`year` + Extrait l’année (sur 4 chiffres) à partir d’une date. Si la date est donnée + directement, il vaut mieux utiliser `substring` qui est plus simple + d’accès. `year` devient utile s’il y a des calculs associés : + + .. code:: toml + + "year( date('%d/%m/%Y', :M) + date('%d/%m/%Y', '31/12/1999') )", + + +Les fonctions de groupes +------------------------ + +Les fonctions suivantes permettent de grouper les données ou de les mettre en +correspondance avec d’autres lignes du fichier. + +Elles prennent se basent sur deux paramètres supplémentaires : + +1. le premier étant les colonnes à identifier pour faire le regroupement, +2. le second étant l’ordre dans lequel les lignes doivent être triées. + + `counter([regroupement, …],[tri, …])` + + Le tri est ignoré si le regroupement est omi. + + +`counter` + Crée un compteur qui s’incrémente tant que les lignes sont identiques. + + L’exemple suivant va remettre le compteur à `1` dès que la société ou le + titre change, et utilisera la date pour ordonner les valeurs dans ce + groupe. + + .. code:: toml + + """counter( + [:societe.H, :lib_titres.B], + [date('%d/%m/%Y', :mouvements.C), :A] + )""" + + + La fonction peut également être utilisée pour ne conserver que les lignes + uniques au sein d’une plage donnée (via un post-traitement où l’on ne garde + que les valeurs à `1`) + + .. code:: toml + + "counter([:C], [:A]) = 1" + + Il est possible de construire plusieurs compteurs sur des groupes et des + tris différents au sein d’un même fichier. + + Si le critère de tri n’est pas donné, l’application va compter le nombre + d’éléments pour chaque groupe: toutes les cellules auront le même résultat. + +`previous` + La fonction `previous` permet d’aller chercher l’élément précédent dans les + données. + + En fonction du critère de regroupement, la valeur renverra vide (si l’on + est sur groupe différent), et la valeur précédente sera recherchée en + fonction du critère de tri donné. + + `previous(expression, [regroupement, …], [tri, …])` + + .. code:: toml + + """previous( + :ths.G, + [:socs.EB, :socs.L, :ths.E], + [:ths.H])""" + +`sum` + La fonction `sum` permet de calculer la somme d’une colonne donnée sur un + critère de regroupement. + + Si le critère de tri n’est pas donné, l’application va calculer la somme + totale en fonction du critère de regroupement : toutes les cellules auront + le même résultat. + + `sum(expression, [regroupement, …], [])` + + .. code:: toml + + """sum( + :shares.K, + [:shares.A, :shares:D], + [])""" + + Au contraire, si un tri est donné, l’application va accumuler la somme tout + au long des valeurs rencontrées, et selon l’ordre du tri. + +`min` + La fonction `min` permet d’aller chercher le premier élément du groupe + (c’est à dire le plus petit selon l’ordre de tri) + + + `min(expression, [regroupement, …], [tri, …])` + + .. code:: toml + + """min( + :mouvements.C, + [:societe.A, :I], + [:mouvements.C])""" + + exemple d’utilisation : rechercher la première date d’achat. + +`max` + La fonction `max` permet d’aller chercher le dernier élément du groupe. + + `max(expression, [regroupement, …], [tri, …])` + -- cgit v1.2.3