salut les gens et bonne année !
je passe juste pour un petit com...
d'abord, merci de partager votre boulot !
je "m'amuse" avec des csv de Société Générale en ce moment et cela me sert à apprendre python...
depuis pas mal d'années, je récupère régulièrement ces csv (et les xls équivalent par sureté) dont beaucoup de lignes sont en doublon car les dates de téléchargement sont fluctuantes (la faute à moi). je fais tout cela avec 3 comptes...
en règle générale, je fais ça avec libreoffice calc :
j'importe les csv, regroupe, en supprimant les doublons, éventuellement j'ajoute les lignes que j'aurais zappé car trop attendu (à faire tous les 3 mois max, mais des fois je zappe), puis j'ajoute des colonnes pour faire mes ventilations, j'utilise les filtres pour faire le point et le copier / coller pour aller plus vite à la saisie,... puis enfin, je fais un tableau croisé dynamique pour chaque compte voire, depuis quelques années, pour les 3 comptes en même temps...
sous calc tout cela me prend l’équivalent de 3 jours répartis sur une à deux semaines en fonction de ma flemme; c'est le temps que cela me prends pour faire notre "bilan" personnel.
NB : certaines années le compte principal comprenait jusqu'à 800 lignes ; aujourd'hui c'est tout au plus la moitié...
j'ai rêvé que je pourrais faire tout cela en python cette année mais j'ai peur de ne pas avoir assez de temps ou de patience pour aller jusqu'au bout...
peut importe, la première partie est déjà réglée à grand coup de list et de set 😉 ; j'ai mes 3 csv utilisable et ce qui me prend les autres années 2 à 3 heures est digéré par le script en moins d'une seconde ! :cool:
voilà c'était pour vous faire part de mon retour d'expérience... et surtout la raison de ce choix des csv : c'est lisible, compréhensible (dans les 2 sens du terme :lol: ) et ça le restera des années encore là où tous les logiciels de compta et leur format proprio que j'ai vu passé depuis ma scolarité (88) ont rejoint les fossiles des dinosaures...
... ah oui, un peu de technique : les csv :
XXXXXX.csv: ISO-8859 text, with CRLF line terminators
l'entête des fichiers originaux anonymisée:
="XXXXXXXXXX";02/01/2018;;XX;09/03/2018;0000,00 EUR
Date de l'opération;Libellé;Détail de l'écriture;Montant de l'opération;Devise
2 lignes d'exemple : (des frais bancaires :lol: )
17/02/2018;COTISATION JAZZ;COTISATION JAZZ ;-8,50;EUR
17/02/2018;OPTION TRANQUILLIT;OPTION TRANQUILLITE ;-0,65;EUR
NB : entre autre joyeusetés, que je corrige dans la foulée :
les doubles espaces,
les dates que je met dans mes scripts au format AAAA-MM-JJ pour faciliter le classement
et les montants dont je remplace les virgules par des points pour en faire des float
et, si cela vous intéresse, voilà où j'en suis (la partie 2 : bilan):
#!/usr/bin/env python3
# -*- coding: UTF8 -*-
# ***************************************************************
# ***************************************************************
# ***************************************************************
# FONCTIONS
def virer_doubles_espaces(ligne):
# >>>' '.join(" je fais du python".split())
# je fais du python
return ' '.join(ligne.split())
# la_ligne = " Monty Python "
def virer_espaces_debut_et_fin(ligne):
return ligne.strip()
# un_test = ">" + virer_espaces_debut_et_fin(la_ligne) + "<"
# print(un_test)
def mef(montant): # montant_en_float
""" permet de convertir à la volée
les montants (strings) en float
avec un point à la place de la virgule """
return float(montant.replace(',', '.'))
# ***************************************************************
# ***************************************************************
# ***************************************************************
# OBJETS
class FichierCsvBq:
def __init__(self, fichier):
self.fichier = fichier
self.lignes = []
self.nbre_lignes = 0
self.champs = []
self.nbre_champs = 0
self.charger(fichier)
def __str__(self):
out = 30*'-' + '\n' + \
"Champs :" + '\n' + str(self.champs) + '\n' + \
str(self.nbre_lignes) + ' lignes' + '\n' + \
str(self.lignes)
30*'-'
return out
def charger(self, un_fichier):
with open(un_fichier,'r') as f:
donnees = f.read()
lignes = [ virer_doubles_espaces(l) for l in donnees.split('\n') if l != "" ]
""" je passe les noms de champs depuis la première ligne en liste et j'ajoute un élément nommé tags"""
self.champs = lignes[0].split(';') + ['tags']
""" je compte les champs et met la valeur dans une variable accessible """
self.nbre_champs = len(self.champs) # utile ??? ATTENTION mise à jour si ajout de ligne
""" je supprime l'entete qui contient les champs """
lignes.pop(0)
""" chaque ligne est éclatée en une liste dont je vire les espaces de début et de fin
puis j'ajoute un élément set pour mettre les tags """
self.lignes = [ [x.strip() for x in l.split(';')] + [set()] for l in lignes ]
""" je met le nombre de lignes dans une variable """
self.nbre_lignes = len(self.lignes) # utile ??? ATTENTION mise à jour si ajout de ligne
def ligne(self,num_ligne):
""" affiche une ligne """
return self.lignes[num_ligne]
def champ(self,ligne, num_champ):
""" affiche un des champs de 0 à len(champs)-1 d'une ligne """
return self.lignes[num_ligne].split(';')[num_champ]
def ligne_champ(self,num_ligne, num_champ):
""" affiche un des champs de 0 à len(champs)-1 d'une ligne par indice """
return self.lignes[num_ligne][num_champ]
def afficher_un_champ_de_toutes_les_lignes(self, num_champ):
return [ x[num_champ] for x in self.lignes ]
def taguer_une_ligne(self, num_ligne, un_tag):
self.lignes[num_ligne][self.nbre_champs - 1].add(un_tag)
def supprimer_un_tag_d_une_ligne(self, num_ligne, un_tag):
self.lignes[num_ligne][self.nbre_champs - 1].remove(un_tag)
def afficher_tags_d_une_ligne(self, num_ligne):
return self.lignes[num_ligne][self.nbre_champs - 1]
def afficher_tags_vides(self):
return [ x for x in self.lignes if len(x[self.nbre_champs - 1]) == 0 ]
# return [ x for x in self.lignes if len(x[self.nbre_champs - 1]) < 2 ]
et mon if main du moment :
if __name__ == '__main__':
compteMrMme = "XXXXXXXX"
un_fichier = compteMrMme + ".csv"
f = FichierCsvBq(un_fichier)
'''
# print(f)
# print(30*'-')
# print(repr(f))
# print(30*'-')
# """ affiche toutes les lignes """
# print(f.lignes)
# """ affiche une ligne """
# print(f.lignes[0])
# print(f.ligne(0))
# """ affiche un champ d'une ligne """
# print(f.ligne_champ(0, 2))
'''
""" affiche un champ d'une ligne """
print("original" , f.ligne_champ(0, 3), "vers", mef(f.ligne_champ(0, 3)), type(mef(f.ligne_champ(0, 3))))
'''
# """ ajout de tags """
# f.taguer_une_ligne(0, "coucou")
# f.taguer_une_ligne(0, "encore")
# print(f.ligne(0))
# """ ajout d'un tag existant impossible car dans un set """
# f.taguer_une_ligne(0, "coucou")
# print(f.ligne(0))
# """ afficher les tags d'une ligne """
# print("tags de la ligne 0", f.afficher_tags_d_une_ligne(0), type(f.afficher_tags_d_une_ligne(0)))
# """ supprimmer un tag """
# f.supprimer_un_tag_d_une_ligne(0, "coucou")
# print(f.ligne(0))
'''
""" afficher_un_champ_de_toutes_les_lignes(num_champ) """
# print(f.afficher_un_champ_de_toutes_les_lignes(1)) # Lib1
# print(f.afficher_un_champ_de_toutes_les_lignes(2)) # Lib2
# print(f.afficher_un_champ_de_toutes_les_lignes(3)) # montants
def tag_les(le_num_champ, le_modele, le_tag):
""" tag une ligne en fonction d'un modèle qui peut être contenu dans un champ """
for num_ligne in range(len(f.lignes)):
if le_modele in f.lignes[num_ligne][le_num_champ]:
f.taguer_une_ligne(num_ligne, le_tag)
# print(f.lignes[num_ligne])
# TAGS DU CHAMP 1
# tag_les(1, "CHEQUE", "CHEQUE")
# tag_les(1, "CARTE", "CARTE")
# tag_les(1, "PRELEVEMENT", "PRELEVEMENT")
# tag_les(1, "ARRETE", "BANQUE")
# tag_les(1, "COTISATION JAZZ", "BANQUE")
# tag_les(1, "OPTION TRANQUILLIT", "BANQUE")
# ...
# TAGS DU CHAMP 2
# tag_les(2, "ARRETE", "BANQUE")
# tag_les(2, "COTISATION JAZZ", "BANQUE")
# tag_les(2, "OPTION TRANQUILLIT", "BANQUE")
# tag_les(2, "Regie Eau", "EAU")
# tag_les(2, "ELECTRICITE", "EDF")
# tag_les(2, "ENGIE", "EDF")
# tag_les(2, "D.G.F.I.P.", "IMPOTS")
# tag_les(2, "CHEQUE", "CHEQUE")
# tag_les(2, "ARRETE", "BANQUE")
# ...
# print(f.afficher_tags_vides())
ce matin, je me suis rendu compte que ce serais bien de mettre un index à mes lignes (quelle tache je fais !!!)
bon c'est le WE !
have fun !!!