{"id":12196,"date":"2024-01-02T02:34:18","date_gmt":"2024-01-02T01:34:18","guid":{"rendered":"https:\/\/www.auditsi.eu\/?p=12196"},"modified":"2024-08-11T16:08:01","modified_gmt":"2024-08-11T14:08:01","slug":"analyse-de-donnees-python-creer-un-fec-augmente","status":"publish","type":"post","link":"https:\/\/www.auditsi.eu\/?p=12196","title":{"rendered":"Analyse de donn\u00e9es &#038; Python : cr\u00e9er un FEC augment\u00e9"},"content":{"rendered":"<p style=\"text-align: justify;\">L&#8217;<strong>analyse de donn\u00e9es comptables<\/strong> contenues dans un Fichier des Ecritures Comptables (<strong>FEC<\/strong>) est une pratique de plus en plus commune. Dans ce cadre, le <strong>langage Python<\/strong> est un formidable outil parfaitement adapt\u00e9 pour <strong>nettoyer et manipuler les donn\u00e9es<\/strong>.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-12241\" src=\"https:\/\/www.auditsi.eu\/wp-content\/uploads\/2024\/01\/GCD-MASSE-SALARIALE.png\" alt=\"GCD MASSE SALARIALE\" width=\"1047\" height=\"445\" srcset=\"https:\/\/www.auditsi.eu\/wp-content\/uploads\/2024\/01\/GCD-MASSE-SALARIALE.png 1047w, https:\/\/www.auditsi.eu\/wp-content\/uploads\/2024\/01\/GCD-MASSE-SALARIALE-300x128.png 300w, https:\/\/www.auditsi.eu\/wp-content\/uploads\/2024\/01\/GCD-MASSE-SALARIALE-1024x435.png 1024w, https:\/\/www.auditsi.eu\/wp-content\/uploads\/2024\/01\/GCD-MASSE-SALARIALE-768x326.png 768w, https:\/\/www.auditsi.eu\/wp-content\/uploads\/2024\/01\/GCD-MASSE-SALARIALE-730x310.png 730w\" sizes=\"auto, (max-width: 1047px) 100vw, 1047px\" \/><\/p>\n<p style=\"text-align: justify;\">L&#8217;article qui suit sera illustr\u00e9 d&#8217;un exemple clef en main \u00e0 titre de d\u00e9monstration. Cet exemple est le script Python du <strong>programme FEC Augment\u00e9<\/strong>.<\/p>\n<p style=\"text-align: justify;\">Ce programme <strong>ajoute les champs<\/strong> suivants sur chaque ligne des FEC qui lui sont soumis :<\/p>\n<ul>\n<li>Solde (d\u00e9bit-cr\u00e9dit) ;<\/li>\n<li>MtTVA : compte identifi\u00e9 comme un compte de TVA ;<\/li>\n<li>BaseTVA : compte identifi\u00e9 comme une base TVA ;<\/li>\n<li>EcritureTxTVA : <strong>taux de TVA<\/strong> de l&#8217;\u00e9criture comptable (report\u00e9 sur chaque ligne de l&#8217;\u00e9criture) ;<\/li>\n<li><a href=\"https:\/\/www.auditsi.eu\/?p=8085\">AAAAMM<\/a> : champ date type 2023\/12 ;<\/li>\n<li>Cpte1, Cpte2, Cpte3, Cpte4, Cpte5, Cpte6 : racines de compte.<\/li>\n<\/ul>\n<div id=\"attachment_12140\" style=\"width: 978px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-12140\" class=\"size-full wp-image-12140\" src=\"https:\/\/www.auditsi.eu\/wp-content\/uploads\/2023\/12\/FEC-augmente.png\" alt=\"FEC augment\u00e9 = FEC + champs additionnels : taux de TVA, racines de compte, solde et mois (AAAA\/MM)\" width=\"968\" height=\"225\" srcset=\"https:\/\/www.auditsi.eu\/wp-content\/uploads\/2023\/12\/FEC-augmente.png 968w, https:\/\/www.auditsi.eu\/wp-content\/uploads\/2023\/12\/FEC-augmente-300x70.png 300w, https:\/\/www.auditsi.eu\/wp-content\/uploads\/2023\/12\/FEC-augmente-768x179.png 768w, https:\/\/www.auditsi.eu\/wp-content\/uploads\/2023\/12\/FEC-augmente-730x170.png 730w\" sizes=\"auto, (max-width: 968px) 100vw, 968px\" \/><p id=\"caption-attachment-12140\" class=\"wp-caption-text\">FEC augment\u00e9 = FEC + champs additionnels : taux de TVA, racines de compte, solde et mois (AAAA\/MM)<\/p><\/div>\n<p style=\"text-align: justify;\">Ces champs facilitent l&#8217;analyse des donn\u00e9es comptables.<\/p>\n<p style=\"text-align: justify;\"><em>Exemples d&#8217;analyses permises avec ces nouveaux champs de donn\u00e9es :<\/em><\/p>\n<p style=\"text-align: justify;\">Le graphique crois\u00e9 dynamique (GCD) r\u00e9alis\u00e9 dans Excel ci-apr\u00e8s <strong>analyse les achats sur un exercice comptable<\/strong> :<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-12239\" src=\"https:\/\/www.auditsi.eu\/wp-content\/uploads\/2024\/01\/FEC-augmente-GCD-masse-salariale.png\" alt=\"FEC augment\u00e9 GCD masse salariale\" width=\"950\" height=\"411\" srcset=\"https:\/\/www.auditsi.eu\/wp-content\/uploads\/2024\/01\/FEC-augmente-GCD-masse-salariale.png 950w, https:\/\/www.auditsi.eu\/wp-content\/uploads\/2024\/01\/FEC-augmente-GCD-masse-salariale-300x130.png 300w, https:\/\/www.auditsi.eu\/wp-content\/uploads\/2024\/01\/FEC-augmente-GCD-masse-salariale-768x332.png 768w, https:\/\/www.auditsi.eu\/wp-content\/uploads\/2024\/01\/FEC-augmente-GCD-masse-salariale-730x316.png 730w\" sizes=\"auto, (max-width: 950px) 100vw, 950px\" \/><\/p>\n<p style=\"text-align: justify;\">Disposition des champs de donn\u00e9es pour obtenir ce GCD :<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-12240\" src=\"https:\/\/www.auditsi.eu\/wp-content\/uploads\/2024\/01\/FEC-augmente-GCD-masse-salariale-Champs.png\" alt=\"FEC augment\u00e9 GCD masse salariale Champs\" width=\"333\" height=\"315\" srcset=\"https:\/\/www.auditsi.eu\/wp-content\/uploads\/2024\/01\/FEC-augmente-GCD-masse-salariale-Champs.png 333w, https:\/\/www.auditsi.eu\/wp-content\/uploads\/2024\/01\/FEC-augmente-GCD-masse-salariale-Champs-300x284.png 300w\" sizes=\"auto, (max-width: 333px) 100vw, 333px\" \/><\/p>\n<p style=\"text-align: justify;\">Le tableau crois\u00e9 dynamique (TCD) suivant liste toutes les <strong>\u00e9critures comptables class\u00e9es par journal comptable et par taux de TVA<\/strong>. Dans le cadre d&#8217;un audit de la TVA, l&#8217;utilisateur peut focaliser son attention sur des achats de location de v\u00e9hicules de tourisme dont la TVA a \u00e9t\u00e9 r\u00e9cup\u00e9r\u00e9e ou sur des ventes exon\u00e9r\u00e9es de TVA, voire sur des inversions HT\/TVA&#8230;<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-12242\" src=\"https:\/\/www.auditsi.eu\/wp-content\/uploads\/2024\/01\/TCD-Taux-TVA.png\" alt=\"TCD Taux TVA\" width=\"419\" height=\"613\" srcset=\"https:\/\/www.auditsi.eu\/wp-content\/uploads\/2024\/01\/TCD-Taux-TVA.png 419w, https:\/\/www.auditsi.eu\/wp-content\/uploads\/2024\/01\/TCD-Taux-TVA-205x300.png 205w\" sizes=\"auto, (max-width: 419px) 100vw, 419px\" \/><\/p>\n<p style=\"text-align: justify;\"><em>Utilisation du programme FEC Augment\u00e9 :<\/em><\/p>\n<p style=\"text-align: justify;\">Pour utiliser le programme FEC Augment\u00e9, deux solutions :<\/p>\n<ul>\n<li>Soit charger le fichier FEC Augment\u00e9.py (t\u00e9l\u00e9chargeable en pied d&#8217;article, \u00e0 renommer de *.txt en *.py) dans l&#8217;interpr\u00e9teur Python ;<\/li>\n<li>Soit double-cliquer sur le fichier FEC Augment\u00e9.exe (contenu dans l&#8217;archive Zip t\u00e9l\u00e9chargeable en pied d&#8217;article) ; ne pas lancer l&#8217;ex\u00e9cution du programme \u00e0 partir du Zip ; il faut pr\u00e9alablement le d\u00e9zipper avant usage.<\/li>\n<\/ul>\n<p style=\"text-align: justify;\">Le programme FEC Augment\u00e9 se pr\u00e9sente ainsi :<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-12243\" src=\"https:\/\/www.auditsi.eu\/wp-content\/uploads\/2024\/01\/FEC-augmente-Selection-FEC.png\" alt=\"FEC augment\u00e9 S\u00e9lection FEC\" width=\"979\" height=\"513\" srcset=\"https:\/\/www.auditsi.eu\/wp-content\/uploads\/2024\/01\/FEC-augmente-Selection-FEC.png 979w, https:\/\/www.auditsi.eu\/wp-content\/uploads\/2024\/01\/FEC-augmente-Selection-FEC-300x157.png 300w, https:\/\/www.auditsi.eu\/wp-content\/uploads\/2024\/01\/FEC-augmente-Selection-FEC-768x402.png 768w, https:\/\/www.auditsi.eu\/wp-content\/uploads\/2024\/01\/FEC-augmente-Selection-FEC-730x383.png 730w\" sizes=\"auto, (max-width: 979px) 100vw, 979px\" \/><\/p>\n<p style=\"text-align: justify;\">Le programme invite l&#8217;utilisateur \u00e0 choisir un FEC.<\/p>\n<p style=\"text-align: justify;\">Une fois le FEC s\u00e9lectionn\u00e9, cliquer sur Ouvrir. Apr\u00e8s quelques instants, le FEC Augment\u00e9 est g\u00e9n\u00e9r\u00e9 (sous la forme d&#8217;un fichier texte). Le temps de calcul d\u00e9pend de la taille du FEC initial (g\u00e9n\u00e9ralement, d&#8217;apr\u00e8s mes tests, de quelques secondes \u00e0 quelques dizaines de secondes).<\/p>\n<p style=\"text-align: justify;\">Le FEC augment\u00e9 est g\u00e9n\u00e9r\u00e9 dans le dossier qui contient l&#8217;ex\u00e9cutable. Le FEC augment\u00e9 est enregistr\u00e9 sous le m\u00eame format qu&#8217;un FEC r\u00e9glementaire mais comprend plus de champs de donne\u00e9es que les 18 ou 19 standard.<\/p>\n<p style=\"text-align: justify;\">C&#8217;est tout simple, non ?<\/p>\n<p style=\"text-align: justify;\">FEC Augment\u00e9 est fourni gracieusement \u00e0 titre de d\u00e9monstration, sans aucune garantie de bon fonctionnement.<\/p>\n<p style=\"text-align: justify;\"><em>Quelques explications sur le code-source du programme :<\/em><\/p>\n<p style=\"text-align: justify;\">Ce script fait appel aux fonctions additionnelles propos\u00e9es par les <strong>biblioth\u00e8ques externes<\/strong> os (pour <em>operating system<\/em> : fonction de gestion de fichiers&#8230;), sys (pour interagir avec l&#8217;interpr\u00e9teur Python), easygui (interface graphique utilisateur : fen\u00eatres&#8230;), pandas (analyse et manipulation de donn\u00e9es) :<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\"># Importation des biblioth\u00e8ques externes\r\nimport os\r\nimport sys\r\nimport easygui\r\nimport pandas as pd<\/pre>\n<p style=\"text-align: justify;\">Le programme affiche des messages d&#8217;introduction avec la commande <em>print<\/em> :<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\"># Message d'introduction\r\nprint(\"-\" * 85)\r\nprint(\"Cr\u00e9ation de FEC augment\u00e9 v1.0 (12\/2023)\")\r\nprint(\"Plus d'infos : https:\/\/www.auditsi.eu\/?p=12196\")\r\nprint()\r\nprint(\"Ce programme ajoute les champs suivants au FEC s\u00e9lectionn\u00e9 :\")\r\nprint(f\"\\t- Solde (d\u00e9bit-cr\u00e9dit)\")\r\nprint(f\"\\t- MtTVA         : compte identifi\u00e9 comme un compte de TVA\")\r\nprint(f\"\\t- BaseTVA       : compte identifi\u00e9 comme une base TVA\")\r\nprint(f\"\\t- EcritureTxTVA : taux de TVA de l'\u00e9criture comptable (report\u00e9 sur chaque ligne de l'\u00e9criture)\")\r\nprint(f\"\\t- AAAAMM        : champ date type 2023\/12\")\r\nprint(f\"\\t- Cpte1, Cpte2, Cpte3, Cpte4, Cpte5, Cpte6 : racines de compte\")\r\nprint(\"-\" * 85)\r\nprint()<\/pre>\n<p style=\"text-align: justify;\">A noter :<\/p>\n<ul>\n<li>La cha\u00eene <em>\\t<\/em> permet d&#8217;ins\u00e9rer une tabulation.<\/li>\n<li>La commande <em>print(&#8220;-&#8221; * 85)<\/em> afficher une ligne constitu\u00e9e de 85 signes moins&#8230;<\/li>\n<\/ul>\n<p style=\"text-align: justify;\">Ceci fait, la commande <em>fileopenbox<\/em> affiche une fen\u00eatre demandant \u00e0 l&#8217;utilisateur de s\u00e9lectionner un FEC :<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\"># Bo\u00eete de dialogue de s\u00e9lection d'un fichier FEC\r\nfichier_FEC = easygui.fileopenbox(title=\"S\u00e9lectionner le fichier FEC \u00e0 traiter\", default=chemin_FEC, filetypes=[\"*.txt\"])<\/pre>\n<p style=\"text-align: justify;\">Les <strong>param\u00e8tres de <em>fileopenbox<\/em><\/strong> \u00e0 fournir :<\/p>\n<ul>\n<li>Barre de titre de la fen\u00eatre : <em>title=&#8221;S\u00e9lectionner le fichier FEC \u00e0 traiter&#8221;<\/em> ;<\/li>\n<li>Chemin d&#8217;acc\u00e8s aux FEC ouvert par d\u00e9faut : <em>default=chemin_FEC<\/em> (d\u00e9fini en amont par la commande <em>os.getcwd()<\/em>, c&#8217;est-\u00e0-dire le dossier o\u00f9 est enregistr\u00e9e l&#8217;application FEC Augment\u00e9) ;<\/li>\n<li>Type de fichier \u00e0 afficher : *.txt : (<em>filetypes=[&#8220;*.txt&#8221;])<\/em>).<\/li>\n<\/ul>\n<p style=\"text-align: justify;\">Une fois le fichier s\u00e9lectionn\u00e9 par l&#8217;utilisateur, son nom est stock\u00e9 dans la variable <em>fichier_FEC<\/em>.<\/p>\n<p style=\"text-align: justify;\">Si l&#8217;utilisateur referme la fen\u00eatre de s\u00e9lection de fichier sans choisir de FEC (par exemple en appuyant sur le bouton Annuler ou la touche Echap), la variable <em>fichier_FEC<\/em> renverra un r\u00e9sultat nul. Bien entendu, dans ce cas il faut stopper l&#8217;ex\u00e9cution du script. C&#8217;est le r\u00f4le de ce code :<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\"># Aucun FEC s\u00e9lectionn\u00e9 (Echap ou Annuler)\r\nif not fichier_FEC:\r\n    print(\"Aucun FEC s\u00e9lectionn\u00e9.\")\r\n    sys.exit()<\/pre>\n<p style=\"text-align: justify;\">Le test conditionnel <em>if not fichier_FEC:<\/em> v\u00e9rifie que la variable est vide et affiche un message et arr\u00eate le programme (<em>sys.exit()<\/em>).<\/p>\n<p style=\"text-align: justify;\">Ensuite, le script cherche \u00e0 identifier le s\u00e9parateur de FEC :<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\"># Identification du s\u00e9parateur de champs de donn\u00e9es\r\nseparateur=recherche_separateur(fichier_FEC)\r\nif separateur==\"E\":\r\n    print(\"FEC non reconnu.\")\r\n    sys.exit()<\/pre>\n<p style=\"text-align: justify;\">Le <strong>s\u00e9parateur de champs<\/strong> est d\u00e9termin\u00e9 par la fonction <em>recherche_separateur<\/em> cr\u00e9\u00e9e ici :<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\"># Identification du s\u00e9parateur de champs (tabulation ou pipe)\r\ndef recherche_separateur(fichier_FEC):\r\n\r\n        separateur=\"\"\r\n        \r\n        # V\u00e9rification si le fichier est un FEC\r\n        if os.path.isfile(fichier_FEC) and fichier_FEC.lower().endswith('.txt'):\r\n\r\n            try:\r\n                # Lecture de la premi\u00e8re ligne du fichier pour obtenir le s\u00e9parateur\r\n                with open(fichier_FEC, 'r') as f:\r\n                    premiere_ligne = f.readline().strip()\r\n                    # S\u00e9parateur tabulation (\\t)\r\n                    if premiere_ligne.startswith(\"JournalCode\\tJournalLib\"):\r\n                        separateur=\"\\t\"\r\n                    # S\u00e9parateur pipe (|)\r\n                    elif premiere_ligne.startswith(\"JournalCode|JournalLib\"):\r\n                        separateur=\"|\"\r\n                    # Sinon Erreur (E)\r\n                    else:\r\n                        separateur=\"E\"\r\n                return separateur\r\n \r\n            except Exception:\r\n                return \"E\"<\/pre>\n<p style=\"text-align: justify;\">Une fonction utilisateur est introduite par la <strong>commande <em>def<\/em><\/strong>. Pour identifier le s\u00e9parateur, cette fonction ouvre le FEC (<em>open<\/em>), lit la premi\u00e8re ligne du FEC (<em>readline<\/em>&#8230;) et confronte (<em>if&#8230; elif&#8230; else:<\/em>) le d\u00e9but de la ligne lue (<em>startswith<\/em>) avec une cha\u00eene pr\u00e9d\u00e9finie (<em>&#8220;JournalCode\\tJournalLib&#8221;<\/em> puis <em>&#8220;JournalCode|JournalLib&#8221;<\/em>). A partir du r\u00e9sultat obtenu, la fonction retourne le s\u00e9parateur identifi\u00e9 ou <em>&#8220;E&#8221;<\/em> si aucun s\u00e9parateur reconnu n&#8217;a pu \u00eatre trouv\u00e9.<\/p>\n<p style=\"text-align: justify;\">Pour m\u00e9moire, le CGI d\u00e9finit la tabulation et la pipe (|) comme seuls s\u00e9parateurs r\u00e9guli\u00e8rement admis.<\/p>\n<p style=\"text-align: justify;\">Une fois le s\u00e9parateur identifi\u00e9, le FEC est ouvert (\u00e0 l&#8217;aide de la <strong>commande <em>read_csv<\/em><\/strong>) :<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\"># Chargement du FEC\r\nfec = pd.read_csv(fichier_FEC, delimiter=separateur, encoding='ISO-8859-1', dtype=str)<\/pre>\n<p style=\"text-align: justify;\">Ensuite, des champs de donn\u00e9es sont ajout\u00e9s au FEC :<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\"># Cr\u00e9ation du champ Solde = Debit - Credit\r\nfec['Solde'] = fec['Debit'] - fec['Credit']\r\n\r\n# Cr\u00e9ation du champ AAAAMM (AAAA\/MM)\r\nfec['AAAAMM'] = pd.to_datetime(fec['EcritureDate'], format='%d\/%m\/%Y').dt.strftime('%Y\/%m')\r\n\r\n# Cr\u00e9ation des champs MtTVA et BaseTVA \u00e0 l'aide des fonctions ad hoc \r\nfec['MtTVA'] = fec.apply(calcul_champ_mttva, axis=1)\r\nfec['BaseTVA'] = fec.apply(calcul_champ_basetva, axis=1)\r\n\r\n# Cr\u00e9ation des champs EcritureTxTVA (taux de TVA)\r\n# --- Regroupement par EcritureNum et calcul de la somme de BaseTVA et MtTVA\r\nregroupement_donnees = fec.groupby('EcritureNum')[['BaseTVA', 'MtTVA']].sum().reset_index()\r\n# --- Pour chaque EcritureNum, calcul du Taux de TVA (si BaseTVA nulle, le r\u00e9sultat renvoy\u00e9 est 'nan')\r\nregroupement_donnees['EcritureTxTVA'] = regroupement_donnees['MtTVA'] \/ regroupement_donnees['BaseTVA']\r\n# --- Fusion des r\u00e9sultats du regroupement dans le FEC d'origine en fonction de EcritureNum\r\nfec = pd.merge(fec, regroupement_donnees[['EcritureNum', 'EcritureTxTVA']], on='EcritureNum', how='left')\r\n\r\n# --- Champ EcritureTxTVA arrondi \u00e0 quatre d\u00e9cimales\r\nfec['EcritureTxTVA'] = fec['EcritureTxTVA'].round(4)\r\n\r\n# Cr\u00e9ation des champs racine de compte Cpte1..Cpte6\r\nfec['Cpte6'] = fec['CompteNum'].str[:6].astype(int)\r\nfec['Cpte5'] = fec['CompteNum'].str[:5].astype(int)\r\nfec['Cpte4'] = fec['CompteNum'].str[:4].astype(int)\r\nfec['Cpte3'] = fec['CompteNum'].str[:3].astype(int)\r\nfec['Cpte2'] = fec['CompteNum'].str[:2].astype(int)\r\nfec['Cpte1'] = fec['CompteNum'].str[0].astype(int)<\/pre>\n<p style=\"text-align: justify;\">Le champ Solde r\u00e9sulte d&#8217;un calcul entre deux cahmps pr\u00e9existants (Debit-Credit).<\/p>\n<p style=\"text-align: justify;\">Le calcul de la base de TVA (BaseTVA) et du montant de la TVA (MtTVA) fait appel \u00e0 deux fonctions cr\u00e9\u00e9es ad hoc :<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\"># Cr\u00e9ation du champ MtTVA\r\ndef calcul_champ_mttva(row):\r\n    if row['CompteNum'].startswith(('44562', '44566', '4457', '44586', '44587')):\r\n        return row['Solde']\r\n    return 0\r\n\r\n# Cr\u00e9ation du champ BaseTVA\r\ndef calcul_champ_basetva(row):\r\n    if row['CompteNum'].startswith(('6', '7', '20', '21', '23')):\r\n            if not row['CompteNum'].startswith(('603', '68', '78')):\r\n                return row['Solde']\r\n    return 0<\/pre>\n<p style=\"text-align: justify;\">Pour le <strong>champ MtTVA<\/strong>, les comptes de TVA \u00e0 retenir commencent par 44562x (TVA d\u00e9ductible sur immobilisations), 44566x (TVA d\u00e9ductible sur biens et services), 4457x (TVA collect\u00e9e), 44586\/7x (TVA sur comptes de coupures). Pour le <strong>champ BaseTVA<\/strong>, les bases de TVA sont form\u00e9es par l&#8217;ensemble des comptes de charges et de produits (sauf comptes de variations de stock (603x), de dotations et de reprises de d\u00e9pr\u00e9ciations (68\/78x)), des comptes d&#8217;immobilisations incorporelles (20x), corporelles (21x) et en cours (23x).<\/p>\n<p style=\"text-align: justify;\">Le calcul du <strong>champ EcritureTxTVA<\/strong> r\u00e9sulte de la division op\u00e9r\u00e9e entre MtTVA et BaseTVA. Pour calculer le taux de TVA au niveau de chaque \u00e9criture, il est n\u00e9cessaire d&#8217;effectuer un regroupement (avec la <strong>commande groupby<\/strong> \u00e0 la mani\u00e8re d&#8217;une requ\u00eate regroupement SQL GROUP BY). Le taux de TVA est arrondi sur quatre d\u00e9cimales (<em>round(4)<\/em>). Par exemple : 0,2000 soit 20,00 %.<\/p>\n<p style=\"text-align: justify;\">Enfin, le FEC agr\u00e9ment\u00e9 des changements ci-avant mentionn\u00e9s est enregistr\u00e9 (<em>to_csv<\/em>) sous son nom d&#8217;origine pr\u00e9d\u00e9c\u00e9 du pr\u00e9fixe <em>&#8220;FEC augment\u00e9 &#8220;<\/em> sauf si le fichier de destination existe d\u00e9j\u00e0 (<em>os.path.isfile<\/em>) auquel cas le programme s&#8217;arr\u00eate sans enregistrer les donn\u00e9es.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\"># R\u00e9cup\u00e9ration du nom du FEC sans l'arborescence\r\nnom_FEC = os.path.basename(fichier_FEC)\r\n\r\n# Cr\u00e9ation du nom de FEC augment\u00e9\r\nfichier_FEC_augmente = chemin_Appli + '\\\\' + \"FEC augment\u00e9 \" + nom_FEC\r\n\r\n# Si le FEC existe d\u00e9j\u00e0 -&gt; arr\u00eat du programme\r\nif os.path.isfile(fichier_FEC_augmente):\r\n    print(f\"Le fichier {fichier_FEC_augmente} existe d\u00e9j\u00e0. Traitement annul\u00e9\")\r\n    sys.exit()    \r\n# Sinon : enregistrement du FEC modifi\u00e9 dans un nouveau fichier texte\r\nelse:\r\n    print(f\"Le fichier {fichier_FEC_augmente} a \u00e9t\u00e9 g\u00e9n\u00e9r\u00e9 avec succ\u00e8s.\")\r\n    fec.to_csv(fichier_FEC_augmente, sep=separateur, index=False, encoding='ISO-8859-1')<\/pre>\n<p style=\"text-align: justify;\"><em>Code-source int\u00e9gral du programme :<\/em><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\"># -------------------------------------------------------------------------------------------\r\n# Cr\u00e9ation de FEC augment\u00e9\r\n# v1.0 12\/2023\r\n# Plus d'infos : https:\/\/www.auditsi.eu\/?p=12196\r\n# -------------------------------------------------------------------------------------------\r\n\r\n# Importation des biblioth\u00e8ques externes\r\nimport os\r\nimport sys\r\nimport easygui\r\nimport pandas as pd\r\n\r\n\r\n# Identification du s\u00e9parateur de champs (tabulation ou pipe)\r\ndef recherche_separateur(fichier_FEC):\r\n\r\n        separateur=\"\"\r\n        \r\n        # V\u00e9rification si le fichier est un FEC\r\n        if os.path.isfile(fichier_FEC) and fichier_FEC.lower().endswith('.txt'):\r\n\r\n            try:\r\n                # Lecture de la premi\u00e8re ligne du fichier pour obtenir le s\u00e9parateur\r\n                with open(fichier_FEC, 'r') as f:\r\n                    premiere_ligne = f.readline().strip()\r\n                    # S\u00e9parateur tabulation (\\t)\r\n                    if premiere_ligne.startswith(\"JournalCode\\tJournalLib\"):\r\n                        separateur=\"\\t\"\r\n                    # S\u00e9parateur pipe (|)\r\n                    elif premiere_ligne.startswith(\"JournalCode|JournalLib\"):\r\n                        separateur=\"|\"\r\n                    # Sinon Erreur (E)\r\n                    else:\r\n                        separateur=\"E\"\r\n                return separateur\r\n \r\n            except Exception:\r\n                return \"E\"\r\n\r\n# Cr\u00e9ation du champ MtTVA\r\ndef calcul_champ_mttva(row):\r\n    if row['CompteNum'].startswith(('44562', '44566', '4457', '44586', '44587')):\r\n        return row['Solde']\r\n    return 0\r\n\r\n# Cr\u00e9ation du champ BaseTVA\r\ndef calcul_champ_basetva(row):\r\n    if row['CompteNum'].startswith(('6', '7', '20', '21', '23')):\r\n            if not row['CompteNum'].startswith(('603', '68', '78')):\r\n                return row['Solde']\r\n    return 0\r\n\r\n# Message d'introduction\r\nprint(\"-\" * 85)\r\nprint(\"Cr\u00e9ation de FEC augment\u00e9 v1.0 (12\/2023)\")\r\nprint(\"Plus d'infos : https:\/\/www.auditsi.eu\/?p=12196\")\r\nprint()\r\nprint(\"Ce programme ajoute les champs suivants au FEC s\u00e9lectionn\u00e9 :\")\r\nprint(f\"\\t- Solde (d\u00e9bit-cr\u00e9dit)\")\r\nprint(f\"\\t- MtTVA         : compte identifi\u00e9 comme un compte de TVA\")\r\nprint(f\"\\t- BaseTVA       : compte identifi\u00e9 comme une base TVA\")\r\nprint(f\"\\t- EcritureTxTVA : taux de TVA de l'\u00e9criture comptable (report\u00e9 sur chaque ligne de l'\u00e9criture)\")\r\nprint(f\"\\t- AAAAMM        : champ date type 2023\/12\")\r\nprint(f\"\\t- Cpte1, Cpte2, Cpte3, Cpte4, Cpte5, Cpte6 : racines de compte\")\r\nprint(\"-\" * 85)\r\nprint()\r\n\r\n# Chemin d'acc\u00e8s par d\u00e9faut\r\nchemin_Appli = os.getcwd()\r\nchemin_FEC = chemin_Appli\r\n\r\n# Bo\u00eete de dialogue de s\u00e9lection d'un fichier FEC\r\nfichier_FEC = easygui.fileopenbox(title=\"S\u00e9lectionner le fichier FEC \u00e0 traiter\", default=chemin_FEC, filetypes=[\"*.txt\"])\r\n\r\n# Aucun FEC s\u00e9lectionn\u00e9 (Echap ou Annuler)\r\nif not fichier_FEC:\r\n    print(\"Aucun FEC s\u00e9lectionn\u00e9.\")\r\n    sys.exit()    \r\n\r\n# Identification du s\u00e9parateur de champs de donn\u00e9es\r\nseparateur=recherche_separateur(fichier_FEC)\r\nif separateur==\"E\":\r\n    print(\"FEC non reconnu.\")\r\n    sys.exit()    \r\n\r\n# Chargement du FEC\r\nfec = pd.read_csv(fichier_FEC, delimiter=separateur, encoding='ISO-8859-1', dtype=str)\r\n\r\n# Conversion des champs Debit et Credit en num\u00e9rique (remplacement de la d\u00e9cimale , par un .)\r\nfec['Debit'] = pd.to_numeric(fec['Debit'].str.replace(',', '.'), errors='coerce')\r\nfec['Credit'] = pd.to_numeric(fec['Credit'].str.replace(',', '.'), errors='coerce')\r\n\r\n# Cr\u00e9ation du champ Solde = Debit - Credit\r\nfec['Solde'] = fec['Debit'] - fec['Credit']\r\n\r\n# Conversion des champs EcritureDate, ValidDate et DateLet au format JJ\/MM\/AAAA\r\nfec['EcritureDate'] = pd.to_datetime(fec['EcritureDate'], format='%Y%m%d').dt.strftime('%d\/%m\/%Y')\r\nfec['ValidDate'] = pd.to_datetime(fec['ValidDate'], format='%Y%m%d').dt.strftime('%d\/%m\/%Y')\r\nfec['DateLet'] = pd.to_datetime(fec['DateLet'], format='%Y%m%d').dt.strftime('%d\/%m\/%Y')\r\n\r\n# Cr\u00e9ation du champ AAAAMM (AAAA\/MM)\r\nfec['AAAAMM'] = pd.to_datetime(fec['EcritureDate'], format='%d\/%m\/%Y').dt.strftime('%Y\/%m')\r\n\r\n# Cr\u00e9ation des champs MtTVA et BaseTVA \u00e0 l'aide des fonctions ad hoc \r\nfec['MtTVA'] = fec.apply(calcul_champ_mttva, axis=1)\r\nfec['BaseTVA'] = fec.apply(calcul_champ_basetva, axis=1)\r\n\r\n# Cr\u00e9ation des champs EcritureTxTVA (taux de TVA)\r\n# --- Regroupement par EcritureNum et calcul de la somme de BaseTVA et MtTVA\r\nregroupement_donnees = fec.groupby('EcritureNum')[['BaseTVA', 'MtTVA']].sum().reset_index()\r\n# --- Pour chaque EcritureNum, calcul du Taux de TVA (si BaseTVA nulle, le r\u00e9sultat renvoy\u00e9 est 'nan')\r\nregroupement_donnees['EcritureTxTVA'] = regroupement_donnees['MtTVA'] \/ regroupement_donnees['BaseTVA']\r\n# --- Fusion des r\u00e9sultats du regroupement dans le FEC d'origine en fonction de EcritureNum\r\nfec = pd.merge(fec, regroupement_donnees[['EcritureNum', 'EcritureTxTVA']], on='EcritureNum', how='left')\r\n\r\n# --- Champ EcritureTxTVA arrondi \u00e0 quatre d\u00e9cimales\r\nfec['EcritureTxTVA'] = fec['EcritureTxTVA'].round(4)\r\n\r\n# Cr\u00e9ation des champs racine de compte Cpte1..Cpte6\r\nfec['Cpte6'] = fec['CompteNum'].str[:6].astype(int)\r\nfec['Cpte5'] = fec['CompteNum'].str[:5].astype(int)\r\nfec['Cpte4'] = fec['CompteNum'].str[:4].astype(int)\r\nfec['Cpte3'] = fec['CompteNum'].str[:3].astype(int)\r\nfec['Cpte2'] = fec['CompteNum'].str[:2].astype(int)\r\nfec['Cpte1'] = fec['CompteNum'].str[0].astype(int)\r\n\r\n# Remplacement des points par des virgules dans les champs de montant (Debit, Credit, Solde, BaseTVA, MtTVA, TxTVA...)\r\nfec[['Debit', 'Credit', 'Solde', 'MtTVA', 'BaseTVA', 'EcritureTxTVA']] = fec[['Debit', 'Credit', 'Solde', 'MtTVA', 'BaseTVA', 'EcritureTxTVA']].apply(lambda x: x.astype(str).str.replace('.', ','))\r\n\r\n# Renommage des champs CompAuxNum et CompAuxLib en CompteAuxNum et CompteAuxLib\r\nfec.rename(columns={'CompAuxNum': 'CompteAuxNum', 'CompAuxLib': 'CompteAuxLib', 'Debit': 'D\u00e9bit', 'Credit': 'Cr\u00e9dit', 'PieceRef': 'Pi\u00e8ceR\u00e9f', 'PieceDate': 'Pi\u00e8ceDate'}, inplace=True)\r\n\r\n# Modification de l'ordre des champs de donn\u00e9es\r\ncolumns_order = ['EcritureNum', 'JournalCode', 'JournalLib', 'EcritureDate', 'CompteNum', 'CompteLib', 'CompteAuxNum', 'CompteAuxLib', 'EcritureLib', 'D\u00e9bit', 'Cr\u00e9dit', 'Solde', 'Pi\u00e8ceR\u00e9f', 'Pi\u00e8ceDate', 'ValidDate', 'EcritureLet', 'DateLet', 'MtTVA', 'BaseTVA', 'EcritureTxTVA', 'AAAAMM', 'Cpte6', 'Cpte5', 'Cpte4', 'Cpte3', 'Cpte2', 'Cpte1']\r\n# --- Si le champ CodeEtabt existe, le mettre en dernier\r\nif 'CodeEtabt' in fec.columns:\r\n    columns_order.remove('CodeEtabt')\r\n    columns_order.append('CodeEtabt')\r\n# --- Mise en oeuvre de l'ordre indiqu\u00e9\r\nfec = fec[columns_order]\r\n\r\n# R\u00e9cup\u00e9ration du nom du FEC sans l'arborescence\r\nnom_FEC = os.path.basename(fichier_FEC)\r\n\r\n# Cr\u00e9ation du nom de FEC augment\u00e9\r\nfichier_FEC_augmente = chemin_Appli + '\\\\' + \"FEC augment\u00e9 \" + nom_FEC\r\n\r\n# Si le FEC existe d\u00e9j\u00e0 -&gt; arr\u00eat du programme\r\nif os.path.isfile(fichier_FEC_augmente):\r\n    print(f\"Le fichier {fichier_FEC_augmente} existe d\u00e9j\u00e0. Traitement annul\u00e9\")\r\n    sys.exit()    \r\n# Sinon : enregistrement du FEC modifi\u00e9 dans un nouveau fichier texte\r\nelse:\r\n    print(f\"Le fichier {fichier_FEC_augmente} a \u00e9t\u00e9 g\u00e9n\u00e9r\u00e9 avec succ\u00e8s.\")\r\n    fec.to_csv(fichier_FEC_augmente, sep=separateur, index=False, encoding='ISO-8859-1')\r\n\r\n# Message final\r\nprint()\r\nprint(\"Traitement termin\u00e9.\")<\/pre>\n<p style=\"text-align: justify;\">Autre exemple de script Python : <a href=\"https:\/\/www.auditsi.eu\/?p=12153\">calcul d&#8217;\u00e9ch\u00e9ancier d&#8217;emprunt<\/a>.<\/p>\n<p style=\"text-align: justify;\">___<\/p>\n<p style=\"text-align: justify;\">Pour approfondir le sujet :&nbsp;<a href=\"https:\/\/www.auditsi.eu\/?p=12059\">se former \u00e0 la programmation en langage Python pour automatiser ses t\u00e2ches<\/a><\/p>\n<div id=\"sconnect-is-installed\" style=\"display: none;\">2.13.0.0<\/div>\n<div id=\"sconnect-is-installed\" style=\"display: none;\">2.13.0.0<\/div>\n<div id=\"sconnect-is-installed\" style=\"display: none;\">2.13.0.0<\/div>\n<div id=\"sconnect-is-installed\" style=\"display: none;\">2.13.0.0<\/div>\n<div id=\"sconnect-is-installed\" style=\"display: none;\">2.13.0.0<\/div>\n<div style=\"padding-bottom:20px; padding-top:10px;\" class=\"hupso-share-buttons\"><!-- Hupso Share Buttons - https:\/\/www.hupso.com\/share\/ --><a class=\"hupso_counters\" href=\"https:\/\/www.hupso.com\/share\/\"><img decoding=\"async\" src=\"https:\/\/static.hupso.com\/share\/buttons\/lang\/fr\/share-small.png\" style=\"border:0px; padding-top:2px; float:left;\" alt=\"Share Button\"\/><\/a><script type=\"text\/javascript\">var hupso_services_c=new Array(\"twitter\",\"facebook_like\",\"facebook_send\",\"email\",\"print\",\"linkedin\");var hupso_counters_lang = \"fr_FR\";var hupso_image_folder_url = \"\";var hupso_twitter_via=\"BenoitRiviere14\";var hupso_url_c=\"\";var hupso_title_c=\"Analyse%20de%20donn%C3%A9es%20%26%20Python%20%3A%20cr%C3%A9er%20un%20FEC%20augment%C3%A9\";<\/script><script type=\"text\/javascript\" src=\"https:\/\/static.hupso.com\/share\/js\/counters.js\"><\/script><!-- Hupso Share Buttons --><\/div>","protected":false},"excerpt":{"rendered":"<p>L&#8217;analyse de donn\u00e9es comptables contenues dans un Fichier des Ecritures Comptables (FEC) est une pratique de plus en plus commune. Dans ce cadre, le langage Python est un formidable outil parfaitement adapt\u00e9 pour nettoyer et manipuler les donn\u00e9es. L&#8217;article qui suit sera illustr\u00e9 d&#8217;un exemple clef en main \u00e0 titre de d\u00e9monstration. Cet exemple est &#8230;<\/p>\n<p><a href=\"https:\/\/www.auditsi.eu\/?p=12196\" class=\"more-link\">Continue reading &lsquo;Analyse de donn\u00e9es &#038; Python : cr\u00e9er un FEC augment\u00e9&rsquo; &raquo;<\/a><\/p>\n<div style=\"padding-bottom:20px; padding-top:10px;\" class=\"hupso-share-buttons\"><!-- Hupso Share Buttons - https:\/\/www.hupso.com\/share\/ --><a class=\"hupso_counters\" href=\"https:\/\/www.hupso.com\/share\/\"><img src=\"https:\/\/static.hupso.com\/share\/buttons\/lang\/fr\/share-small.png\" style=\"border:0px; padding-top:2px; float:left;\" alt=\"Share Button\"\/><\/a><script type=\"text\/javascript\">var hupso_services_c=new Array(\"twitter\",\"facebook_like\",\"facebook_send\",\"email\",\"print\",\"linkedin\");var hupso_counters_lang = \"fr_FR\";var hupso_image_folder_url = \"\";var hupso_twitter_via=\"BenoitRiviere14\";var hupso_url_c=\"\";var hupso_title_c=\"Analyse%20de%20donn%C3%A9es%20%26%20Python%20%3A%20cr%C3%A9er%20un%20FEC%20augment%C3%A9\";<\/script><script type=\"text\/javascript\" src=\"https:\/\/static.hupso.com\/share\/js\/counters.js\"><\/script><!-- Hupso Share Buttons --><\/div>","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"advanced_seo_description":"","jetpack_seo_html_title":"","jetpack_seo_noindex":false,"ngg_post_thumbnail":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","_links_to":"","_links_to_target":""},"categories":[3260,800,508,3087],"tags":[2032,166,1981,3135,1210,3131,1211,3133,2456,2276,3134,1951,3136,640,2339,258,3140,2048,3088,2386,3138,1960,441,3137,2050,1261,182,222,3139,3132],"class_list":["post-12196","post","type-post","status-publish","format-standard","hentry","category-analyser-un-fec-avec-python","category-cycle-fiscalite","category-cycle-personnel","category-python","tag-aaaa-mm","tag-analyse-de-donnees","tag-audit-de-la-tva","tag-def","tag-fec","tag-fec-augmente","tag-fichier-des-ecritures-comptables","tag-fileopenbox","tag-fonction","tag-gcd","tag-getcwd","tag-groupby","tag-if-elif-else","tag-inversion-de-tvaht","tag-nettoyage-des-donnees","tag-open","tag-os-path-isfile","tag-pipe","tag-python","tag-readline","tag-read_csv","tag-requete-regroupement","tag-round","tag-startswith","tag-tabulation","tag-taux-de-tva","tag-tcd","tag-tests-conditionnels","tag-to_csv","tag-t"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_likes_enabled":false,"_links":{"self":[{"href":"https:\/\/www.auditsi.eu\/index.php?rest_route=\/wp\/v2\/posts\/12196","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.auditsi.eu\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.auditsi.eu\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.auditsi.eu\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.auditsi.eu\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=12196"}],"version-history":[{"count":5,"href":"https:\/\/www.auditsi.eu\/index.php?rest_route=\/wp\/v2\/posts\/12196\/revisions"}],"predecessor-version":[{"id":12246,"href":"https:\/\/www.auditsi.eu\/index.php?rest_route=\/wp\/v2\/posts\/12196\/revisions\/12246"}],"wp:attachment":[{"href":"https:\/\/www.auditsi.eu\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=12196"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.auditsi.eu\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=12196"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.auditsi.eu\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=12196"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}