Bonjour, je cherche actuellement à automatiser ma comptabilité informatique à l'aide de Python, pour cela je voulais utiliser le package ezodf qui de ce que j'ai lu permet de modifier des tableurs au format ods facilement.
J'ai développé ( un bien grand mot ) le code qui me permet de lire mes tableurs d'entrées, celui qui me permet de lire le tableur de sortie, malheureusement le code pour écrire dans le tableur de sortie ne fonctionne pas, et ce exclusivement sur le tableur de sortie que je demande
Je viens donc demander si ici quelqu'un a déjà utilisé cette librairie ou au moins pense pouvoir m'aider à résoudre ce problème d'écriture.
Maintenant pour la partie technique:
La version python que j'utilise : Python 3.4.2 (default, Oct 8 2014, 10:45:20) on linux (64 bits).
J'utilise Pyzo 2.3.0 comme IDE de développement, avec ezodf à la version 0.3.2
Les différentes parties de mon programme :
Les fonctions utilitaires et import de librairies
Les fonctions de lectures dans les fichiers d'entrée (factures) (données du tableur)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84 import os import sys import shutil import ezodf from datetime import datetime rep_fact="./" #Répertoire des factures (entrée) rep_stat="./" #Répertoire des statistiques (sortie) def is_int(p): try: int(p) except ValueError: return False return True def get_lex(string, dep=0): cur = '' for i in range(dep,len(string)): if string[i] in [' ', '-', '/', '\\']: return cur,i else: cur += string[i] return cur, len(string) def get_date(string): if is_int(string): return -1 list = [] curw, i = get_lex(string) while i != len(string) or curw != '': try: list.append(int(curw)) except ValueError: curw = curw.capitalize() list.append(curw) curw, i = get_lex(string,i+1) if len(list) != 3: return -1 else: if is_int(list[1]): months = ['Janvier', 'Fevrier', 'Mars', 'Avril', 'Mai', 'Juin', 'Juillet', 'Aout', 'Septembre','Octobre','Novembre','Decembre'] list[1] = months[list[1]-1] list[0],list[2]=list[2],list[0] #On remet la date dans le format "Date Mois Année" return list def sec_ecrire(odsFile, sheet, cell, data): c = odsFile.sheets[sheet].get_cell(cell) c.set_value(data) if (lire_donnee(odsFile, sheet, cell) != data): print("Write error occur in : "+odsFile.docname+" at "+sheet+" "+cell) return -1 return c.value def ecrire_donnee_stat(fichier, position, donnee): #Ecrire donnee dans le fichier sortie (stat) sec_ecrire(fichier, 1, position, donnee) def lire_donnee(fichier,sheet, position): sheet = fichier.sheets[sheet] value = sheet[position].value if value is None: return 0 return sheet[position].value def is_fact_name(string): list=[] curw,i = get_lex(string) while i != len(string) or curw != '': try: list.append(int(curw)) except ValueError: curw = curw[0].capitalize() + curw[1:] list.append(curw) curw, i = get_lex(string, i+1) if list[1] != "Facture": return False elif not is_int(list[0]): return False else: return True
Les fonctions de récupération et sauvegarde des fichiers entrées et sortie
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56 def est_facture_normale(fact): #Fonction type : True -> Normale ; False -> Loc type = str(lire_donnee(fact, 0, 'I8')) if (type.upper().find("LOC") != -1): #Type de la facture return False else: return True def date_arrivee(fact): return get_date(lire_donnee(fact,0, 'C13')) def jour_arrivee(fact): #Fonction pour récupérer le jour d'arrivée d'une facture => Fichier ODS date = get_date(lire_donnee(fact, 0, 'C13')) if date != -1: return date[0] else: return -1 def mois_arrivee(fact): #Fonction pour récupérer le mois d'une facture => Fichier ODS date = get_date(lire_donnee(fact, 0, 'C13')) if date != -1: return date[1] else: return -1 def date_depart(fact): return get_date(lire_donnee(fact,0, 'C14')) def jour_depart(fact): date = get_date(lire_donnee(fact, 0, 'C14')) if date != -1: return date[0] else: return -1 def mois_depart(fact): date = get_date(lire_donnee(fact, 0, 'C14')) if date != -1: return date[1] else: return -1 def nb_nuitee(fact): #Fonction pour récupérer le nombre de nuitées dans fact => Fichier ODS return lire_donnee(fact,0, 'G24') def nb_emplacements(fact): #Fonction pour récupérer le nombre d'emplacement dans fact => Fichier ODS return lire_donnee(fact,0, 'D17') def nb_personnes(fact): #Fonction pour récupérer le nombre de personnes dans fact => Fichier ODS return lire_donnee(fact,0, 'D20')+lire_donnee(fact,0, 'D21')+lire_donnee(fact,0, 'D22') def pays_fact(fact): s= lire_donnee(fact,0, 'H7') if is_int(s): return "" return s
Les fonction d'écriture dans le fichier sortie
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57 def get_stat_file(mois): #Fonction pour ouvrir le fichier Statistiques du mois s'il existe, sinon le créer curdir = os.getcwd() os.chdir(rep_stat) name= "Stat "+mois+" 2017.ods" if(os.path.isfile(name)): stat_file = ezodf.opendoc(name) else: stat_file = ezodf.opendoc("Sortie.ods") stat_file.saveas(name) os.chdir(curdir) return stat_file def get_factures(rep, log_file): #Fonction pour récuperer les factures, non traitées, dans le repertoire rep files = os.listdir(rep) facts = [] for file in files: print("Process file ",file, file=log_file) if (not file.endswith('.ods')) or file.endswith('FF.ods'): print("\t Not a facture", file=log_file) continue elif not is_fact_name(os.path.splitext(file)[0]): print("\t Not a facture", file=log_file) continue else: print("\t facture", file=log_file) fact = ezodf.opendoc(rep+file) cond_date = date_arrivee(fact) != -1 and date_depart(fact) != -1 cond_mois = mois_arrivee(fact) == mois_depart(fact) cond_autre=lire_donnee(fact, 0, 'G27')==lire_donnee(fact,0,'G28')=="Autre" cond_pays= pays_fact(fact).upper() in ["PAYS1","PAYS2","PAYS3"] if cond_date and cond_mois and cond_autre and cond_pays: print("\t\t facture normale !!!!", file=log_file) facts.append(fact.docname) else: print("\t\t facture anormale :", file=log_file) if not cond_date: print("\t\t\t Date incorrecte", file=log_file) if not cond_mois: print("\t\t\t Mois chevauchant", file=log_file) if not cond_autre: print("\t\t\t Données dans Autres", file=log_file) if not cond_pays: print("\t\t\t Pays non supporté", file=log_file) continue return facts def fin_traitement(rep,file, rename): #Sauvegarde, ferme et renomme file si rename == TRUE) cur = os.getcwd() os.chdir(rep) if rename: name = file.docname file.saveas(os.path.splitext(file.docname)[0]+"FF.ods") os.remove(name) else: file.save() os.chdir(cur)
La fonction principale
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48 def ecrire_arrivee(fact,stat, log_file): #Fonction pour écrire les données du jour d'arrivée (Colonne selon pays, date) date = jour_arrivee(fact) p = pays_fact(fact) ligne=0 colonne=0 # Pays1 #Determiner ligne arrivée selon première quinzaine # ou deuxieme quinzaine, et alignement sur notation info if date <= 15: ligne= (date*2+1) - 1 else: ligne= (date*2+6) - 1 if not est_facture_normale(fact): #Facture LOC ligne += 1 emp = nb_emplacements(fact) + lire_donnee(stat,1, (ligne, 2)) ecrire_donnee_stat(stat, (ligne,2), emp) if p == "Pays1": colonne = 3 elif p == "Pays2": colonne = 5 elif p == "Pays3": colonne = 7 else: print("Pays inconnu dans la feuille de stat : ", p, file=log_file) return -1 pers = nb_personnes(fact) + lire_donnee(stat,1, (ligne, colonne)) ecrire_donnee_stat(stat, (ligne,colonne), pers) return (ligne,colonne) def ecrire_sejour_entier(fact,stat, log_file): # Fonction pour écrire arrivée et nuitée date = jour_arrivee(fact) pers = nb_personnes(fact) ligne,colonne = ecrire_arrivee(fact,stat,log_file) colonne += 1 # On decale sur la rangée des nuitées for i in range(0, int(nb_nuitee(fact))): total_pers = pers + lire_donnee(stat,1, (ligne, colonne)) ecrire_donnee_stat(stat, (ligne,colonne), total_pers) if (date +i == 16 ): # On passe dans la deuxieme quinzaine ligne =37 else: ligne += 2 # On passe au jour d'après dans une quinzaine return 0
Je fournirais les fichiers ods d'entrée et sortie si besoin, sachant que les cellules que l'on manipule ne contienne que des dates, chiffres, ou chaines de caractères simples.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 def main(): log_file=open("log.txt", "a") log_file.write(str(datetime.now())+"\n") list=get_factures(rep_fact, log_file) mois_precedent="" for name in list: fact =ezodf.opendoc(name) #On récupère en interne : La facture, le fichier stat correspondant. mois_cur = mois_arrivee(fact) if mois_precedent == "": stat = get_stat_file(mois_cur) mois_precedent = mois_cur elif mois_cur != mois_precedent: fin_traitement(rep_stat, stat, False) stat = get_stat_file(mois_cur) mois_precedent = mois_cur ecrire_sejour_entier(fact,stat, log_file) #fin_traitement(rep_fact, fact, True) if name == list[len(list)-1]: fin_traitement(rep_stat, stat, False) log_file.close()
Merci à vous.
Partager