{"id":11980,"date":"2023-12-18T06:05:26","date_gmt":"2023-12-18T05:05:26","guid":{"rendered":"https:\/\/www.auditsi.eu\/?p=11980"},"modified":"2023-11-12T18:37:36","modified_gmt":"2023-11-12T17:37:36","slug":"power-query-excel-recuperer-des-donnees-contenues-dans-un-fichier-pdf","status":"publish","type":"post","link":"https:\/\/www.auditsi.eu\/?p=11980","title":{"rendered":"Power Query (Excel) : r\u00e9cup\u00e9rer des donn\u00e9es contenues dans un fichier PDF"},"content":{"rendered":"<p style=\"text-align: justify;\">Les <strong>fichiers PDF<\/strong> de sources diverses (factures, liasses fiscales, plaquettes des comptes annuels&#8230;) contiennent de nombreuses donn\u00e9es. L&#8217;extraction de donn\u00e9es de documents PDF est facilit\u00e9e par le module <strong>Power Query<\/strong> d&#8217;Excel. Pour autant, la collecte de ces donn\u00e9es n&#8217;est pas toujours tr\u00e8s intuitive.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-11981\" src=\"https:\/\/www.auditsi.eu\/wp-content\/uploads\/2023\/11\/AVIS-CREDIT-GARANTIE.png\" alt=\"AVIS CREDIT GARANTIE\" width=\"1229\" height=\"668\" srcset=\"https:\/\/www.auditsi.eu\/wp-content\/uploads\/2023\/11\/AVIS-CREDIT-GARANTIE.png 1229w, https:\/\/www.auditsi.eu\/wp-content\/uploads\/2023\/11\/AVIS-CREDIT-GARANTIE-300x163.png 300w, https:\/\/www.auditsi.eu\/wp-content\/uploads\/2023\/11\/AVIS-CREDIT-GARANTIE-1024x557.png 1024w, https:\/\/www.auditsi.eu\/wp-content\/uploads\/2023\/11\/AVIS-CREDIT-GARANTIE-768x417.png 768w, https:\/\/www.auditsi.eu\/wp-content\/uploads\/2023\/11\/AVIS-CREDIT-GARANTIE-730x397.png 730w\" sizes=\"auto, (max-width: 1229px) 100vw, 1229px\" \/><\/p>\n<p style=\"text-align: justify;\">Cet article s&#8217;appuie sur un exemple concret. Un <strong>concessionnaire automobile<\/strong> est amen\u00e9 \u00e0 r\u00e9parer des v\u00e9hicules de clients tomb\u00e9s en panne pendant la p\u00e9riode de garantie constructeur. Dans ce cas le concessionnaire engage la prestation de r\u00e9paration et dans un second temps le constructeur le rembourse du co\u00fbt des pi\u00e8ces de rechange et de la main d&#8217;oeuvre. Les constructeurs Citro\u00ebn et Peugeot (Stellantis) \u00e9mettent \u00e0 cette occasion des <strong>avis de cr\u00e9dit<\/strong> (ou avoirs) de garantie et communiquent \u00e0 leurs concessionnaires tous les mois un <strong>\u00e9tat r\u00e9capitulatif<\/strong> de l&#8217;ensemble des avis de cr\u00e9dit de la p\u00e9riode au format PDF. C&#8217;est de cet \u00e9tat que je vous propose d&#8217;extraire les donn\u00e9es pour <strong>reconstituer<\/strong> pour chaque op\u00e9ration de r\u00e9paration le <strong>montant de la d\u00e9pense<\/strong> dont le remboursement est attendu du constructeur.<\/p>\n<p style=\"text-align: justify;\">La macro VBA pr\u00e9sent\u00e9e ci-apr\u00e8s collectera puis listera dans un tableau Excel le <strong>num\u00e9ro VIN<\/strong> (<em>Vehicle Identification Number<\/em> ou num\u00e9ro d\u2019identification du v\u00e9hicule, compos\u00e9 de 17 caract\u00e8res) du v\u00e9hicule r\u00e9par\u00e9 ainsi que le <strong>co\u00fbt de la r\u00e9paration<\/strong>. Ces deux donn\u00e9es sont rep\u00e9r\u00e9es en jaune sur l&#8217;\u00e9tat ci-avant.<\/p>\n<p style=\"text-align: justify;\">Cette collecte de donn\u00e9es passe par la cr\u00e9ation de <strong>requ\u00eates M<\/strong> pilot\u00e9es par du <strong>code VBA<\/strong>.<\/p>\n<p style=\"text-align: justify;\">Le code VBA de <strong>collecte de donn\u00e9es issues d&#8217;un fichier PDF<\/strong> \u00e0 l&#8217;aide de Power Query a d\u00e9j\u00e0 fait l&#8217;objet d&#8217;un expos\u00e9 d\u00e9taill\u00e9. Le lecteur d\u00e9sireux d&#8217;approfondir la partie VBA se reportera aux deux articles suivants :<\/p>\n<ul>\n<li><a href=\"https:\/\/www.auditsi.eu\/?p=10284\">Excel : importer un tableau de donn\u00e9es contenu dans un fichier PDF<\/a> ;<\/li>\n<li><a href=\"https:\/\/www.auditsi.eu\/?p=10302\">Excel : automatiser l\u2019extraction des tableaux de donn\u00e9es d\u2019un fichier PDF<\/a>.<\/li>\n<\/ul>\n<p style=\"text-align: justify;\">L&#8217;expos\u00e9 qui suit s&#8217;attardera sur la partie <strong>requ\u00eate M (Power Query)<\/strong>.<\/p>\n<p style=\"text-align: justify;\">Le code VBA cr\u00e9e des requ\u00eates en fonction des donn\u00e9es de l&#8217;utilisateur (nom et chemin d&#8217;acc\u00e8s au fichier PDF) et des caract\u00e9ristiques du fichier PDF (nombre de pages).<\/p>\n<p style=\"text-align: justify;\">Il cr\u00e9e <strong>une requ\u00eate par page import\u00e9e<\/strong>. Exemple avec la premi\u00e8re page (requ\u00eate Page001) :<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">let\r\n Source = Pdf.Tables(File.Contents(\"C:\\TESTS\\20231019-SAGL281 RECAPITULATIF_DES_AVIS_DE_CREDIT.pdf\"), [Implementation=\"1.3\"]),\r\n Page1 = Source{[Id=\"Page001\"]}[Data]\r\nin\r\n Page1<\/pre>\n<p style=\"text-align: justify;\">Puis, il cr\u00e9e <strong>une seconde requ\u00eate combinant l&#8217;ensemble des pages<\/strong> (requ\u00eate Pages_PDF), ici 34 pages :<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">let\r\n Source = Table.Combine({Page001,Page002,Page003,Page004,Page005,Page006,Page007,Page008,Page009,Page010,Page011,Page012,Page013,Page014,Page015,Page016,Page017,Page018,Page019,Page020,Page021,Page022,Page023,Page024,Page025,Page026,Page027,Page028,Page029,Page030,Page031,Page032,Page033,Page034}),\r\n #\"Type modifi\u00e9\" = Table.TransformColumnTypes(Source,{{\"Column4\", type text}, {\"Column7\", type text}, {\"Column12\", type text}, {\"Column16\", type text}, {\"Column17\", type text}}),\r\n #\"Colonnes fusionn\u00e9es\" = Table.CombineColumns(Table.TransformColumnTypes(#\"Type modifi\u00e9\", {{\"Column7\", type text}, {\"Column12\", type text}, {\"Column16\", type text}, {\"Column17\", type text}}, \"fr-FR\"),{\"Column1\", \"Column2\", \"Column3\", \"Column4\", \"Column5\", \"Column6\", \"Column7\", \"Column8\", \"Column9\", \"Column10\", \"Column11\", \"Column12\", \"Column13\", \"Column14\", \"Column15\", \"Column16\", \"Column17\"},Combiner.CombineTextByDelimiter(\"##\", QuoteStyle.None),\"Fusionn\u00e9\"),\r\n #\"Lignes filtr\u00e9es\" = Table.SelectRows(#\"Colonnes fusionn\u00e9es\", each Text.Contains([Fusionn\u00e9], \"##VIN:\") or Text.Contains([Fusionn\u00e9], \"!MT.INC:\")),\r\n #\"Autres colonnes supprim\u00e9es\" = Table.SelectColumns(#\"Lignes filtr\u00e9es\",{\"Fusionn\u00e9\"}),\r\n #\"Duplication de la colonne\" = Table.DuplicateColumn(#\"Autres colonnes supprim\u00e9es\", \"Fusionn\u00e9\", \"Fusionn\u00e9 - Copier\"),\r\n #\"Texte extrait entre les d\u00e9limiteurs\" = Table.TransformColumns(#\"Duplication de la colonne\", {{\"Fusionn\u00e9\", each Text.BetweenDelimiters(_, \"##VIN:\", \"##\"), type text}}),\r\n #\"Texte extrait entre les d\u00e9limiteurs1\" = Table.TransformColumns(#\"Texte extrait entre les d\u00e9limiteurs\", {{\"Fusionn\u00e9 - Copier\", each Text.BetweenDelimiters(_, \"!MT.INC:####\", \" \"), type text}}),\r\n #\"Type modifi\u00e91\" = Table.TransformColumnTypes(#\"Texte extrait entre les d\u00e9limiteurs1\",{{\"Fusionn\u00e9 - Copier\", type number}}),\r\n #\"Valeur remplac\u00e9e\" = Table.ReplaceValue(#\"Type modifi\u00e91\",\"\",null,Replacer.ReplaceValue,{\"Fusionn\u00e9\"}),\r\n #\"Rempli vers le bas\" = Table.FillDown(#\"Valeur remplac\u00e9e\",{\"Fusionn\u00e9\"}),\r\n #\"Lignes filtr\u00e9es1\" = Table.SelectRows(#\"Rempli vers le bas\", each ([#\"Fusionn\u00e9 - Copier\"] &lt;&gt; null)),\r\n #\"Colonnes renomm\u00e9es\" = Table.RenameColumns(#\"Lignes filtr\u00e9es1\",{{\"Fusionn\u00e9\", \"VIN\"}, {\"Fusionn\u00e9 - Copier\", \"MT_INC\"}})\r\nin\r\n #\"Colonnes renomm\u00e9es\"<\/pre>\n<p style=\"text-align: justify;\">Pas-\u00e0-pas de la requ\u00eate Pages_PDF et <strong>visualisation de chaque \u00e9tape sur les donn\u00e9es<\/strong> dans le module Power Query :<\/p>\n<ul>\n<li>Source = Table.Combine : Combinaison de l&#8217;ensemble des pages<\/li>\n<\/ul>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-11985\" src=\"https:\/\/www.auditsi.eu\/wp-content\/uploads\/2023\/11\/PQ-Pages_PDF-Source.png\" alt=\"PQ Pages_PDF Source\" width=\"1147\" height=\"300\" srcset=\"https:\/\/www.auditsi.eu\/wp-content\/uploads\/2023\/11\/PQ-Pages_PDF-Source.png 1147w, https:\/\/www.auditsi.eu\/wp-content\/uploads\/2023\/11\/PQ-Pages_PDF-Source-300x78.png 300w, https:\/\/www.auditsi.eu\/wp-content\/uploads\/2023\/11\/PQ-Pages_PDF-Source-1024x268.png 1024w, https:\/\/www.auditsi.eu\/wp-content\/uploads\/2023\/11\/PQ-Pages_PDF-Source-768x201.png 768w, https:\/\/www.auditsi.eu\/wp-content\/uploads\/2023\/11\/PQ-Pages_PDF-Source-730x191.png 730w\" sizes=\"auto, (max-width: 1147px) 100vw, 1147px\" \/><\/p>\n<ul>\n<li>#&#8221;Colonnes fusionn\u00e9es&#8221; = Table.CombineColumns : fusion des champs de donn\u00e9es en un seul (chaque champ est s\u00e9par\u00e9 par un double ##) pour faciliter l&#8217;extraction des donn\u00e9es :<\/li>\n<li><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-11986\" src=\"https:\/\/www.auditsi.eu\/wp-content\/uploads\/2023\/11\/PQ-Pages_PDF-Fusion-champs.png\" alt=\"PQ Pages_PDF Fusion champs\" width=\"819\" height=\"233\" srcset=\"https:\/\/www.auditsi.eu\/wp-content\/uploads\/2023\/11\/PQ-Pages_PDF-Fusion-champs.png 819w, https:\/\/www.auditsi.eu\/wp-content\/uploads\/2023\/11\/PQ-Pages_PDF-Fusion-champs-300x85.png 300w, https:\/\/www.auditsi.eu\/wp-content\/uploads\/2023\/11\/PQ-Pages_PDF-Fusion-champs-768x218.png 768w, https:\/\/www.auditsi.eu\/wp-content\/uploads\/2023\/11\/PQ-Pages_PDF-Fusion-champs-730x208.png 730w\" sizes=\"auto, (max-width: 819px) 100vw, 819px\" \/>#&#8221;Lignes filtr\u00e9es&#8221; = Table.SelectRows : cette ligne de la requ\u00eate filtre sur toutes les lignes qui contiennent les identifiants des deux donn\u00e9es recherch\u00e9es &#8220;<span style=\"background-color: #ffff00;\">##VIN:<\/span>&#8221; et &#8220;<span style=\"background-color: #ffff00;\">!MT.INC:<\/span>&#8220;<\/li>\n<\/ul>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-11987\" src=\"https:\/\/www.auditsi.eu\/wp-content\/uploads\/2023\/11\/PQ-Pages_PDF-Lignes-filtrees.png\" alt=\"PQ Pages_PDF Lignes filtr\u00e9es\" width=\"555\" height=\"233\" srcset=\"https:\/\/www.auditsi.eu\/wp-content\/uploads\/2023\/11\/PQ-Pages_PDF-Lignes-filtrees.png 555w, https:\/\/www.auditsi.eu\/wp-content\/uploads\/2023\/11\/PQ-Pages_PDF-Lignes-filtrees-300x126.png 300w\" sizes=\"auto, (max-width: 555px) 100vw, 555px\" \/><\/p>\n<ul>\n<li>#&#8221;Autres colonnes supprim\u00e9es&#8221; = Table.SelectColumns : supprime tous les champs (le cas \u00e9ch\u00e9ant) autres que celui celui nomm\u00e9 Fusionn\u00e9<\/li>\n<\/ul>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-11988\" src=\"https:\/\/www.auditsi.eu\/wp-content\/uploads\/2023\/11\/PQ-Pages_PDF-Autres-colonnes-supprimees.png\" alt=\"PQ Pages_PDF Autres colonnes supprim\u00e9es\" width=\"500\" height=\"215\" srcset=\"https:\/\/www.auditsi.eu\/wp-content\/uploads\/2023\/11\/PQ-Pages_PDF-Autres-colonnes-supprimees.png 500w, https:\/\/www.auditsi.eu\/wp-content\/uploads\/2023\/11\/PQ-Pages_PDF-Autres-colonnes-supprimees-300x129.png 300w\" sizes=\"auto, (max-width: 500px) 100vw, 500px\" \/><\/p>\n<ul>\n<li>#&#8221;Duplication de la colonne&#8221; = Table.DuplicateColumn : cette ligne duplique le champ Fusionn\u00e9 :<\/li>\n<\/ul>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-11989\" src=\"https:\/\/www.auditsi.eu\/wp-content\/uploads\/2023\/11\/PQ-Pages_PDF-Duplication-colonne.png\" alt=\"PQ Pages_PDF Duplication colonne\" width=\"767\" height=\"276\" srcset=\"https:\/\/www.auditsi.eu\/wp-content\/uploads\/2023\/11\/PQ-Pages_PDF-Duplication-colonne.png 767w, https:\/\/www.auditsi.eu\/wp-content\/uploads\/2023\/11\/PQ-Pages_PDF-Duplication-colonne-300x108.png 300w, https:\/\/www.auditsi.eu\/wp-content\/uploads\/2023\/11\/PQ-Pages_PDF-Duplication-colonne-730x263.png 730w\" sizes=\"auto, (max-width: 767px) 100vw, 767px\" \/><\/p>\n<ul>\n<li>#&#8221;Texte extrait entre les d\u00e9limiteurs&#8221; = Table.TransformColumns : cette ligne nettoie les donn\u00e9es afin de n&#8217;obtenir que les num\u00e9ros VIN et le montant des garanties<\/li>\n<\/ul>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-11990\" src=\"https:\/\/www.auditsi.eu\/wp-content\/uploads\/2023\/11\/PQ-Pages_PDF-Extraction-delimiteur.png\" alt=\"PQ Pages_PDF Extraction d\u00e9limiteur\" width=\"755\" height=\"215\" srcset=\"https:\/\/www.auditsi.eu\/wp-content\/uploads\/2023\/11\/PQ-Pages_PDF-Extraction-delimiteur.png 755w, https:\/\/www.auditsi.eu\/wp-content\/uploads\/2023\/11\/PQ-Pages_PDF-Extraction-delimiteur-300x85.png 300w, https:\/\/www.auditsi.eu\/wp-content\/uploads\/2023\/11\/PQ-Pages_PDF-Extraction-delimiteur-730x208.png 730w\" sizes=\"auto, (max-width: 755px) 100vw, 755px\" \/><\/p>\n<ul>\n<li>#&#8221;Valeur remplac\u00e9e&#8221; = Table.ReplaceValue : remplace les donn\u00e9es vides par <em>Null<\/em><\/li>\n<\/ul>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-11991\" src=\"https:\/\/www.auditsi.eu\/wp-content\/uploads\/2023\/11\/PQ-Pages_PDF-Remplacement-par-null.png\" alt=\"PQ Pages_PDF Remplacement par null\" width=\"472\" height=\"191\" srcset=\"https:\/\/www.auditsi.eu\/wp-content\/uploads\/2023\/11\/PQ-Pages_PDF-Remplacement-par-null.png 472w, https:\/\/www.auditsi.eu\/wp-content\/uploads\/2023\/11\/PQ-Pages_PDF-Remplacement-par-null-300x121.png 300w\" sizes=\"auto, (max-width: 472px) 100vw, 472px\" \/><\/p>\n<ul>\n<li>#&#8221;Rempli vers le bas&#8221; = Table.FillDown : permet de remplir le num\u00e9ro VIN de haut en bas (en remplacement des valeurs <em>Null<\/em>)<\/li>\n<\/ul>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-11992\" src=\"https:\/\/www.auditsi.eu\/wp-content\/uploads\/2023\/11\/PQ-Pages_PDF-Remplissage.png\" alt=\"PQ Pages_PDF Remplissage\" width=\"469\" height=\"187\" srcset=\"https:\/\/www.auditsi.eu\/wp-content\/uploads\/2023\/11\/PQ-Pages_PDF-Remplissage.png 469w, https:\/\/www.auditsi.eu\/wp-content\/uploads\/2023\/11\/PQ-Pages_PDF-Remplissage-300x120.png 300w\" sizes=\"auto, (max-width: 469px) 100vw, 469px\" \/><\/p>\n<ul>\n<li>#&#8221;Lignes filtr\u00e9es1&#8243; = Table.SelectRows : supprime toutes les lignes pour lesquelles le montant est <em>Null<\/em><\/li>\n<\/ul>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-11993\" src=\"https:\/\/www.auditsi.eu\/wp-content\/uploads\/2023\/11\/PQ-Pages_PDF-Lignes-filtrees1.png\" alt=\"PQ Pages_PDF Lignes filtr\u00e9es1\" width=\"669\" height=\"233\" srcset=\"https:\/\/www.auditsi.eu\/wp-content\/uploads\/2023\/11\/PQ-Pages_PDF-Lignes-filtrees1.png 669w, https:\/\/www.auditsi.eu\/wp-content\/uploads\/2023\/11\/PQ-Pages_PDF-Lignes-filtrees1-300x104.png 300w\" sizes=\"auto, (max-width: 669px) 100vw, 669px\" \/><\/p>\n<ul>\n<li>#&#8221;Colonnes renomm\u00e9es&#8221; = Table.RenameColumns : renomme les deux champs en <span style=\"background-color: #ffff00;\">VIN<\/span> et <span style=\"background-color: #ffff00;\">MT_INC<\/span><\/li>\n<\/ul>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-11994\" src=\"https:\/\/www.auditsi.eu\/wp-content\/uploads\/2023\/11\/PQ-Pages_PDF-Colonnes-renommees.png\" alt=\"PQ Pages_PDF Colonnes renomm\u00e9es\" width=\"546\" height=\"193\" srcset=\"https:\/\/www.auditsi.eu\/wp-content\/uploads\/2023\/11\/PQ-Pages_PDF-Colonnes-renommees.png 546w, https:\/\/www.auditsi.eu\/wp-content\/uploads\/2023\/11\/PQ-Pages_PDF-Colonnes-renommees-300x106.png 300w\" sizes=\"auto, (max-width: 546px) 100vw, 546px\" \/><\/p>\n<p style=\"text-align: justify;\">Le r\u00e9sultat de tous ces calculs est retranscrit dans un <strong>tableau Excel<\/strong> : 128 avoirs pour un total de 51 030,37 \u20ac :<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-11984\" src=\"https:\/\/www.auditsi.eu\/wp-content\/uploads\/2023\/11\/AVIS-CREDIT-GARANTIE-Excel.png\" alt=\"AVIS CREDIT GARANTIE Excel\" width=\"397\" height=\"573\" srcset=\"https:\/\/www.auditsi.eu\/wp-content\/uploads\/2023\/11\/AVIS-CREDIT-GARANTIE-Excel.png 397w, https:\/\/www.auditsi.eu\/wp-content\/uploads\/2023\/11\/AVIS-CREDIT-GARANTIE-Excel-208x300.png 208w\" sizes=\"auto, (max-width: 397px) 100vw, 397px\" \/><\/p>\n<p>Ce qui correspond bien \u00e0 la derni\u00e8re page du fichier PDF (synth\u00e8se des pages pr\u00e9c\u00e9dentes) :<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-11982\" src=\"https:\/\/www.auditsi.eu\/wp-content\/uploads\/2023\/11\/AVIS-CREDIT-GARANTIE-total.png\" alt=\"AVIS CREDIT GARANTIE total\" width=\"1240\" height=\"174\" srcset=\"https:\/\/www.auditsi.eu\/wp-content\/uploads\/2023\/11\/AVIS-CREDIT-GARANTIE-total.png 1240w, https:\/\/www.auditsi.eu\/wp-content\/uploads\/2023\/11\/AVIS-CREDIT-GARANTIE-total-300x42.png 300w, https:\/\/www.auditsi.eu\/wp-content\/uploads\/2023\/11\/AVIS-CREDIT-GARANTIE-total-1024x144.png 1024w, https:\/\/www.auditsi.eu\/wp-content\/uploads\/2023\/11\/AVIS-CREDIT-GARANTIE-total-768x108.png 768w, https:\/\/www.auditsi.eu\/wp-content\/uploads\/2023\/11\/AVIS-CREDIT-GARANTIE-total-730x102.png 730w\" sizes=\"auto, (max-width: 1240px) 100vw, 1240px\" \/><\/p>\n<p style=\"text-align: justify;\">Le classeur Excel g\u00e9n\u00e9r\u00e9 par la macro est \u00e0 enregistrer sous le nom de votre choix&#8230;<\/p>\n<p><strong><em>Code source int\u00e9gral :<\/em><\/strong><\/p>\n<p>Le code source comprend des commentaires expliquant son fonctionnement.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">'---------------------------------------------------------------------------------------\r\n'PROGRAMME DE TRAITEMENT DES RECAPITULATIFS MENSUELS DES AVIS DE CREDIT\r\n'Un avis de cr\u00e9dit (ou avoir) de garantie est \u00e9mis par les constructeurs Citro\u00ebn ou Peugeot\r\n'pour rembourser le concessionnaire qui a r\u00e9par\u00e9 un v\u00e9hicule d'un client qui a connu une\r\n'panne pendant la p\u00e9riode de garantie\r\n'Le constructeur envoie tous les mois au concessionnaire un \u00e9tat r\u00e9capitulatif de tous les\r\n'avoirs de la p\u00e9riode\r\n'Cette macro r\u00e9cup\u00e8re le num\u00e9ro VIN et le montant de la garantie associ\u00e9e (MO+PR) dans un\r\n'tableau Excel\r\n'\r\n'Ecrit par Beno\u00eet RIVIERE 11\/2023 (sauf code tiers)\r\n'Plus d'infos : https:\/\/www.auditsi.eu\/?p=11980\r\n'---------------------------------------------------------------------------------------\r\n\r\n\r\nOption Explicit\r\n\r\n\r\n'---------------------------------------------------------------------------------------\r\n'Cette fonction d\u00e9termine le nombre de pages d'un fichier PDF\r\n'Code tiers, source :\r\n'https:\/\/excel-downloads.com\/threads\/vba-compter-le-nombre-de-page-dun-pdf-resolu.164261\/\r\n'---------------------------------------------------------------------------------------\r\nFunction GetPageNum(PDF_File As Variant)\r\n    'Haluk 19\/10\/2008\r\n    Dim FileNum As Long\r\n    Dim strRetVal As String\r\n    Dim RegExp\r\n    Set RegExp = CreateObject(\"VBscript.RegExp\")\r\n    RegExp.Global = True\r\n    RegExp.Pattern = \"\/Type\\s*\/Page[^s]\"\r\n    FileNum = FreeFile\r\n    Open PDF_File For Binary As #FileNum\r\n    strRetVal = Space(LOF(FileNum))\r\n    Get #FileNum, , strRetVal\r\n    Close #FileNum\r\n    GetPageNum = RegExp.Execute(strRetVal).Count\r\nEnd Function\r\n\r\n\r\n'---------------------------------------------------------------------------------------\r\n'Cette routine combine toutes les pages du PDF s\u00e9lectionn\u00e9 dans Power Query et en\r\n'extrait les donn\u00e9es VIN et montant de garantie\r\n'puis les restituent dans un tableau Excel\r\n'---------------------------------------------------------------------------------------\r\nSub PQ_PDF_RECAP_AVIS_CREDIT()\r\n    'D\u00e9claration des variables\r\n    Dim NbPages As Integer\r\n    Dim FichierPDF As Variant\r\n    Dim i As Integer\r\n    Dim Formule As String\r\n    \r\n    'S\u00e9lection du fichier PDF \u00e0 traiter (cf https:\/\/www.auditsi.eu\/?p=6456)\r\n    FichierPDF = Application.GetOpenFilename(\"Fichiers PDF (*.pdf),*.pdf,Tous les fichiers (*.*),*.* \", 1, \"S\u00e9lectionnez le r\u00e9capitulatif des avis de cr\u00e9dit \u00e0 traiter\", , False)\r\n    '---Arr\u00eate la routine si l'utilise ne s\u00e9lectionne aucun fichier (touche Echap ou bouton Annuler)\r\n    If FichierPDF = False Then Exit Sub\r\n    \r\n    'Cr\u00e9e un nouveau classeur Excel pour accueillir les donn\u00e9es\r\n    Workbooks.Add\r\n    \r\n    'D\u00e9termine le nombre de pages du fichier PDF\r\n    'et retire 1 : la derni\u00e8re est une page qui totalise tous les avis de cr\u00e9dit du mois et qui ne contient pas les donn\u00e9es recherch\u00e9es\r\n    NbPages = GetPageNum(FichierPDF) - 1\r\n    \r\n    'POWER QUERY :\r\n    '1. Int\u00e9gration de toutes les pages du PDF (boucle i=1 To NbPages...)\r\n    For i = 1 To NbPages\r\n        'La variable Formule calcule \u00e0 la vol\u00e9e la requ\u00eate M permettant d'int\u00e9grer chaque page du PDF dans Power Query\r\n        '---Ouverture de la requ\u00eate\r\n        Formule = \"let\" &amp; Chr(13) &amp; \"\" &amp; Chr(10)\r\n        '---Source des donn\u00e9es = FichierPDF...\r\n        Formule = Formule &amp; \" Source = Pdf.Tables(File.Contents(\"\"\" &amp; FichierPDF &amp; \"\"\"), [Implementation=\"\"1.3\"\"]),\" &amp; Chr(13) &amp; \"\" &amp; Chr(10)\r\n        '---... et page num\u00e9rot\u00e9e i\r\n        Formule = Formule &amp; \" Page\" &amp; i &amp; \" = Source{[Id=\"\"Page\" &amp; Format(i, \"000\") &amp; \"\"\"]}[Data]\" &amp; Chr(13) &amp; \"\" &amp; Chr(10)\r\n        Formule = Formule &amp; \"in\" &amp; Chr(13) &amp; \"\" &amp; Chr(10)\r\n        Formule = Formule &amp; \" Page\" &amp; i\r\n        'Cr\u00e9e une requ\u00eate pour chacune des pages\r\n        ActiveWorkbook.Queries.Add Name:=\"Page\" &amp; Format(i, \"000\"), Formula:=Formule\r\n    Next i\r\n\r\n    '2. Combinaison de toutes les pages en une seule requ\u00eate\r\n    'Cr\u00e9ation du texte de la requ\u00eate\r\n    Formule = \"let\" &amp; Chr(13) &amp; \"\" &amp; Chr(10)\r\n    Formule = Formule &amp; \" Source = Table.Combine({\"\r\n    '---Boucle successivement sur chacune des pages d\u00e9tect\u00e9es\r\n    For i = 1 To NbPages\r\n        Formule = Formule &amp; \"Page\" &amp; Format(i, \"000\")\r\n        'Chaque Page est s\u00e9par\u00e9e des autres par une virgule\r\n        If i &lt;&gt; NbPages Then Formule = Formule &amp; \",\"\r\n    Next i\r\n    Formule = Formule &amp; \"}),\" &amp; Chr(13) &amp; \"\" &amp; Chr(10)\r\n    '---Modification du format des champs de donn\u00e9es : texte\r\n    Formule = Formule &amp; \" #\"\"Type modifi\u00e9\"\" = Table.TransformColumnTypes(Source,{{\"\"Column4\"\", type text}, {\"\"Column7\"\", type text}, {\"\"Column12\"\", type text}, {\"\"Column16\"\", type text}, {\"\"Column17\"\", type text}}),\" &amp; Chr(13) &amp; \"\" &amp; Chr(10)\r\n    '---Tous les champs de donn\u00e9es sont fusionn\u00e9s en un seul et d\u00e9limit\u00e9s les uns des autres par ##\r\n    Formule = Formule &amp; \" #\"\"Colonnes fusionn\u00e9es\"\" = Table.CombineColumns(Table.TransformColumnTypes(#\"\"Type modifi\u00e9\"\", {{\"\"Column7\"\", type text}, {\"\"Column12\"\", type text}, {\"\"Column16\"\", type text}, {\"\"Column17\"\", type text}}, \"\"fr-FR\"\"),{\"\"Column1\"\", \"\"Column2\"\", \"\"Column3\"\", \"\"Column4\"\", \"\"Column5\"\", \"\"Column6\"\", \"\"Column7\"\", \"\"Column8\"\", \"\"Column9\"\", \"\"Column10\"\", \"\"Column11\"\", \"\"Column12\"\", \"\"Column13\"\", \"\"Column14\"\", \"\"Column15\"\", \"\"Column16\"\", \"\"Column17\"\"},Combiner.CombineTextByDelimiter(\"\"##\"\", QuoteStyle.None),\"\"Fusionn\u00e9\"\"),\" &amp; Chr(13) &amp; \"\" &amp; Chr(10)\r\n    '---Filtre les lignes contenant le n\u00b0 VIN (libell\u00e9 ##VIN:) ou le montant total (libell\u00e9 !MT.INC:)\r\n    Formule = Formule &amp; \" #\"\"Lignes filtr\u00e9es\"\" = Table.SelectRows(#\"\"Colonnes fusionn\u00e9es\"\", each Text.Contains([Fusionn\u00e9], \"\"##VIN:\"\") or Text.Contains([Fusionn\u00e9], \"\"!MT.INC:\"\")),\" &amp; Chr(13) &amp; \"\" &amp; Chr(10)\r\n    '---Le cas \u00e9ch\u00e9ant supprimes les autres champs\r\n    Formule = Formule &amp; \" #\"\"Autres colonnes supprim\u00e9es\"\" = Table.SelectColumns(#\"\"Lignes filtr\u00e9es\"\",{\"\"Fusionn\u00e9\"\"}),\" &amp; Chr(13) &amp; \"\" &amp; Chr(10)\r\n    '---Duplique la colonne\r\n    Formule = Formule &amp; \" #\"\"Duplication de la colonne\"\" = Table.DuplicateColumn(#\"\"Autres colonnes supprim\u00e9es\"\", \"\"Fusionn\u00e9\"\", \"\"Fusionn\u00e9 - Copier\"\"),\" &amp; Chr(13) &amp; \"\" &amp; Chr(10)\r\n    '---Extrait le num\u00e9ro VIN (donn\u00e9e d\u00e9limit\u00e9e par ##VIN: et ##)\r\n    Formule = Formule &amp; \" #\"\"Texte extrait entre les d\u00e9limiteurs\"\" = Table.TransformColumns(#\"\"Duplication de la colonne\"\", {{\"\"Fusionn\u00e9\"\", each Text.BetweenDelimiters(_, \"\"##VIN:\"\", \"\"##\"\"), type text}}),\" &amp; Chr(13) &amp; \"\" &amp; Chr(10)\r\n    '---Extrait le montant (donn\u00e9e d\u00e9limit\u00e9e par !MT.INC:#### et Espace)\r\n    Formule = Formule &amp; \" #\"\"Texte extrait entre les d\u00e9limiteurs1\"\" = Table.TransformColumns(#\"\"Texte extrait entre les d\u00e9limiteurs\"\", {{\"\"Fusionn\u00e9 - Copier\"\", each Text.BetweenDelimiters(_, \"\"!MT.INC:####\"\", \"\" \"\"), type text}}),\" &amp; Chr(13) &amp; \"\" &amp; Chr(10)\r\n    '---Convertit le champ montant en un nombre d\u00e9cimal\r\n    Formule = Formule &amp; \" #\"\"Type modifi\u00e91\"\" = Table.TransformColumnTypes(#\"\"Texte extrait entre les d\u00e9limiteurs1\"\",{{\"\"Fusionn\u00e9 - Copier\"\", type number}}),\" &amp; Chr(13) &amp; \"\" &amp; Chr(10)\r\n    '---Remplace les donn\u00e9es manquantes par Null\r\n    Formule = Formule &amp; \" #\"\"Valeur remplac\u00e9e\"\" = Table.ReplaceValue(#\"\"Type modifi\u00e91\"\",\"\"\"\",null,Replacer.ReplaceValue,{\"\"Fusionn\u00e9\"\"}),\" &amp; Chr(13) &amp; \"\" &amp; Chr(10)\r\n    '---Remplit les donn\u00e9es vers le bas\r\n    Formule = Formule &amp; \" #\"\"Rempli vers le bas\"\" = Table.FillDown(#\"\"Valeur remplac\u00e9e\"\",{\"\"Fusionn\u00e9\"\"}),\" &amp; Chr(13) &amp; \"\" &amp; Chr(10)\r\n    '---Supprime les lignes dont le montant est Null\r\n    Formule = Formule &amp; \" #\"\"Lignes filtr\u00e9es1\"\" = Table.SelectRows(#\"\"Rempli vers le bas\"\", each ([#\"\"Fusionn\u00e9 - Copier\"\"] &lt;&gt; null)),\" &amp; Chr(13) &amp; \"\" &amp; Chr(10)\r\n    '---Renomme les deux champs en VIN et MT_INC\r\n    Formule = Formule &amp; \" #\"\"Colonnes renomm\u00e9es\"\" = Table.RenameColumns(#\"\"Lignes filtr\u00e9es1\"\",{{\"\"Fusionn\u00e9\"\", \"\"VIN\"\"}, {\"\"Fusionn\u00e9 - Copier\"\", \"\"MT_INC\"\"}})\" &amp; Chr(13) &amp; \"\" &amp; Chr(10)\r\n    '---Cl\u00f4ture la requ\u00eate M\r\n    Formule = Formule &amp; \"in\" &amp; Chr(13) &amp; \"\" &amp; Chr(10)\r\n    Formule = Formule &amp; \" #\"\"Colonnes renomm\u00e9es\"\"\"\r\n    'Ajoute la requ\u00eate\r\n    ActiveWorkbook.Queries.Add Name:=\"Pages_PDF\", Formula:=Formule\r\n\r\n    '3. Cr\u00e9e le tabeau Excel \u00e0 partir du r\u00e9sultat de la requ\u00eate M Pages_PDF\r\n    Application.CutCopyMode = False\r\n    With ActiveSheet.ListObjects.Add(SourceType:=0, Source:=\"OLEDB;Provider=Microsoft.Mashup.OleDb.1;Data Source=$Workbook$;Location=Pages_PDF;Extended Properties=\"\"\"\"\" _\r\n        , Destination:=Range(\"$A$1\")).QueryTable\r\n        .CommandType = xlCmdSql\r\n        .CommandText = Array(\"SELECT * FROM [Pages_PDF]\")\r\n        .RowNumbers = False\r\n        .FillAdjacentFormulas = False\r\n        .PreserveFormatting = True\r\n        .RefreshOnFileOpen = False\r\n        .BackgroundQuery = True\r\n        .RefreshStyle = xlInsertDeleteCells\r\n        .SavePassword = False\r\n        .SaveData = True\r\n        .AdjustColumnWidth = True\r\n        .RefreshPeriod = 0\r\n        .PreserveColumnInfo = True\r\n        .ListObject.DisplayName = \"Pages_PDF\"\r\n        .Refresh BackgroundQuery:=False\r\n    End With\r\nEnd Sub\r\n<\/pre>\n<p style=\"text-align: justify;\">___<\/p>\n<p style=\"text-align: justify;\">Approfondir le sujet : <a href=\"https:\/\/www.auditsi.eu\/?p=9737\">extraire des tableaux de donn\u00e9es depuis une photo<\/a> \/ <a href=\"https:\/\/www.auditsi.eu\/?p=8590\">importer de donn\u00e9es d\u2019un fichier ASCII \/ CSV (exemple avec un FEC)<\/a> \/&nbsp;En savoir plus sur l\u2019<a href=\"https:\/\/www.auditsi.eu\/?tag=analyse-de-donnees\">analyse de donn\u00e9es<\/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 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=\"Power%20Query%20%28Excel%29%20%3A%20r%C3%A9cup%C3%A9rer%20des%20donn%C3%A9es%20contenues%20dans%20un%20fichier%20PDF\";<\/script><script type=\"text\/javascript\" src=\"https:\/\/static.hupso.com\/share\/js\/counters.js\"><\/script><!-- Hupso Share Buttons --><\/div>","protected":false},"excerpt":{"rendered":"<p>Les fichiers PDF de sources diverses (factures, liasses fiscales, plaquettes des comptes annuels&#8230;) contiennent de nombreuses donn\u00e9es. L&#8217;extraction de donn\u00e9es de documents PDF est facilit\u00e9e par le module Power Query d&#8217;Excel. Pour autant, la collecte de ces donn\u00e9es n&#8217;est pas toujours tr\u00e8s intuitive. Cet article s&#8217;appuie sur un exemple concret. Un concessionnaire automobile est amen\u00e9 &#8230;<\/p>\n<p><a href=\"https:\/\/www.auditsi.eu\/?p=11980\" class=\"more-link\">Continue reading &lsquo;Power Query (Excel) : r\u00e9cup\u00e9rer des donn\u00e9es contenues dans un fichier PDF&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=\"Power%20Query%20%28Excel%29%20%3A%20r%C3%A9cup%C3%A9rer%20des%20donn%C3%A9es%20contenues%20dans%20un%20fichier%20PDF\";<\/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":[544,8,2680,215],"tags":[2709,2710,815,1770,372,3079,3080,2525,307,294,3069,1700,2706,2712,2803,2902,2711,373,2708,2719,987,3068,3071,3074,3077,3078,3076,3073,3072,3075,1641,3070],"class_list":["post-11980","post","type-post","status-publish","format-standard","hentry","category-distribution-automobile-secteurs-dactivite","category-extractions-de-donnees","category-m","category-vba","tag-combine","tag-queries-add","tag-automatisation","tag-citroen","tag-concessionnaire","tag-ddg","tag-ddr","tag-facture","tag-fichier-pdf","tag-filtres","tag-garantie","tag-getopenfilename","tag-langage-m","tag-let-in","tag-mode-tableau","tag-null","tag-pdf-tables","tag-peugeot","tag-power-query","tag-requete","tag-separateur","tag-stellantis","tag-table-combine","tag-table-duplicatecolumn","tag-table-filldown","tag-table-renamecolumns","tag-table-replacevalue","tag-table-selectcolumns","tag-table-selectrows","tag-table-transformcolumns","tag-vba","tag-vin"],"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\/11980","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=11980"}],"version-history":[{"count":7,"href":"https:\/\/www.auditsi.eu\/index.php?rest_route=\/wp\/v2\/posts\/11980\/revisions"}],"predecessor-version":[{"id":11998,"href":"https:\/\/www.auditsi.eu\/index.php?rest_route=\/wp\/v2\/posts\/11980\/revisions\/11998"}],"wp:attachment":[{"href":"https:\/\/www.auditsi.eu\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=11980"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.auditsi.eu\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=11980"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.auditsi.eu\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=11980"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}