[Résolu][Base] Erreurs lors de l'importation d'un fichier CSV

Discussions et questions sur tout ce qui concerne la programmation tous langages et tous modules confondus.

Modérateur : Vilains modOOs

Règles du forum
:alerte: Balisage obligatoire dans cette section !
Aidez-nous à vous aider au mieux en balisant correctement votre question : reportez-vous sur les règles de cette section avant de poster !
Avatar de l’utilisateur
Rafbor
NOOuvel adepte
NOOuvel adepte
Messages : 13
Inscription : 24 déc. 2024 15:43

[Résolu][Base] Erreurs lors de l'importation d'un fichier CSV

Message par Rafbor »

Bonjour,
Je rencontre un problème lors de l'import d'un fichier CSV dans une table, le dernier champ n'a pas de partie décimale, il semble qu'il soit importé comme un entier.
J'utilise une macro issue de ce post et je l'ai adaptée. Cette macro a également une origine dans un sujet épinglé ici.

Extrait du fichier Albums2.csv, le dernier champ a une partie décimale
9782490591817;5;Apprends moi le dessin - BD humoristique 1;13,8;100;12;0;0;88;0;12;165,6
9782382110058;5;Apprends moi le dessin - BD humoristique 2;14,8;100;8;0;0;92;0;8;118,4
9782382110270;5;Apprends-moi le dessin - Manga;14,8;100;8;0;0;92;0;8;118,4
9782382111710;5;Apprends moi le dessin - Les toons;18,9;100;12;0;0;88;0;12;226,8
9782957706303;5;Une année pour mieux manger T1;15;100;8;0;0;92;0;8;120
Après import dans la table tblAlbums, la partie décimale est absente:
table_result.jpg
Je pense que cela vient du Select Case de la procédure CopierDonnees qui est censé fonctionner pour n'importe quel fichier importé, quel que soit le nombre de champs, mais qui ne reconnaît pas toujours bien le type de champ

Code : Tout sélectionner

Select Case .Columns.getByIndex(i -1).TypeName
	Case "SMALLINT"
		.Columns.getByIndex(i -1).updateInt(resuQuery.getInt(i))
	Case "VARCHAR"
		.Columns.getByIndex(i -1).updateString(resuQuery.getString(i))
	Case "NUMERIC"
		.Columns.getByIndex(i -1).updateInt(resuQuery.getInt(i))
	Case "DOUBLE"
		.Columns.getByIndex(i -1).updateDouble(resuQuery.getDouble(i))
	Case "FLOAT"
		.Columns.getByIndex(i -1).updateFloat(resuQuery.getFloat(i))
End Select
Je m'inquiète car cela fonctionne bien avec un fichier CSV différent, le fichier Albums1.csv, j'ai peur que le problème se reproduise sur d'autres champs.
Pour l'instant j'ai contourné le problème en lançant une requête update à la fin de la procédure OnBtnImporterClicked pour recalculer le PrixTotal

Code : Tout sélectionner

maRequete = maConnexion.createStatement()
instrSQL = "UPDATE ""tblAlbums"" SET ""PrixTotal"" = ""PrixVente""*""TotalVendu"""
maRequete.executeUpdate(instrSQL)
Une autre solution serait de calculer le PrixTotal dans le rapport, mais je n'ai réussi à en faire le total pour l'afficher en bas du tableau, dans une fonction Accumulation.

Je me demande si je ne devrais pas réécrire la macro pour qu'elle lise les champs dans l'ordre, avec le bon type, mais dans ce cas, elle ne serait plus auto-adaptative, et il faudrait une procédure spécifique pour chaque fichier.

Si vous voulez tester, dans la macro du fichier odb, il faut modifier dans la procédure OnBtnImporterClicked la variable chemin pour quelle corresponde à votre dossier de travail

Code : Tout sélectionner

chemin = Environ("HOME") & "/ForumOO/"
et changer le nom du fichier à importer dans sNomFichier

Code : Tout sélectionner

sNomFichier = "Albums1"
ou

Code : Tout sélectionner

sNomFichier = "Albums2"
Tous les fichiers sont dans le zip
BdArtLib.zip
Vous ne pouvez pas consulter les pièces jointes insérées à ce message.
Dernière modification par Rafbor le 28 déc. 2024 14:26, modifié 4 fois.
LibreOffice 24.2.7.2 sur Xubuntu 24.04.1
Avatar de l’utilisateur
Dude
IdOOle de la suite
IdOOle de la suite
Messages : 26205
Inscription : 03 mars 2006 07:45
Localisation : 127.0.0.1

Re: [Base] Erreurs lors de l'importation d'un fichier CSV

Message par Dude »

Salut,

La méthode getFloat ne fonctionne que si le nombre est au format US.
Si ton séparateur est une virgule, le plus simple est de le remplacer par un point.
Avatar de l’utilisateur
Rafbor
NOOuvel adepte
NOOuvel adepte
Messages : 13
Inscription : 24 déc. 2024 15:43

Re: [Base] Erreurs lors de l'importation d'un fichier CSV

Message par Rafbor »

@Dude: merci pour ta réponse, mais comme je l'ai dit, cela fonctionne bien avec le fichier Albums1.csv
9782490591817;5;Apprends moi le dessin - BD humoristique 1;13,8;12;3;0;0;9;0;3;41,4
9782382110058;5;Apprends moi le dessin - BD humoristique 2;14,8;8;2;0;0;6;0;2;29,6
9782382110270;5;Apprends-moi le dessin - Manga;14,8;12;2;0;0;10;0;2;29,6
9782382111710;5;Apprends moi le dessin - Les toons;18,9;5;3;0;0;2;0;3;56,7
9782957706303;5;Une année pour mieux manger T1;15;5;2;0;0;3;0;2;30
Résultat dans la table tblAlbums
table_result_1.jpg
Vous ne pouvez pas consulter les pièces jointes insérées à ce message.
LibreOffice 24.2.7.2 sur Xubuntu 24.04.1
Avatar de l’utilisateur
Dude
IdOOle de la suite
IdOOle de la suite
Messages : 26205
Inscription : 03 mars 2006 07:45
Localisation : 127.0.0.1

Re: [Base] Erreurs lors de l'importation d'un fichier CSV

Message par Dude »

Ce que tu donnes comme extrait ne contient pas de ligne d'entête.

Code : Tout sélectionner

isbn;id_auteur;titre;prix_vente;col1;col2;col3;col4;col5;col6;prix_total
9782490591817;5;Apprends moi le dessin - BD humoristique 1;13,8;100;12;0;0;88;0;12;165,6
9782382110058;5;Apprends moi le dessin - BD humoristique 2;14,8;100;8;0;0;92;0;8;118,4
9782382110270;5;Apprends-moi le dessin - Manga;14,8;100;8;0;0;92;0;8;118,4
9782382111710;5;Apprends moi le dessin - Les toons;18,9;100;12;0;0;88;0;12;226,8
9782957706303;5;Une année pour mieux manger T1;15;100;8;0;0;92;0;8;120
Si tu connais ta structure, il te suffit d'imposer le type comme avec ImportCSV.
En déclarant une clé primaire et les deux colonnes en 2 décimales, aucun problème :
Vous ne pouvez pas consulter les pièces jointes insérées à ce message.
Avatar de l’utilisateur
Rafbor
NOOuvel adepte
NOOuvel adepte
Messages : 13
Inscription : 24 déc. 2024 15:43

Re: [Base] Erreurs lors de l'importation d'un fichier CSV

Message par Rafbor »

Merci, mais ça ne répond à mon problème. J'ai écrit une application qui permet de gérer des ventes de livres puis qui génère les fichiers CSV et qui lance Base pour les importer d'un simple clic, pour imprimer les tableaux de ventes. C'est destiné à être utilisé par des utilisateurs non informaticiens, donc pas question de leur demander de choisir les types de données à importer.
PS: mes fichiers CSV comportent bien une ligne d'entête

Je vais faire les modifications que j'ai annoncé et je reviendrai donner le résultat.
LibreOffice 24.2.7.2 sur Xubuntu 24.04.1
Avatar de l’utilisateur
Dude
IdOOle de la suite
IdOOle de la suite
Messages : 26205
Inscription : 03 mars 2006 07:45
Localisation : 127.0.0.1

Re: [Base] Erreurs lors de l'importation d'un fichier CSV

Message par Dude »

L'usage d'ImportCSV est juste pour savoir si ton erreur de détection ne serait pas liée au pilote.

Car tu utilises le format Firebird qui est toujours déclaré comme expérimental.
Ici, on recommande l'usage du HSQLDB.
Tu devrais refaire ton ODB. Il y a de fortes chances que cela résolve ton problème.
Avatar de l’utilisateur
DLE
HédOOniste
HédOOniste
Messages : 1516
Inscription : 30 déc. 2007 18:56
Localisation : Lille

Re: [Base] Erreurs lors de l'importation d'un fichier CSV

Message par DLE »

Bonsoir,
Avec l'ajout de ces quelques lignes de code, on constate que les valeurs avec des décimales n'apparaissent que dans la variable "zz" pour le fichier "Albums2" alors qu'elles apparaissent dans la variable "xx" et "zz" pour le fichier "Albums1"!! Si on ouvre les deux fichiers directement avec Libo tout semble correct.
Revoir peut-être la création de "Albums2".
A+

Le code :

Code : Tout sélectionner

					Case "DOUBLE"
If i =12 Then
xx = resuQuery.getDouble(i)
yy = resuQuery.getint(i)
zz = resuQuery.getstring(i)

End if
'						.Columns.getByIndex(i -1).updateDouble(resuQuery.getstring(i))   
						.Columns.getByIndex(i -1).updateDouble(resuQuery.getDouble(i))
MacOS Tahoe 26.5 (iMac-M4) : AOO 4.1.16 , LibreOffice 25.8.7.3, Adoptium-temurinJDK 1.8.0_402, CCC, FireFox, Thunderbird, ORB 1.2.1
Parallels Desktop = Windows 11 & MacOS : AOO, Libre Office.
Avatar de l’utilisateur
Rafbor
NOOuvel adepte
NOOuvel adepte
Messages : 13
Inscription : 24 déc. 2024 15:43

Re: [Base] Erreurs lors de l'importation d'un fichier CSV

Message par Rafbor »

@Dude: j'ai fait l'essai de refaire mon odb avec le moteur HSQLDB, le résultat est identique.

@DLE: merci pour cette piste. Les fichiers CSV sont générés par du code C#, les données sont stockées en mémoire dans un DataTable, lors de l'export je construis chaque ligne en concaténant les champs des DataRow convertis en string avec la méthode ToString()
ex. pour les 2 derniers champs:

Code : Tout sélectionner

strLigne += row["nQteTotalVendu"].ToString() + ";";
strLigne += row["dblPrixTotal"].ToString();
En bidouillant le fichier je me suis rendu compte d'une chose incompréhensible, en supprimant la ligne 16 du fichier Albums2.csv

Code : Tout sélectionner

9780201379624;2;Chasse à l'homme;20;100;68;0;0;32;0;68;1360
les décimales sont conservées !
LibreOffice 24.2.7.2 sur Xubuntu 24.04.1
Avatar de l’utilisateur
Dude
IdOOle de la suite
IdOOle de la suite
Messages : 26205
Inscription : 03 mars 2006 07:45
Localisation : 127.0.0.1

Re: [Base] Erreurs lors de l'importation d'un fichier CSV

Message par Dude »

Rafbor a écrit : 26 déc. 2024 20:21 j'ai fait l'essai de refaire mon odb avec le moteur HSQLDB, le résultat est identique.
Il aurait été utile de fournir ce fichier tout comme publier la macro.

Dans ton code, tu supprimes les données des tables.
Je ne vois donc pas l'intérêt d'utiliser le service RowSet.
Pourquoi ne pas parcourir ton CSV ligne par ligne et lancer une requête INSERT ?

Code : Tout sélectionner

sub OnBtnImporterClicked
    Dim DrvMan As Object, maRequete as Object
    Dim chemin, cheminCSV As String, URLbdcsv As String, instrSQL as String
    Dim Infos(5) As New com.sun.star.beans.PropertyValue
    Dim x As Long
    Dim sNomFichier As String, sNomTable As String
    Dim nNbChamps As integer
    
    oFormAA = thisComponent
    ThisDatabaseDocument.CurrentController.connect("","")
    maConnexion = ThisDatabasedocument.CurrentController.ActiveConnection
    DrvMan = CreateUnoService("com.sun.star.sdbc.DriverManager")
    
	Infos(0).Name = "HeaderLine"
	Infos(0).Value = True
	Infos(1).Name = "FieldDelimiter"
	Infos(1).Value = chr(59)' ";"
	Infos(2).Name = "StringDelimiter"
	Infos(2).Value = ""
	Infos(3).Name = "DecimalDelimiter"
	Infos(3).Value = chr(44)' ","
	Infos(4).Name = "Extension"
	Infos(4).Value = "csv"
	Infos(5).Name = "CharSet"
	Infos(5).Value = "UTF-8"
	
	chemin = Environ("HOME") & "/ForumOO/"
    sNomFichier = "Auteurs"
    sNomTable = "tblAuteurs"
    nNbChamps = 4
    cheminCSV = chemin & sNomFichier & ".csv"
	URLbdcsv = "sdbc:flat:" & cheminCSV
	oConnexion = DrvMan.getConnectionWithInfo(URLbdcsv, Infos())
	
	' On efface la table Albums
	maRequete = maConnexion.createStatement()
	instrSQL = "DELETE FROM ""tblAlbums"""
	maRequete.executeUpdate(instrSQL)
	
	' On efface la table Auteurs
	maRequete = maConnexion.createStatement()
	instrSQL = "DELETE FROM ""tblAuteurs"""
	maRequete.executeUpdate(instrSQL)
	
	' On remplit la table Auteurs
	CopierDonnees(sNomFichier, sNomTable, nNbChamps)
	
	' On remplit la table Albums
    sNomFichier = "Albums2"
    sNomTable = "tblAlbums"
    nNbChamps = 12
    cheminCSV = chemin & sNomFichier & ".csv"
	URLbdcsv = "sdbc:flat:" & cheminCSV
	oConnexion = DrvMan.getConnectionWithInfo(URLbdcsv, Infos())
	CopierDonnees(sNomFichier, sNomTable, nNbChamps)
	
	' Update de la table auteur pour le champ 12
	' pour contourner un bug: dans certains cas, lors de l'import CSV,
	' le dernier champ a perdu sa partie décimale
'	maRequete = maConnexion.createStatement()
'	instrSQL = "UPDATE ""tblAlbums"" SET ""PrixTotal"" = ""PrixVente""*""TotalVendu"""
'	maRequete.executeUpdate(instrSQL)
end Sub

sub CopierDonnees(sNomFichier As string, sNomTable As string, nNbChamps As integer)
	On Error GoTo CopierDonnees_Err
	Dim unRowSet as Object, maRequete as Object, resuQuery as Object, maRequete2, Resultat as Object
	Dim Fenetre as Object, FenetreForm as Object, avance as Object
	Dim instrSQL as String, instrSQL2 as String, i as Integer, Compte as Integer, x as Integer
	Fenetre = ThisDatabaseDocument.CurrentController.Frame.ContainerWindow
	FenetreForm = oFormAA.currentcontroller.Frame.ContainerWindow
	Fenetre.Enable = False
	FenetreForm.Enable = False
	avance = oFormAA.CurrentController.StatusIndicator
	unRowSet = createUnoService("com.sun.star.sdb.RowSet")
	
	instrSQL = "SELECT * FROM " & sNomFichier
	instrSQL2 = "SELECT COUNT(*) as ""nb"" FROM " & sNomFichier
	
	maRequete = oConnexion.createStatement()
	maRequete2 = oConnexion.createStatement()
	Resultat = maRequete2.executeQuery(instrSQL2)
	Resultat.Next
	Compte = resultat.getInt(1)
	resuQuery = maRequete.executeQuery(instrSQL)
	With unRowSet
		.ActiveConnection = maConnexion
		.CommandType = com.sun.star.sdb.CommandType.TABLE
		.Command = sNomTable
		.Execute
		x = 1
		avance.start("Veuillez patienter ...", Compte)
		Do While resuQuery.Next
			.moveToInsertRow
			For i = 1 to nNbChamps
				Select Case .Columns.getByIndex(i -1).TypeName
					Case "SMALLINT"
						.Columns.getByIndex(i -1).updateInt(resuQuery.getInt(i))
					Case "VARCHAR"
						.Columns.getByIndex(i -1).updateString(resuQuery.getString(i))
					Case "NUMERIC"
						.Columns.getByIndex(i -1).updateInt(resuQuery.getInt(i))
					Case "DOUBLE"
						.Columns.getByIndex(i -1).updateDouble(resuQuery.getDouble(i))
					Case "FLOAT"
						.Columns.getByIndex(i -1).updateFloat(resuQuery.getFloat(i))
				End Select
				If i = 1 Then
					.insertRow
				Else
					.UpdateRow
				End If	
    		Next i
			avance.Value = x
			avance.Text = "Ligne " & x & " recopiée" 
			x = x + 1 		   		
  		Loop
  		avance.Text = "Terminé " & Compte & " lignes recopiées"
  	End With
	oConnexion.Dispose
	unRowSet.Dispose
	Wait 800
	avance.End
	FenetreForm.Enable = True
	Fenetre.Enable = True
	
CopierDonnees_Exit:	
	On Error GoTo 0
	Exit Sub
	
CopierDonnees_Err:
	MsgBox(Error, 16)
	FenetreForm.Enable = True
	Fenetre.Enable = True
	oConnexion.Dispose
	unRowSet.Dispose
	Resume CopierDonnees_Exit		
End Sub
Une choses encore... il aurait été sympathique de citer l'auteur de la macro originale dont tu t'es inspirée.
Avatar de l’utilisateur
Rafbor
NOOuvel adepte
NOOuvel adepte
Messages : 13
Inscription : 24 déc. 2024 15:43

Re: [Base] Erreurs lors de l'importation d'un fichier CSV

Message par Rafbor »

Dude a écrit : 26 déc. 2024 20:41 ..
Une choses encore... il aurait été sympathique de citer l'auteur de la macro originale dont tu t'es inspirée.
Je l'ai fait dans mon 1er post
Rafbor a écrit : 26 déc. 2024 07:38 Bonjour,
...
J'utilise une macro issue de ce post et je l'ai adaptée. Cette macro a également une origine dans un sujet épinglé ici.
LibreOffice 24.2.7.2 sur Xubuntu 24.04.1
Avatar de l’utilisateur
Dude
IdOOle de la suite
IdOOle de la suite
Messages : 26205
Inscription : 03 mars 2006 07:45
Localisation : 127.0.0.1

Re: [Base] Erreurs lors de l'importation d'un fichier CSV

Message par Dude »

Cela doit figurer aussi dans le document. Sinon, c'est un peu trop facile.
Poser une question, c'est bien. Répondre aux autres, c'est encore mieux.
Améliorez AOO et votez pour les issues
Avatar de l’utilisateur
Rafbor
NOOuvel adepte
NOOuvel adepte
Messages : 13
Inscription : 24 déc. 2024 15:43

Re: [Base] Erreurs lors de l'importation d'un fichier CSV

Message par Rafbor »

Dude a écrit : 26 déc. 2024 21:01 Cela doit figurer aussi dans le document. Sinon, c'est un peu trop facile.
Ok je ferai ça quand je publierai mes modifications sur ma page Github, j'y pense pas toujours.
Mais seulement si la solution à mon problème est trouvée, car en l'état, cette macro n'est pas fiable, le driver qui extrait les données du fichier CSV oublie les parties décimales dans certains cas.
Je vais la réécrire comme tu l'as suggéré, je sais le faire les yeux fermés en C# .Net, mais en Basic OO il va me falloir un peu de temps...
LibreOffice 24.2.7.2 sur Xubuntu 24.04.1
Avatar de l’utilisateur
Dude
IdOOle de la suite
IdOOle de la suite
Messages : 26205
Inscription : 03 mars 2006 07:45
Localisation : 127.0.0.1

Re: [Base] Erreurs lors de l'importation d'un fichier CSV

Message par Dude »

Rafbor a écrit : 27 déc. 2024 07:26 cette macro n'est pas fiable, le driver qui extrait les données du fichier CSV oublie les parties décimales dans certains cas
C'est fiable mais je me répète : ton CSV ne contient pas de partie décimale puisque le séparateur n'est pas un point.
Et donc, pourquoi ne pas faire ce que je te suggère ?
Dude a écrit : 26 déc. 2024 20:41 parcourir ton CSV ligne par ligne et lancer une requête INSERT

Code : Tout sélectionner

Sub Main
	Dim nId as long, nPourcent as currency
	'Origine https://beaussier.com/sections/viewtopic.php?f=8&t=1577
	sUrl = ThisDatabaseDocument.URL
	oDC = CreateUnoService("com.sun.star.sdb.DatabaseContext")
	oSrc = oDC.getByName(sUrl)
	oDB = oSrc.getConnection("","")
	oCnx = oDB.createStatement()
	
	sFic = "c:\temp\BdArtLib\Auteurs.csv"
	nFic = Freefile
	Open sFic For Input As nFic
	While not eof(nFic)
		Line Input #nFic, sLigne
		aItems = Split(sLigne, ";")
		nId = aItems(0) 
		nPourcent = aItems(3)
		sReq = "INSERT INTO ""tblAuteurs"" (" & _
				" ""IdAuteur"", " & _
				" ""PrenomAuteur"", " &_
				" ""NomAuteur"", " & _
				" ""Pourcentage"" ) VALUES (" & _
				nId & ", " & _
				"'" & aItems(1) & "', " & _
				"'" & aItems(2) & "', " & _
				nPourcent & ")"
		oCnx.executeUpdate(sReq)	
	Wend	
	Close #nFic	
	oCnx.dispose
End Sub
Avatar de l’utilisateur
Rafbor
NOOuvel adepte
NOOuvel adepte
Messages : 13
Inscription : 24 déc. 2024 15:43

Re: [Base] Erreurs lors de l'importation d'un fichier CSV

Message par Rafbor »

Dude a écrit : 27 déc. 2024 08:32 C'est fiable mais je me répète : ton CSV ne contient pas de partie décimale puisque le séparateur n'est pas un point.
J'avais un gros doute là-dessus car pourquoi cela fonctionne bien avec le fichier Albums1 ? Et pourquoi si je retire quelques lignes du fichier Albums2 cela fonctionne ?
Bref, j'ai généré un fichier avec des points au lieu de la virgule pour les nombres décimaux, fichier Albums3.csv joint, et en effet, cela fonctionne.
Par contre, si je l'ouvre dans Calc, les points posent un problème, les nombres décimaux ne sont plus reconnus.. Et c'est embêtant car le fichier qui sort de mon appli est en réalité plus complet, il y a des champs supplémentaires (que j'ai supprimé ici pour les tests) qui me permettent d'exploiter les données dans des tableaux croisés dynamique.
Albums3.csv.zip
Dude a écrit : 27 déc. 2024 08:32 Et donc, pourquoi ne pas faire ce que je te suggère ?
Ben si, j'ai dit que j'allais le faire mais que ça allait me prendre du temps, il faut que je me documente.

Tu as été plus rapide que moi :D
Je te remercie, je regarderai ce soir pour adapter ton code :super:
Vous ne pouvez pas consulter les pièces jointes insérées à ce message.
LibreOffice 24.2.7.2 sur Xubuntu 24.04.1
Jeff
Grand Maître de l'OOffice
Grand Maître de l'OOffice
Messages : 10015
Inscription : 18 sept. 2006 09:40
Localisation : France

Re: [Base] Erreurs lors de l'importation d'un fichier CSV

Message par Jeff »

Bonjour à tous,
Rafbor a écrit : 27 déc. 2024 10:44 si je l'ouvre dans Calc, les points posent un problème, les nombres décimaux ne sont plus reconnus.
Ça pourrait faire l'objet d'un autre fil de discussion sur l'import d'un csv (sinon, la réponse est peut-être déjà en section Macros), pour importer un csv sous Calc avec un séparateur décimal comme le point, il faut le définir comme dans ce sujet : viewtopic.php?p=278005#p278005

A +
À lire avant tout !

Pour télécharger Apache OpenOffice

AOO 4.1.16 / Debian 13 "Trixie" / Xfce
AOO 4.1.15 / Debian 11 "Bullseye" / Cinnamon
Avatar de l’utilisateur
Rafbor
NOOuvel adepte
NOOuvel adepte
Messages : 13
Inscription : 24 déc. 2024 15:43

Re: [Base] Erreurs lors de l'importation d'un fichier CSV

Message par Rafbor »

@Jeff: merci

Je vais faire des tests et voir quelle solution je retiens, mon but étant de réaliser tous ces exports-imports de manière automatisée, je peux toujours adapter mon appli pour quelle génère les fichiers attendus par chaque module LO.
LibreOffice 24.2.7.2 sur Xubuntu 24.04.1
Avatar de l’utilisateur
Rafbor
NOOuvel adepte
NOOuvel adepte
Messages : 13
Inscription : 24 déc. 2024 15:43

Re: [Base] Erreurs lors de l'importation d'un fichier CSV

Message par Rafbor »

J'ai réécrit la macro en partant de l'exemple fourni par @Dude.
Pour les nombres décimaux, j'ai préféré conserver la virgule comme séparateur décimal dans mon fichier CSV, car je peux l'exploiter dans Calc sans avoir besoin de choisir le mode US pour les colonnes concernées, je procède donc au remplacement de la virgule par le point avec la fonction Replace, lors de l'importation du fichier

Code : Tout sélectionner

sPrixTotal = Replace(aItems(11), ",", ".") ' on remplace la virgule par le point
J'ai également refait mon odb avec le moteur HSQLDB, je vais publier cette version, même si la version avec Firebird fonctionne aussi avec la même macro.
Je vous mets tous les fichiers dans le zip.
Fichiers.zip
Et voici la macro complète

Code : Tout sélectionner

REM  *****  BASIC  *****
option Explicit

' ouverture du formulaire au lancement
sub FormOpen
	ThisDatabaseDocument.CurrentController.connect("","") 
	ThisDatabaseDocument.FormDocuments.getByName("frmAuteursAlbums").open
end sub

sub OnBtnImporterClicked
' Macro inspirée de https://forum.openoffice.org/fr/forum/viewtopic.php?p=217819#p217819 de @Piaf
' et de https://forum.openoffice.org/fr/forum/viewtopic.php?p=388317#p388317 de @Dude

	On Error GoTo Import_Err
	
	Dim oDC, oSrc, oDB, oCnx As Object
	Dim sChemin, sFichierCSV, sNomFichier, sUrl, sReqSQL As String
	Dim sLigne, sNom, sPrenom, sTitre As String
	Dim nFic, nCount As Integer
	Dim aItems As Variant
	Dim sPourcent, sPrixVente, sPrixTotal As String
	dim oFormAA, oFenetre, oFenetreForm, oAvance as Object
	
	sUrl = ThisDatabaseDocument.URL
	oDC = CreateUnoService("com.sun.star.sdb.DatabaseContext")
	oSrc = oDC.getByName(sUrl)
	oDB = oSrc.getConnection("","")
	
	sChemin = Environ("HOME") & "/ForumOO/"
	
	' On efface la table Albums
	oCnx = oDB.createStatement()
	sReqSQL = "DELETE FROM ""tblAlbums"""
	oCnx.executeUpdate(sReqSQL)
	
	' On efface la table Auteurs
	oCnx = oDB.createStatement()
	sReqSQL = "DELETE FROM ""tblAuteurs"""
	oCnx.executeUpdate(sReqSQL)

	oFormAA = thisComponent
	oFenetre = ThisDatabaseDocument.CurrentController.Frame.ContainerWindow
	oFenetreForm = oFormAA.currentcontroller.Frame.ContainerWindow
	oFenetre.Enable = False
	oFenetreForm.Enable = False
	oAvance = oFormAA.CurrentController.StatusIndicator

	' Importation du fichier Auteurs
	nCount = 0
	oCnx = oDB.createStatement()
    	sNomFichier = "Auteurs.csv"
    	sFichierCSV = sChemin & sNomFichier
    	nFic = Freefile
	Open sFichierCSV For Input As nFic
	' 1ère ligne
	Line Input #nFic, sLigne
	' lignes suivantes
	oAvance.start("Veuillez patienter ...", nCount)
	While not eof(nFic)
		Line Input #nFic, sLigne
		nCount = nCount + 1
		aItems = Split(sLigne, ";")
		sPrenom = Replace(aItems(1), "'", "''") ' on double les apostrophes
		sNom = Replace(aItems(2), "'", "''") ' on double les apostrophes
		sPourcent = Replace(aItems(3), ",", ".") ' on remplace la virgule par le point
		sReqSQL = "INSERT INTO ""tblAuteurs"" (" & _
				" ""IdAuteur"", " & _
				" ""Prénom"", " &_
				" ""Nom"", " & _
				" ""Pourcentage"" ) VALUES (" & _
				"'" & aItems(0) & "', " & _
				"'" & sPrenom & "', " & _
				"'" & sNom & "', " & _
				"'" & sPourcent & "')"
		oCnx.executeUpdate(sReqSQL)
		oAvance.Value = nCount
		oAvance.Text = "Ligne " & nCount & " recopiée"
		Wait 20
	Wend
	Close #nFic
	oAvance.Text = "Terminé " & nCount & " lignes recopiées"
	Wait 800
	oAvance.End
	
	' Importation du fichier Albums
	nCount = 0
	oCnx = oDB.createStatement()
    	sNomFichier = "Albums1.csv"
    	sFichierCSV = sChemin & sNomFichier
    	nFic = Freefile
	Open sFichierCSV For Input As nFic
	' 1ère ligne
	Line Input #nFic, sLigne
	' lignes suivantes
	oAvance.start("Veuillez patienter ...", nCount)
	While not eof(nFic)
		Line Input #nFic, sLigne
		nCount = nCount + 1
		aItems = Split(sLigne, ";")
		sTitre = Replace(aItems(2), "'", "''") ' on double les apostrophes
		sPrixVente = Replace(aItems(3), ",", ".") ' on remplace la virgule par le point		
		sPrixTotal = Replace(aItems(11), ",", ".") ' on remplace la virgule par le point
		sReqSQL = "INSERT INTO ""tblAlbums"" (" & _
				" ""CodeIsbnEan"", " & _
				" ""IdAuteur"", " & _
				" ""Titre"", " &_
				" ""PrixVente"", " & _
				" ""StockInitial"", " & _
				" ""VenduLibrairie"", " &_
				" ""VenduMediat"", " & _
				" ""Offert"", " & _
				" ""StockFinal"", " &_
				" ""Afacturer"", " & _
				" ""TotalVendu"", " &_
				" ""PrixTotal"" ) VALUES (" & _
				"'" & aItems(0) & "', " & _
				"'" & aItems(1) & "', " & _
				"'" & sTitre & "', " & _
				"'" & sPrixVente & "', " & _
				"'" & aItems(4) & "', " & _
				"'" & aItems(5) & "', " & _
				"'" & aItems(6) & "', " & _
				"'" & aItems(7) & "', " & _
				"'" & aItems(8) & "', " & _
				"'" & aItems(9) & "', " & _
				"'" & aItems(10) & "', " & _
				"'" & sPrixTotal & "')"
		oCnx.executeUpdate(sReqSQL)
		oAvance.Value = nCount
		oAvance.Text = "Ligne " & nCount & " recopiée"
		Wait 10
	Wend
	Close #nFic
	oAvance.Text = "Terminé " & nCount & " lignes recopiées"
	Wait 1000
	oAvance.End
	oFenetreForm.Enable = True
	oFenetre.Enable = True
	
Import_Exit:	
	On Error GoTo 0
	Exit Sub
	
Import_Err:
	MsgBox(Error, 16)
	oFenetreForm.Enable = True
	oFenetre.Enable = True
	oCnx.Dispose
	Resume Import_Exit
End Sub

sub OnBtnImprimerClicked
	' ouvre le rapport
	ThisDatabaseDocument.ReportDocuments.getByName("rptVentesAuteur").open 
end Sub
Merci à vous pour votre aide, vous faites du bon boulot sur ce forum :super: . Je passe en résolu.
Vous ne pouvez pas consulter les pièces jointes insérées à ce message.
LibreOffice 24.2.7.2 sur Xubuntu 24.04.1