Manipulation de fichier Excel : utilisez Python

Le besoin était simple, à partir d’un fichier de vente global à une société, il fallait proposer un fichier spécifique par commercial pour qu’il puisse saisir son prévisionnel propre à chacun de ses clients … puis proposer un outil permettant de réaliser la synthèse de ses documents particuliers.

La manipulation de fichier Excel via openpyxl

Les fonctions de base :

L’ouverture d’un fichier excel avec cette libraire se fait comme dans la vraie vie. Il faut ouvrir le fichier : load_workbook puis sélectionner l’onglet dans lequel on souhaite travailler . Les onglets sont stockés sous forme de dictionnaire, il suffit de donc le charger en utilisant comme clé le nom de l’onglet workbook[‘nomOnglet’].

Lire une valeur : Il suffit de repartir de l’objet utilisé pour récupérer l’onglet. Les cellules sont atteignables via le couple Ligne/colonne. Par exemple, pour récupérer la valeur en F13, il suffit de faire : val = onglet[‘F13’].value

def getValueNumerique(ong, key):    
   valT = 0    
   val  = ong[key].value    
   if (isinstance(val, Number)):
      valT =  val   
return valT

Enregistrer une valeur peut être réaliser en faisant une simple affectation : onglet[‘F13’] = val

Ajouter/dupliquer un onglet :         wb.copy_worksheet(wb[‘CC’])

Enregistrer le fichier final : wb.save(« nouveauNom »)

De un vers plusieurs : Python via Panda pour un éclatement rapide

La difficulté la plus grande est de trouver l’élément sur lequel vos filtres vont pouvoir s’appuyer. Dans mon contexte, chaque vente était relié à son représentant. La sélection des données fut donc de :

  • Filtrer sur la période de temps souhaité :         listeCommade38_2018 =   df_filtre_soc[( (df_filtre_soc[« MOIS_FACT »] >= 201800.) & (df_filtre_soc[« MOIS_FACT »] <= 201900.)  )]
  • Puis, après construit la liste des représentants, boucler dessus afin de ne traiter que les ventes du représentant en cours de traitement :     df_filtre = df[(df[« CODE_REPRESENTANT »] == representant_ref)]
  • Dans certain cas, nous n’avons pas besoin que d’une valeur, mais d’une combinaison de valeur. Dans ce cas, la fonction query facilite les regroupements d’information :   m2019 =   (liste_2019_cc_filtre.query(‘@pp.liste_ref in CODE_ART’))[« QTE_EXPE »]
  • On peut ensuite appliquer des fonctions sur le résultat obtenu : nbProd_2019 = m2019.sum()

De plusieurs vers un : une simple routine en Python

Tout aussi simple. Pour identifier l’ensemble des fichiers résultats, la commande glob.glob(path) permet de retrouver un ensemble de fichier correspondant à un dossier et possédant un pattern exploitable.

Ensuite, il suffit d’ouvrir chacun des fichiers, de retrouver l’onglet de synthèse, puis de lire les données calculée via macro. Attention, afin d’avoir la valeur et non la méthode de la macro, il faut passer des arguments à la fonction d’ouverture de document excel :     wb = load_workbook(fich, read_only=False, keep_vba=True,  data_only=True).

Dans mon cas, les données étant réparties en fonction d’un template fixe, j’ai préféré passer par un dictionnaire pour faciliter l’identification des données à consulter :

totaux ={
    'F7' : 0,
    'F8' : 0,
    'F9' : 0,
    'F13' : 0,
    'F14' : 0,
    'F15' : 0,
    'F16' : 0
}

Il suffit ensuite de boucler sur le dictionnaire, pour réaliser, en une boucle, la lecture de l’ensemble des données :

def rechercheOngletSynthese(wb, sommeTige):
    synth =  wb['Synthese']

    for key in totaux:
        val  = synth[key].value  

Une fois les valeurs obtenues, il n’y a plus qu’à construire le fichier résultat (basé une fois de plus sur un template excel.

wb = load_workbook(fichR, read_only=False, keep_vba=True,  data_only=True)

# On va dans l'onglet synthèse
synth =  wb['Synthese']
for key in totaux:
    synth[key] = totaux[key]

sauvegarde_finale('resultat2019.xls' , wb)

Au final, avec deux scripts, nous pouvons automatiser la génération des fichiers à faire remplir, puis la construction de la synthèse. Le temps de développement est relativement cours (le plus long fut la prise du résultat à produire). De plus, le résultat pouvant être produit à la demande, il est très simple de fournir des résultats intermédiaire … le temps que l’ensemble des fichiers reviennent après leur saisie.

Liste des imports utiles :

import csv
import pandas as pd
import produit 
import  re as Regex

#Pour le traitement des fichiers excels
from openpyxl import Workbook
from openpyxl import load_workbook
#Pour la vérification des nombres
from numbers import Number

# Pour les fichiers
import os.path
import glob
from pathlib import Path

import unicodedata

Url :

https://pypi.org/project/openpyxl/

https://pandas.pydata.org/

Un modèle de formulaire dynamique en Python / Django

Le concept : Un n-ième outil de création de formulaire

Le sujet n’est pas réellement innovant : il doit exister autant de site de formulaire dynamique que de développeur  … Pourtant, à chaque nouveau développement, il est rare de trouver l’outil, le module, qui va permettre de ne pas développer son modèle de formulaire. Il manque souvent, la fonctionnalité, ou le paramétrage qui va permettre d’avoir le paramétrage ou la personnalisation nécessaire.  Le principe de ce développement ne sera donc pas de faire le module de formulaire le plus complet possible … mais au contraire, de proposer un outil simple, robuste qui pourra être utilisé tel quel … ou étendu pour des besoins spécifiques.

L’innovation : Penser directement pour l’exploitation des résultats

En effet, un formulaire, quel qu’il soit n’est utile que si l’exploitation des résultats est possible.  L’objectif de ce développement sera donc de fournir l’ensemble des outils permettant la conception et l’utilisation d’un formulaire mais également, ceux qui permettent une exploitation ou un export des résultats.

Le mode de distribution

Sur ce point,  je vais essayer d’être le plus complet possible afin que tous puisse y trouver leur compte.  L’objectif sera donc de proposer :

  • Un service en ligne complet et autonome.
  • Une Api, permettant à des solutions de personnaliser complètement une partie de l’interface tout profitant d’un backend et de solution d’export existante.
  • Sous forme de brique logicielle autonome pouvant être déployant directement au sein d’une infrastructure
  • et pour ceux qui veulent aller plus loin dans la personnalisation, directement les sources de la solution (open ou closed source) en fonction de la cible du logiciel.

la stack technique

Pour le moment, rien n’est définitif … Mais le premier jet sera basé sur Python Django + un serveur MariaDB.  L’objectif de cette stack est de permettre d’obtenir un premier résultat rapide. De plus, ce choix permet de jolies évolutions. 

La cerise sur le gâteau est que Python est Le langage a suivre pour le moment. Ce choix est donc à la fois pour l’évolution du produit .. que pour mon évolution.