[résolu] problème accès bdd sqlite

Aide et conseils concernant AutoIt et ses outils.
Règles du forum
.
Répondre
whitewater
Niveau 1
Niveau 1
Messages : 7
Enregistré le : sam. 27 avr. 2013 15:31
Status : Hors ligne

[résolu] problème accès bdd sqlite

#1

Message par whitewater » lun. 15 juil. 2019 14:41

Bonjour,
j'ai une base de données SQLlite "code" avec 2 champs code_1 et code_2.
Un code_1 correspond à un code_2.

J'aimerai faire une requête dans Autoit pour récupéré code_2 selon code_1. Exemple de requête :

Code : Tout sélectionner

SELECT code_1 FROM code WHERE code_2 = 1000
Je teste ma requête avec DB Browser : j'ai le bon résultat, 538941 par exemple.

Je n'arrive pas à faire tourner ma requête dans Autoit, voici le code :

Code : Tout sélectionner

#include <File.au3>
#include <SQLite.au3>
#include <SQLite.dll.au3>

_SQLite_Startup(@ScriptDir & "\config\sqlite3.dll", False, 1)

If @error Then
    MsgBox($MB_SYSTEMMODAL, "SQLite Erreur", "Le fichier SQLite.dll ne peut pas être chargé.")
    Exit -1
 Else

 EndIf
ConsoleWrite("_SQLite_LibVersion=" & _SQLite_LibVersion() & @CRLF)
ConsoleWrite("_SQLite_statup=" & _SQLite_Startup() & @CRLF)

$handle_db=_SQLite_Open("code.db") ; chargement de la base de donnée

MsgBox(0,"sqlite open",@error)

_SQLite_Query($handle_db, "SELECT code_1 FROM code WHERE code_2 = 1000",$requete)
_SQLite_FetchData($requete,$resultat)

MsgBox(0,"resultat", $resultat&"   "&$resultat[0])
Je vais avoir dans la console :

Code : Tout sélectionner

_SQLite_LibVersion=3.27.2
_SQLite_statup=sqlite3.dll
Le 1er msgbox, @error après le sql_open : 0
le 2e msgbox, $résultat@error après le sql_open : vide

Le @error aprèsle sqlite_open à 0 m'indiquerait qu'autoit n'arrive pas à ouvrir la base de données.
Je ne comprend pas pourquoi.
J'ai créé cette base en ligne de commande avec sqlite3.exe à partir d'un fichier csv, 2 colonnes séparé par un ;
Sa version est la même que la librairie SQLlite : 3.27.2 (obtenu par un select sqlite_version(); dans DB Browser).

Merci pour vos pistes.
Modifié en dernier par whitewater le ven. 19 juil. 2019 09:25, modifié 1 fois.

jchd
AutoIt MVPs (MVP)
AutoIt MVPs (MVP)
Messages : 2099
Enregistré le : lun. 30 mars 2009 21:57
Localisation : Sud-Ouest de la France (43.622788,-1.260864)
Status : Hors ligne

Re: problème accès bdd sqlite

#2

Message par jchd » lun. 15 juil. 2019 19:36

J'aimerai faire une requête dans Autoit pour récupéré code_2 selon code_1. Exemple de requête :
La requête fait exactement le contraire : récupère le code_1 en fonction d'un code_2.

Le succès de _SQLite_Open est indiqué par @error = 0 (voir l'aide). Le problème n'est donc pas là.

La table s'appelle-t-elle bien code ?
Que renvoie _SQLite_Query ? Et _SQLite_FetchData ?

Sinon ça doit fonctionner :

Code : Tout sélectionner

#include <MsgBoxConstants.au3>
#include <SQLite.au3>

_SQLite_Startup()
;~ ConsoleWrite("_SQLite_LibVersion=" & _SQLite_LibVersion() & @CRLF)	; useless
_SQLite_Open() ; open :memory: Database

_SQLite_Exec(-1, "CREATE TABLE code (code_1 int, code_2 integer primary key)")
_SQLite_Exec(-1, "INSERT INTO code VALUES (123, 1)")
_SQLite_Exec(-1, "INSERT INTO code VALUES (234, 10)")
_SQLite_Exec(-1, "INSERT INTO code VALUES (345, 100)")
_SQLite_Exec(-1, "INSERT INTO code VALUES (456, 1000)")
_SQLite_Exec(-1, "INSERT INTO code VALUES (567, 10000)")

; simple query
Local $aRow, $iRes
$iRes = _SQLite_QuerySingleRow(-1, "SELECT code_1 FROM code where code_2 = 1000", $aRow)
If $iRes = $SQLITE_OK Then
	MsgBox($MB_SYSTEMMODAL, "SQLite query result", "For code_2 = 1000, code_1 is " & $aRow[0])
Else
	MsgBox($MB_SYSTEMMODAL, "SQLite query failed", _SQLite_ErrMsg())
EndIf

; better querying way
Local $aRows, $iRows, $iCols
_SQLite_GetTable(-1, "SELECT code_1 FROM code where code_2 = 1000", $aRows, $iRows, $iCols)
If Not @error Then _ArrayDisplay($aRows)

_SQLite_Close()
_SQLite_Shutdown()
MsgBox(0,"resultat", $resultat&" "&$resultat[0])
$resultat est un tableau si la requête fonctionne, donc MsgBox n'affiche rien.
La cryptographie d'aujourd'hui c'est le taquin plus l'électricité.

whitewater
Niveau 1
Niveau 1
Messages : 7
Enregistré le : sam. 27 avr. 2013 15:31
Status : Hors ligne

Re: problème accès bdd sqlite

#3

Message par whitewater » mar. 16 juil. 2019 09:16

Bonjour jchd,

Effectivement, j'ai inversé code_1 et code_2 dans ma requête.

La table s'appelle bien code avec les champs code_1 et code_2

"Le succès de _SQLite_Open est indiqué par @error = 0 (voir l'aide). Le problème n'est donc pas là."
j'avais en-tête que le 0 était le code retour de @error et non la "return value", j'ai mal interprété l'aide :roll:

"$resultat est un tableau si la requête fonctionne, donc MsgBox n'affiche rien."

j'ai changé ma ligne en

Code : Tout sélectionner

MsgBox(0,"resultat", $resultat[0])
j'ai bien le résultat de ma requête :)

j'ai le code suivant :

Code : Tout sélectionner

#include <File.au3>
#include <SQLite.au3>
#include <SQLite.dll.au3>

_SQLite_Startup(@ScriptDir & "\config\sqlite3.dll", False, 1)

local $requete,$resultat

If @error Then
    MsgBox($MB_SYSTEMMODAL, "SQLite Erreur", "Le fichier SQLite.dll ne peut pas être chargé.")
    Exit -1
 Else

 EndIf
ConsoleWrite("_SQLite_LibVersion=" & _SQLite_LibVersion() & @CRLF)
ConsoleWrite("_SQLite_statup=" & _SQLite_Startup() & @CRLF)

$handle_db=_SQLite_Open("code.db") ; chargement de la base de donnée

_SQLite_Query($handle_db, "SELECT code_2 FROM code WHERE code_1 = 1000",$requete)

_SQLite_FetchData($requete,$resultat)

MsgBox(0,"resultat", $resultat[0])

_SQLite_Close($handle_db)
_SQLite_Shutdown()
Je vais avoir ce message à la console :

Code : Tout sélectionner

--> Function: _SQLite_Close
--> Error:    unable to close due to unfinalized statements or unfinished backups
est-ce que je dois modifier mon code en reprenant cette méthode pour ne pas avoir les messages à la console ?

Code : Tout sélectionner

If $iRes = $SQLITE_OK Then
	MsgBox($MB_SYSTEMMODAL, "SQLite query result", "For code_2 = 1000, code_1 is " & $aRow[0])
Else
	MsgBox($MB_SYSTEMMODAL, "SQLite query failed", _SQLite_ErrMsg())
EndIf
Merci pour ton code, il est clair.
Je n'ai pas trouvé comment faire "citer" tes messages pour les reprendre proprement.

Avatar du membre
mikell
Modérateur
Modérateur
Messages : 5892
Enregistré le : dim. 29 mai 2011 16:32
Localisation : Deep Cévennes
Status : Hors ligne

Re: problème accès bdd sqlite

#4

Message par mikell » mar. 16 juil. 2019 19:27

Je n'ai pas trouvé comment faire "citer" tes messages pour les reprendre proprement.
Normal, cette fonctionnalité a été désactivée pour le dernier message du sujet. Il faut utiliser l'icone 'quote' Image dans le message de réponse
" L'échec est le fondement de la réussite. " (Lao-Tseu )
" Plus ça rate, plus on a de chances que ça marche " (les Shadoks )

jchd
AutoIt MVPs (MVP)
AutoIt MVPs (MVP)
Messages : 2099
Enregistré le : lun. 30 mars 2009 21:57
Localisation : Sud-Ouest de la France (43.622788,-1.260864)
Status : Hors ligne

Re: problème accès bdd sqlite

#5

Message par jchd » mer. 17 juil. 2019 09:14

Quand on fait un _SQLite_Query suivi d'un ou plusieurs _SQLite_FetchData, il faut impérativement finaliser la requête avec _SQLite_QueryFinalize sinon la requête reste ouverte et SQLite ne peut pas fermer le fichier de la BD. Si des modifications ont été faites, elles seront perdues et la BD peut devenir incohérente.

L'aide US dit bien, pour _SQLite_QueryFinalize :
All prepared statements must be finalized before _SQLite_Close() is called or else the call will fail with a return code of $SQLITE_BUSY.

et pour _SQLite_Close :
Prior to calling _SQLite_Close(), the application must invoke _SQLite_QueryFinalize() for each query explicitely left unfinalized.

C'est pour cela que je préconise très fortement d'employer les fonctions de plus haut niveau : _SQLite_GetTable[2d] ou _SQLite_QuerySingleRow.
Il va falloir que je modifie les exemples de l'aide et que j'ajoute plusieurs notes à ce sujet.

Pour rester à l'abri de toute injection SQL, il est impératif d'assainir (_SQLite_FastEscape) les paramètres concaténés dans les chaînes de commande SQL si on a un quelconque doute sur la possibilité d'une manipulation malveillante. https://xkcd.com/327/

L'emploi de _SQLite_Query et suivants doit être réservé à des utilisations spéciales qui dépassent largement le cas typique.
Du fait de la lourdeur de l'usage de DllCall à répétition, lier les paramètres (_sqlite3_bind*) est très défavorable dans la grande majorité des cas.
La cryptographie d'aujourd'hui c'est le taquin plus l'électricité.

whitewater
Niveau 1
Niveau 1
Messages : 7
Enregistré le : sam. 27 avr. 2013 15:31
Status : Hors ligne

Re: problème accès bdd sqlite

#6

Message par whitewater » jeu. 18 juil. 2019 16:07

Merci Mikell pour ta réponse sur quote.
Quand on fait un _SQLite_Query suivi d'un ou plusieurs _SQLite_FetchData, il faut impérativement finaliser la requête avec _SQLite_QueryFinalize sinon la requête reste ouverte et SQLite ne peut pas fermer le fichier de la BD. Si des modifications ont été faites, elles seront perdues et la BD peut devenir incohérente.
OK. j'ai ajouté _SQLite_QueryFinalize.

j'ai amélioré mon code mais j'ai un comportement que je n'arrive pas à comprendre.
voici mon code pour le programme dont j'ai besoin.
ça ne doit pas être très joli à voir, mais il fait le job.

d'abord, explication.

le but est de récupérer un fichier texte d'un programme de facturation comprenant un code, un libellé, un montant et un montant total par catégorie depuis le fichier 20190711.txt (par exemple)

je traite chaque ligne du fichier pour créer un 2e fichier "winfic_import_opera-"&@YEAR&@MON&@MDAY&".txt"
ce fichier contient les lignes pour importer en compta dans le logiciel compta winfic.
le fichier se créé correctement, de la façon dont j'ai besoin.

La bdd sqlite va chercher le code comptable correspondant au code opera.
je le met à la colonne du fichier CSV en fonction du montant s'il est négatif ou positif.

* Pour terminer mon programme, il me manque un montant total que je doit calculer à partir du fichier.

dans le fichier 20190711.txt, il y a 3 montants en fin de ligne à additionner.
pour bien montrer de quoi il s'agit, ce sont les montants 3572,71 468,27 et -9226,29
avec ça j'obtient -5185,31.
j'aurai une dernière ligne à créer avec ce montant dans le fichier, une fois toutes les lignes traitées.

J'ai ajouté MsgBox(0,"total general",$total_general) après le Next du For.

* problème :
rien n'apparaît.
si je met une commande pour créer une ligne dans mon fichier, je n'ai rien.
si je met avec le Next, ça fonctionne mais je n'en ai pas besoin là.

Je ne comprend pas pourquoi rien ne se passe après le Next.
merci

Code : Tout sélectionner

#include <File.au3>
#include <SQLite.au3>
#include <SQLite.dll.au3>

; ** Initialisation des variables
Local $compte_winfic ; compte winfic correspondant au code opera dans la bdd SQLite
Local $requete
dim $line[10]	; Variable tableau qui contient chaque élément de la ligne du fichier opera à traiter

local $ligne_total_general_ecrit 							  ; variable pour contrôler si la ligne avec le total général est écrite car je ne comprend pas pourquoi apres la boucle for / next rien ne se passe
Local $total_general,$compteur_total, $compteur_total_ligne	; Le total général est à calculer à partir des données du fichier

$total_general = 0
$compteur_total = 0	; utile pour comparer la valeur avec celle de la ligne précédente
$compteur_total_ligne = 0
$ligne_total_general_ecrit = 0

; nom du fichier créé par ce programme pour importer dans winfic
$file_prepa_import_winfic="winfic_import_opera-"&@MDAY&@MON&@YEAR&".txt"


; Chargement de la DLL sqlite
_SQLite_Startup(@ScriptDir & "\config\sqlite3.dll", False, 1)

If @error Then
    MsgBox($MB_SYSTEMMODAL, "SQLite Erreur", "Le fichier SQLite.dll ne peut pas être chargé.")
    Exit -1
 Else

 EndIf
ConsoleWrite("_SQLite_LibVersion=" & _SQLite_LibVersion() & @CRLF)	; si besoin de débugguer, affichage d'information dans la console.
ConsoleWrite("_SQLite_statup=" & _SQLite_Startup() & @CRLF)

$file = "20190711.txt" ; fichier exemple à traiter

; On récupère la partie date du nom du fichier sous la forme JJMMAAAA, car le fichier sera enregistré sous la formme JJMMAAAA.TXT
$winfic_date_piece=StringLeft($file,8)

; on contrôle qu'il n'y ai bien que des valeurs numériques.
if IsNumber(Number($winfic_date_piece))=0 Then
   MsgBox(0,"nom du fichier incorrect","Merci de mettre le nom du fichier sous la forme JJMMAAAA.txt"&@CRLF&@CRLF&"Exemple : "&@MDAY&@MON&@YEAR&".txt")
   Exit
EndIf


; on ouvre les fichiers à traiter et créer
FileOpen($file, 0)
FileOpen($file_prepa_import_winfic,2)


; // on démarre le traitement du fichier Opéra

; le traitement du fichier sera ainsi
; voir dans la colonne 5 si le montant est positif ou négatif
; positif : le montant sera en DEBIT
; négatif : le montant sera en CREDIT

; notes :
; les montants sont adaptés pour winfic : suppression de la virgule dans les séparateurs de miliers,
; remplacement . par , dans les décimaux au moment de crééer la ligne compta car sinon, avec les chiffres 0,91 par exemple aucun compte comptable dans l'écriture de la ligne du fichier import opera winfic


;~ On parcours chaque ligne
; $line prend la ligne en cours

For $i = 1 to _FileCountLines($file)-1

    $line = StringSplit (FileReadLine($file, $i),@TAB) ; on récupère la ligne en cours

   ; on ouvre la bdd sqlite3
   $handle_db=_SQLite_Open("code_opera_winfic.db") ; chargement de la base de donnée
   _SQLite_Query($handle_db, "SELECT compte_winfic FROM code WHERE code_opera = "& $line[3] & "",$requete)
   _SQLite_FetchData($requete,$compte_winfic)

   ; On vérifie que le compte comptable winfic n'est pas vide dans la base de données
   if $compte_winfic[0]="" Then
;~ 	  MsgBox(0,"Compte vide", "le code opera "&$line[3]&" n'a pas de compte comptable winfic dans la base de données.")
	  Exit
   EndIf

; On adapte la valeur du montant
   $montant=StringReplace(StringReplace($line[5],",","")," ","") ; on supprime les virgules et les espace, on remplace les . par ,

   ;~    vérification des montants pour calculer la ligne "total général"
   $compteur_total_ligne = StringReplace(StringReplace($line[6],",","")," ","")

   if $compteur_total_ligne <> $compteur_total Then
   $total_general=$total_general+$compteur_total_ligne
   $compteur_total=$compteur_total_ligne
   EndIf


; On vérifie la valeur du montant. Il faut démarrer en controlant que la valeur est bien positive ou négative pour le bon déroulement du programme

   if $montant<>0 Then

; si le montant est positif, on écrit une ligne avec le montant dans crédit
   if $montant>0 Then
;~ 	  MsgBox(0,"info","positif")
	  FileWriteLine($file_prepa_import_winfic,"VE;"&$winfic_date_piece&";"&$compte_winfic[0]&";"&$line[4]&";"&StringReplace($montant,".",",")&";")

   ElseIf $montant<0 Then
;~ 	  MsgBox(0,"info","négatif")
	  FileWriteLine($file_prepa_import_winfic,"VE;"&$winfic_date_piece&";"&$compte_winfic[0]&";"&$line[4]&";"&";"&StringReplace($montant,".",","))

   EndIf

;~  le montant est forcément égale à 0 car ni suppérieur, ni inférieur à 0
   Else
;~      FileWriteLine($file_prepa_import_winfic,"VEEEEEE;"&$winfic_date_piece&";"&$compte_winfic&";"&";"&$montant)
MsgBox(0,"montant", $total_general)

EndIf

; Il reste les montant = 0, alors on est sur la 2e partie du document. Inutile pour cette partie de traitement

 _SQLite_QueryFinalize($handle_db)

Next

MsgBox(0,"total general",$total_general)

; Fermeture des fichiers et de la bdd SQLite
FileClose($file_prepa_import_winfic)
FileClose($file)
_SQLite_Close($handle_db)
_SQLite_Shutdown()
Fichiers joints
20190711.txt
(2.64 Kio) Téléchargé 29 fois
20190711.txt
(2.64 Kio) Téléchargé 29 fois

jchd
AutoIt MVPs (MVP)
AutoIt MVPs (MVP)
Messages : 2099
Enregistré le : lun. 30 mars 2009 21:57
Localisation : Sud-Ouest de la France (43.622788,-1.260864)
Status : Hors ligne

Re: problème accès bdd sqlite  

#7

Message par jchd » jeu. 18 juil. 2019 20:01

Je ne comprend pas pourquoi rien ne se passe après le Next.
Parce que vous sortez du programme (Exit) à la rencontre de la première ligne qui n'a pas le format des écritures que vous voulez traiter.
Ce fichier a un format atroce !

Déjà utilisez uniquement le format AAAAMMJJ et pas un mélange avec JJMMAAAA. Le premier se trie naturellement et, depuis un temps certain, ne commence plus par un zéro (pas forcément présent) en tête.

Je reste étonné qu'un programme de compta demande des montants incluant une virgule et non un point.

Code : Tout sélectionner

#include <File.au3>
#include <SQLite.au3>

; Chargement de la DLL sqlite
_SQLite_Startup(@ScriptDir & "\config\sqlite3.dll", False, 1)

If @error Then
	MsgBox($MB_SYSTEMMODAL, "SQLite Erreur", "Le fichier SQLite.dll ne peut pas être chargé.")
	Exit -1
EndIf

; on ouvre la bdd sqlite3
Local $hDB = _SQLite_Open("code_opera_winfic.db") ; chargement de la base de donnée

; on ouvre les fichiers à traiter et créer
Local $sFile = "20190711.txt" ; fichier exemple à traiter

; On récupère la partie date du nom du fichier sous la forme AAAAMMJJ, car le fichier sera enregistré sous la formme AAAAMMJJ.TXT
Local $sDatePiece = StringLeft($sFile, 8)

; on contrôle qu'il n'y ait bien que des valeurs numériques.
If Not StringRegExp($sDatePiece, "(?i)^\d{8}$") Then
	MsgBox(0, "Nom du fichier incorrect", "Merci de mettre le nom du fichier sous la forme AAAAMMJJ.txt" & @CRLF & @CRLF & "Exemple : " & @YEAR & @MON & @MDAY & ".txt")
	Exit
EndIf
Local $hFile = FileOpen($sFile, 0)

; nom du fichier créé par ce programme pour importer dans winfic
Local $sFile_prepa_import_winfic = "winfic_import_opera-" & @YEAR & @MON & @MDAY & ".txt"
Local $hPrepa = FileOpen($sFile_prepa_import_winfic, 2)

; // on démarre le traitement du fichier Opéra

Local $sLine			; ligne lue
Local $aFields			; tableau qui contient chaque élément de la ligne du fichier opera à traiter
Local $sCompteOpera		; compte Opera
Local $sCompteWinfic    ; compte winfic correspondant au code opera dans la bdd SQLite
Local $sLibelle			; libellé de l'écriture
Local $iMontant			; montant de l'écriture
Local $iTotalGeneral    ; le total général est à calculer à partir des données du fichier

;~ Pour chaque ligne
While 1
	$sLine = FileReadLine($hFile)
	If @error Then ExitLoop
	$aFields = StringSplit($sLine, @TAB, $STR_NOCOUNT) ; on récupère la ligne en cours
	$sType = $aFields[1]
	If Not StringRegExp($sType, "(?i)^[\ha-z]{2,}") Then ExitLoop
	$sCompteOpera = $aFields[2]
	$sLibelle = $aFields[3]
	; les montants sont adaptés pour winfic : suppression de la virgule dans les séparateurs de miliers,
	$iMontant = StringRegExpReplace($aFields[4], "[,. ]", "")	; on supprime les espaces, les points et les virgules (montants en centimes)
	$iTotalType = StringRegExpReplace($aFields[5], "[,. ]", "")	; on supprime les espaces, les points et les virgules (montants en centimes)

	_SQLite_QuerySingleRow($hDB, "SELECT compte_winfic FROM code WHERE code_opera = " & $sCompteOpera, $sCompteWinfic)

	; On vérifie que le compte comptable winfic n'est pas vide dans la base de données
	$sCompteWinfic = $sCompteWinfic[0]
	If $sCompteWinfic = "" Then
		MsgBox(0, "Compte vide", "Le code opera " & $sCompteOpera & " n'a pas de compte comptable winfic dans la base de données.")
		ContinueLoop        ; on pourrait sortir de la boucle aussi
	EndIf

	; somme des montants
	$iTotalGeneral += $iMontant

	; Si le montant est positif, on écrit une ligne avec le montant dans crédit
	If $iMontant > 0 Then
		FileWriteLine($sFile_prepa_import_winfic, "VE;" & $sDatePiece & ";" & $sCompteWinfic & ";" & $sLibelle & ";" & StringReplace(StringFormat("%.2f", $iMontant / 100), ".", ","))
	; sinon dans débit
	ElseIf $iMontant < 0 Then
		FileWriteLine($sFile_prepa_import_winfic, "VE;" & $sDatePiece & ";" & $sCompteWinfic & ";" & $sLibelle & ";;" & StringReplace(StringFormat("%.2f", $iMontant / 100), ".", ","))
	Else
		MsgBox(0, "Montant à zéro", $iMontant)
	EndIf
WEnd

MsgBox(0, "Total général", $iTotalGeneral / 100)
FileWrite($sFile_prepa_import_winfic, "VE;" & $sDatePiece & ";" & "#### Compte comptable Winfic du total" & ";Total général;;" & StringReplace(StringFormat("%.2f", $iTotalGeneral / 100), ".", ","))

; Fermeture des fichiers et de la bdd SQLite
FileClose($hPrepa)
FileClose($hFile)
_SQLite_Close($hDB)
_SQLite_Shutdown()
La cryptographie d'aujourd'hui c'est le taquin plus l'électricité.

whitewater
Niveau 1
Niveau 1
Messages : 7
Enregistré le : sam. 27 avr. 2013 15:31
Status : Hors ligne

Re: problème accès bdd sqlite

#8

Message par whitewater » ven. 19 juil. 2019 09:24

Parce que vous sortez du programme (Exit) à la rencontre de la première ligne qui n'a pas le format des écritures que vous voulez traiter.
ça m'a traversé l'esprit de rechercher le mot "exit", je suis passé à autre chose et voila...
quelle "erreur" stupide... ça apprend. merci de l'avoir vu.
Ce fichier a un format atroce !
tant qu'il ne fait pas mal au crane à sa lecture, ça va ;)
il y a certainement des choses à améliorer.

je devrai arriver à terminer le code pour le besoin.
Merci en tout cas de toute tes réponses.

jchd
AutoIt MVPs (MVP)
AutoIt MVPs (MVP)
Messages : 2099
Enregistré le : lun. 30 mars 2009 21:57
Localisation : Sud-Ouest de la France (43.622788,-1.260864)
Status : Hors ligne

Re: [résolu] problème accès bdd sqlite

#9

Message par jchd » ven. 19 juil. 2019 16:27

je devrai arriver à terminer le code pour le besoin.
Vous avez regardé et testé le code que j'ai posté en dernier ?
La cryptographie d'aujourd'hui c'est le taquin plus l'électricité.

whitewater
Niveau 1
Niveau 1
Messages : 7
Enregistré le : sam. 27 avr. 2013 15:31
Status : Hors ligne

Re: [résolu] problème accès bdd sqlite

#10

Message par whitewater » lun. 29 juil. 2019 16:07

Bonjour jchd, j'ai dû passer à autre chose pour le travail.
j'ai regardé le code. C'est sûr, c'est autre chose ! merci !

Je ne l'ai pas encore testé. Je préfère m'y replonger quand j'aurai du temps à y consacrer.
J'espère cette semaine.
Super sympa d'avoir partagé le code. vraiment plus propre et clair.
Je vous tiens au courant.

whitewater
Niveau 1
Niveau 1
Messages : 7
Enregistré le : sam. 27 avr. 2013 15:31
Status : Hors ligne

Re: [résolu] problème accès bdd sqlite

#11

Message par whitewater » mar. 30 juil. 2019 15:22

J'ai regardé le code.

Je ne comprend pas la ligne 51 :

Code : Tout sélectionner

If Not StringRegExp($sType, "(?i)^[\ha-z]{2,}")
C'est pour vérifier qu'il n'y a pas de chiffre ?

Sinon,
j'ai compris que supprimer les caractères . , espace et diviser par 100 au moment de l'enregistrement était plus propre.

Variable $iTotalGeneral :
Je n'avais même pas testé la somme des montants. C'est sûr, plus facile et plus propre aussi.
J'avais pris les "sous-totaux" pour avoir le total général.
Avec ce montant, il y a une ligne à ajouter, selon positif ou négatif, comme pour $iMontant.

j'ai ajouté les lignes au code.

Sinon, dans les besoins du programme, je ne vois pas à quoi sert $sType car les lignes écrites sont fonction de $iMontant, négatif ou positif.

Par contre, je ne comprend pas, aucun fichier n'est créé. Pas de "winfic_import_opera-<date>.txt"
Avec mon code du début du sujet, le fichier est créé.

Le code avec les 2 lignes :

Code : Tout sélectionner

#include <File.au3>
#include <SQLite.au3>

; Chargement de la DLL sqlite
_SQLite_Startup(@ScriptDir & "\config\sqlite3.dll", False, 1)

If @error Then
	MsgBox($MB_SYSTEMMODAL, "SQLite Erreur", "Le fichier SQLite.dll ne peut pas être chargé.")
	Exit -1
EndIf

; on ouvre la bdd sqlite3
Local $hDB = _SQLite_Open("code_opera_winfic.db") ; chargement de la base de donnée

; on ouvre les fichiers à traiter et créer
Local $sFile = "20190711.txt" ; fichier exemple à traiter

; On récupère la partie date du nom du fichier sous la forme AAAAMMJJ, car le fichier sera enregistré sous la formme AAAAMMJJ.TXT
Local $sDatePiece = StringLeft($sFile, 8)

; on contrôle qu'il n'y ait bien que des valeurs numériques.
If Not StringRegExp($sDatePiece, "(?i)^\d{8}$") Then
	MsgBox(0, "Nom du fichier incorrect", "Merci de mettre le nom du fichier sous la forme AAAAMMJJ.txt" & @CRLF & @CRLF & "Exemple : " & @YEAR & @MON & @MDAY & ".txt")
	Exit
EndIf
Local $hFile = FileOpen($sFile, 0)

; nom du fichier créé par ce programme pour importer dans winfic
Local $sFile_prepa_import_winfic = "winfic_import_opera-" & @YEAR & @MON & @MDAY & ".txt"
Local $hPrepa = FileOpen($sFile_prepa_import_winfic, 2)


; // on démarre le traitement du fichier Opéra

Local $sLine			; ligne lue
Local $aFields			; tableau qui contient chaque élément de la ligne du fichier opera à traiter
Local $sCompteOpera		; compte Opera
Local $sCompteWinfic      ; compte winfic correspondant au code opera dans la bdd SQLite
Local $sLibelle			; libellé de l'écriture
Local $iMontant			; montant de l'écriture
Local $iTotalGeneral    ; le total général est à calculer à partir des données du fichier

;~ Pour chaque ligne
While 1
	$sLine = FileReadLine($hFile)
	If @error Then ExitLoop
	$aFields = StringSplit($sLine, @TAB, $STR_NOCOUNT) ; on récupère la ligne en cours
	$sType = $aFields[1]

;~ 	MsgBox(0,"info",$aFields[0])

	If Not StringRegExp($sType, "(?i)^[\ha-z]{2,}") Then ExitLoop
	$sCompteOpera = $aFields[2]
	$sLibelle = $aFields[3]

	; les montants sont adaptés pour winfic : suppression de la virgule dans les séparateurs de miliers,
	$iMontant = StringRegExpReplace($aFields[4], "[,. ]", "")	; on supprime les espaces, les points et les virgules (montants en centimes)
	$iTotalType = StringRegExpReplace($aFields[5], "[,. ]", "")	; on supprime les espaces, les points et les virgules (montants en centimes)

	_SQLite_QuerySingleRow($hDB, "SELECT compte_winfic FROM code WHERE code_opera = " & $sCompteOpera, $sCompteWinfic)

	; On vérifie que le compte comptable winfic n'est pas vide dans la base de données
	$sCompteWinfic = $sCompteWinfic[0]
	If $sCompteWinfic = "" Then
		MsgBox(0, "Compte vide", "Le code opera " & $sCompteOpera & " n'a pas de compte comptable winfic dans la base de données.")
		ContinueLoop        ; on pourrait sortir de la boucle aussi
	EndIf

	; somme des montants
	$iTotalGeneral += $iMontant

	; Si le montant est positif, on écrit une ligne avec le montant dans crédit
	If $iMontant > 0 Then
		FileWriteLine($sFile_prepa_import_winfic, "VE;" & $sDatePiece & ";" & $sCompteWinfic & ";" & $sLibelle & ";" & StringReplace(StringFormat("%.2f", $iMontant / 100), ".", ","))

	; sinon dans débit
	ElseIf $iMontant < 0 Then
		FileWriteLine($sFile_prepa_import_winfic, "VE;" & $sDatePiece & ";" & $sCompteWinfic & ";" & $sLibelle & ";;" & StringReplace(StringFormat("%.2f", $iMontant / 100), ".", ","))

Else
	EndIf
WEnd

   ; On écrit la dernière ligne dans le fichier avec le Total Général
	If $iTotalGeneral > 0 Then
		FileWriteLine($sFile_prepa_import_winfic, "VE;" & $sDatePiece & ";" & $sCompteWinfic & ";Total General;" & StringReplace(StringFormat("%.2f", $iTotalGeneral / 100), ".", ","))

	; sinon dans débit
	ElseIf $iTotalGeneral < 0 Then
		FileWriteLine($sFile_prepa_import_winfic, "VE;" & $sDatePiece & ";" & $sCompteWinfic & ";Total General;;" & StringReplace(StringFormat("%.2f", $iTotalGeneral / 100), ".", ","))

   EndIf

;~ MsgBox(0, "Total général", $iTotalGeneral / 100)
;~ FileWrite($sFile_prepa_import_winfic, "VE;" & $sDatePiece & ";" & "#### Compte comptable Winfic du total" & ";Total général;;" & StringReplace(StringFormat("%.2f", $iTotalGeneral / 100), ".", ","))

; Fermeture des fichiers et de la bdd SQLite
FileClose($hPrepa)
FileClose($hFile)
_SQLite_Close($hDB)
_SQLite_Shutdown()

Répondre