PC SOFT

FORUMS PROFESSIONNELS
WINDEVWEBDEV et WINDEV Mobile

Accueil → WINDEV (précédentes versions) → Import CSV séparateur virgule
Import CSV séparateur virgule
Débuté par Calimero, 15 jan. 2025 10:50 - 14 réponses
Membre enregistré
89 messages
Posté le 15 janvier 2025 - 10:50
Bonjour à tous,

Comme l'indique le titre, je voudrais importer importer des données de plusieurs fichiers csv avec séparateur virgule. Le problème est que certaines colonnes contiennent des chiffres séparés par des virgules. ( poids, dimensions ou prix ). Je suis sur windev25.

Je cherche depuis plusieurs jours comment y remédier. Pour l'instant, je dois charger sur Excel, transformer etc... mais ce n'est pas pratique et ça me prend du temps, sachant que je dois le faire plusieurs fois par jour.

Pour l'instant, mon code reste simple avec un fLitLigne mais bien sûr, ça ne fonctionne pas. J'ai trouvé peut être une solution avec CSVVersTableau mais j'avoue que je ne comprends pas bien le fonctionnement.

Voici le code que j'ai fait actuellement, j'ai simplifié parce qu'il y a beaucoup de colonnes.
C'est un fichier de colisage que j'importe vers mon fichier de données fournisseur. Les données principales existent déjà importées depuis un autre fichier, j'y ajoute juste les formats de colis, poids, prix etc...

Merci d'avance pour votre aide

sRefFournisseur est une chaîne
sLongueurProduit est une chaîne
sLargeurProduit est une chaîne
sHauteurProduit est une chaîne
sPoidsProduit est une chaîne

nMonfichierOuvert est une entier
sLigneLue est une chaîne

//Ouvrir le fichier
nMonfichierOuvert = fOuvre(ComplèteRep(fRepExe) + "IMPORTATION CATALOGUES FOURNISSEURS\Colisage.csv",foLecture)

//Tester l'ouverture
SI nMonfichierOuvert <> - 1 ALORS
//Positionner sur la 1ère ligne
sLigneLue = fLitLigne(nMonfichierOuvert, Caract(10))

//Boucle de lecture

TANTQUE sLigneLue<> EOT

//Lire les données, les extraire et les allouer


sRefFournisseur = ExtraitChaîne(sLigneLue,1,",")
sLongueurProduit = ExtraitChaîne(sLigneLue,11,",")
sLargeurProduit = ExtraitChaîne(sLigneLue,12,",")
sHauteurProduit = ExtraitChaîne(sLigneLue,13,",")
sPoidsProduit = ExtraitChaîne(sLigneLue,14,",")

HLitRecherchePremier(Fournisseur,REFFournisseur,sRefFournisseur)
SI HTrouve() ALORS

Fournisseur.LongueurProduit = sLongueurProduit
Fournisseur.LargeurProduit = sLargeurProduit
Fournisseur.HauteurProduit = sHauteurProduit
Fournisseur.PoidsProduit = sPoidsProduit

HModifie(Fournisseur)

FIN

SINON

FIN
FIN

sLigneLue = fLitLigne(nMonfichierOuvert,Caract(10))
FIN

SINON
Info("problème")
FIN



Trace("Importation des colisages terminée")
fFerme(nMonfichierOuvert)
Membre enregistré
175 messages
Posté le 15 janvier 2025 - 15:27
Bonjour

Je ne vois pas votre problème, vous avez déjà étudier le programme, essayez d'utiliser xlsOuvre("chemin", "xlsEcriture") dans le cas ou ce serait nécessaire

NB : je vois très bien votre programme, juste un conseil, essayez de ne pas sauter des lignes de code parce que cela pourrait fausser le statistique de nombre de ligne

Cordialement
Mr.RATSIMANDRESY
Niry Aina Eddy
Membre enregistré
89 messages
Posté le 15 janvier 2025 - 17:05
Bonjour,

Merci pour votre réponse.
J'ai une version Windev 25, je vois que XlsOuvre ne fonctionne sur des fichiers csv que depuis la dernière version 2025.
Donc je suis en train de suivre la piste Himportetexte ( pour l'instant, je fais des tests )

Je reformule donc mon problème, avec fLitligne, mes séparateurs sont des virgules mais j'ai également des chiffres avec décimales dans mes champs donc Windev ne fait pas la différence d'où mon intérêt pour Himportetexte où il semble qu'on puisse paramétrer les limiteurs de champs, décimales et lignes
Membre enregistré
7 messages
Posté le 15 janvier 2025 - 17:51
Bonjour,

Je pense que la fonction CSVVersTableau() est la solution.
Le 1er paramètre est le contenu du fichier csv disponible grâce à la fonction fChargeTexte()

Bon développement.
NN12
Membre enregistré
751 messages
Posté le 15 janvier 2025 - 21:02
Bonjour
une question avant de réfléchir à une solution : Avez-vous essayé d'éditer le fichier avec un éditeur de texte (Notepad ++ ou autre) sans l'ouvrir avec Excel.
Etes-vous certain que le fichier CSV originel contient des virgules en séparateur de colonnes et des virgules en séparateur décimal (et pas des points).
Si c'est le cas, c'est une erreur.
L'éditeur de texte vous permettra de vérifier ce point.
Cdlt
Membre enregistré
89 messages
Posté le 16 janvier 2025 - 00:18
Bonjour Cédric_34,

Je viens de le télécharger et de l'ouvrir directement dans notepad++.
Les séparateurs sont bien des virgules ainsi que les décimales. Je mets une copies d'écran en pièce jointe.


un retour ligne LF

Mais en regardant de plus près, quelques séparateurs décimal, rarement, sont avec un point
Message modifié, 16 janvier 2025 - 00:26
Membre enregistré
751 messages
Posté le 16 janvier 2025 - 00:33
Je me trompe ou les nombres décimaux sont indiqués comme des chaines ?
Dans ce cas, une virgule qui ne se trouve pas entre les double guillemets "" est une virgule séparatrice de colonnes.

effectivement, il semble que les dimensions ont pour séparateur décimal le point, mais elles sont indiquées dans l'indicateur de chaines "".
Si ceci se confirme, il y a de quoi traiter le fichier.
Cdlt
Message modifié, 16 janvier 2025 - 00:47
Membre enregistré
751 messages
Posté le 16 janvier 2025 - 00:55
Les lignes sont complètes car nous voyons les LF mais il nous faudrait la ligne complète des En-têtes pour confirmer les colonnes (pour faire des tests).
Je pense que la solution se trouve bien dans les identificateurs de chaines "", une virgule entre "" est un séparateur décimal, pareil pour le point.
Membre enregistré
89 messages
Posté le 16 janvier 2025 - 01:46
Il y a effectivement quelques points comme séparateurs décimal mais pas beaucoup. Ce sont en général des virgules.

Voici un exemple des premières lignes, ( il faudra mettre le LF à la fin de chaque ligne )on peut voir que la dernière ligne par exemple contient "73.5 cm","37,6", un point dans un et une virgule dans l'autre.

C'est un fichier qui contient 400 000 lignes de 47 Mo. J'ai passé ma journée à faire des tests avec Himportetexte, fchargetexte etc... ce ne sont pas des fonctions dont j'ai eu besoin par le passé et l'aide de Windev n'est pas très explicite. Je n'ai pas trouvé de tutos non plus et chatgpt ne m'a pas beaucoup aidé sur ce coup là ;-)

SKU,carton_1,carton_2,carton_3,carton_4,carton_5,carton_6,carton_7,carton_8,carton_9,product_length,product_width,product_height,product_weight/kg,packet_length_carton_1/CM,packet_length_carton_2/CM,packet_length_carton_3/CM,packet_length_carton_4/CM,packet_length_carton_5/CM,packet_length_carton_6/CM,packet_length_carton_7/CM,packet_length_carton_8/CM,packet_length_carton_9/CM,packet_width_carton_1/CM,packet_width_carton_2/CM,packet_width_carton_3/CM,packet_width_carton_4/CM,packet_width_carton_5/CM,packet_width_carton_6/CM,packet_width_carton_7/CM,packet_width_carton_8/CM,packet_width_carton_9/CM,packet_height_carton_1/CM,packet_height_carton_2/CM,packet_height_carton_3/CM,packet_height_carton_4/CM,packet_height_carton_5/CM,packet_height_carton_6/CM,packet_height_carton_7/CM,packet_height_carton_8/CM,packet_height_carton_9/CM,packet_weight_carton_1/KG,packet_weight_carton_2/KG,packet_weight_carton_3/KG,packet_weight_carton_4/KG,packet_weight_carton_5/KG,packet_weight_carton_6/KG,packet_weight_carton_7/KG,packet_weight_carton_8/KG,packet_weight_carton_9/KG,total_package_weight,overall_length,overall_height,overall_width,carton_quantity_1,carton_quantity_2,carton_quantity_3,carton_quantity_4,carton_quantity_5,carton_quantity_6,carton_quantity_7,carton_quantity_8,carton_quantity_9
44009,44009.A,,,,,,,,,,"60 cm","105 cm","8,5",99,,,,,,,,,64,,,,,,,,,6,,,,,,,,,"8,5",,,,,,,,,"8,5",,"105 cm",,1,,,,,,,,
801807,801807.A,,,,,,,,,,"40 cm","76 cm",19,89,,,,,,,,,"49,5",,,,,,,,,"10,5",,,,,,,,,"22,89",,,,,,,,,"22,89","40 cm","76 cm","50 cm",1,,,,,,,,
284687,284687.A,,,,,,,,,,,,"19,4","110,5",,,,,,,,,33,,,,,,,,,"15,5",,,,,,,,,21,,,,,,,,,21,"209 cm","84 cm","207 cm",1,,,,,,,,
3116173,345951.A,,,,,,,,,,,,9,"84,5",,,,,,,,,"43,5",,,,,,,,,11,,,,,,,,,"9,8",,,,,,,,,"9,8","80 cm","128 cm","5 cm",1,,,,,,,,
846097,846097.A,,,,,,,,,,"40 cm","40 cm","8,5","61,2",,,,,,,,,"43,2",,,,,,,,,"10,3",,,,,,,,,10,,,,,,,,,10,"40 cm","40 cm","42.5 cm",1,,,,,,,,
369089,369089.A,,,,,,,,,,,,"10,8","75,1",,,,,,,,,49,,,,,,,,,"29,7",,,,,,,,,"12,2",,,,,,,,,"12,2","138 cm","40 cm","74 cm",1,,,,,,,,
3142730,345797.A,347256.A,347807.A,347911.A,,,,,,,,,"57,59","76,5","104,2","80,2","57,7",,,,,,"42,7","40,9","46,1","29,2",,,,,,"11,4","19,3","44,6","28,3",,,,,,9,"24,15",25,"5,22",,,,,,"72,37","203 cm","128 cm","144 cm",2,1,1,1,,,,,
3334475,319279.A,369096.A,,,,,,,,,,,"32,8",88,63,,,,,,,,57,57,,,,,,,,12,25,,,,,,,,"22,9","13,6",,,,,,,,"63,7","160 cm","74 cm","80 cm",1,3,,,,,,,
3054263,248269.A,248309.A,248309.B,,,,,,,,"90 cm","73.5 cm","37,6","56,5",94,"81,5",,,,,,,51,94,20,,,,,,,46,5,17,,,,,,,"17,6","10,9","14,8",,,,,,,"43,3","90 cm","73.5 cm","90 cm",1,1,1,,,,,,
Membre enregistré
171 messages
Posté le 16 janvier 2025 - 09:51
Bonjour et bonne année,

Peut-être demander au fournisseur du fichier de modifier son exportation pour une tabulation en séparateur de champs ?
Membre enregistré
751 messages
Posté le 16 janvier 2025 - 21:05
Bonsoir Calimero,

BP n'a pas tort, si vous pouvez intervenir auprès du fournisseur de données, vous aurez la solution la plus fiable car un séparateur décimal et un séparateur de colonne avec le même caractère serait inexploitable sans les guillemets.

Vous pouvez essayer le code ci-dessous si les guillemets sont bien la solution au problème.
C'est votre code, j'ai ajouté du code qui nettoie la chaine sLigneLue avant son traitement.
J'ai ajouté des variables au début de votre code puis j'ai ajouté du code entre :

TANTQUE sLigneLue<> EOT
et
//Lire les données, les extraire et les allouer

sRefFournisseur est une chaîne
sLongueurProduit est une chaîne
sLargeurProduit est une chaîne
sHauteurProduit est une chaîne
sPoidsProduit est une chaîne

nNbOccurrence est un entier
x est un entier
nPosition1, nPosition2 sont des entiers
sMachaine est une chaîne

nMonfichierOuvert est une entier
sLigneLue est une chaîne

//Ouvrir le fichier
nMonfichierOuvert = fOuvre(ComplèteRep(fRepExe) + "IMPORTATION CATALOGUES FOURNISSEURS\Colisage.csv",foLecture)

//Tester l'ouverture
SI nMonfichierOuvert <> - 1 ALORS
//Positionner sur la 1ère ligne
sLigneLue = fLitLigne(nMonfichierOuvert, Caract(10))

//Boucle de lecture

TANTQUE sLigneLue<> EOT

POUR x = nNbOccurrence - 1 _À_ 1 PAS -2 // On décrémente x pour traiter sLigneLue de la fin de la chaine vers le début

nPosition1 = PositionOccurrence(sLigneLue, Caract(34), x, DepuisDébut) // récupération de la position des guillemets ouvrantes
nPosition2 = PositionOccurrence(sLigneLue, Caract(34), x + 1, DepuisDébut) // récupération de la position des guillemets fermantes
sMachaine = Milieu(sLigneLue, nPosition1, ((nPosition2 - nPosition1) + 1)) // récupération de la chaine entre les guillemets ouvrantes et fermantes
sMachaine = Remplace(sMachaine, Caract(34), "") // remplacement des guillemets par rien (suppression)
sMachaine = Remplace(sMachaine, ",", ".") // remplacement des virgules par un point
sLigneLue = Remplace(sLigneLue, nPosition1, ((nPosition2 - nPosition1) + 1), sMachaine) // remplacement de la chaine corrigée dans sLigneLue

FIN

//Lire les données, les extraire et les allouer


sRefFournisseur = ExtraitChaîne(sLigneLue,1,",")
sLongueurProduit = ExtraitChaîne(sLigneLue,11,",")
sLargeurProduit = ExtraitChaîne(sLigneLue,12,",")
sHauteurProduit = ExtraitChaîne(sLigneLue,13,",")
sPoidsProduit = ExtraitChaîne(sLigneLue,14,",")

HLitRecherchePremier(Fournisseur,REFFournisseur,sRefFournisseur)
SI HTrouve() ALORS

Fournisseur.LongueurProduit = sLongueurProduit
Fournisseur.LargeurProduit = sLargeurProduit
Fournisseur.HauteurProduit = sHauteurProduit
Fournisseur.PoidsProduit = sPoidsProduit

HModifie(Fournisseur)

FIN

SINON

FIN
FIN

sLigneLue = fLitLigne(nMonfichierOuvert,Caract(10))
FIN

SINON
Info("problème")
FIN



Trace("Importation des colisages terminée")
fFerme(nMonfichierOuvert)


Vérifiez bien le résultat avant d'utiliser ce code car je n'ai pas suffisamment de données pour garantir le bon fonctionnement.

Edit : Avez-vous essayé HImporteTexte (Fonction)
https://doc.pcsoft.fr/fr-FR/?3044011

Cdlt
Message modifié, 16 janvier 2025 - 21:26
Membre enregistré
89 messages
Posté le 17 janvier 2025 - 12:29
Bonjour Cédric et BP,

Je ne vais pas trop rentrer dans les détails, mais je suis gérant d'une société qui fait partie d'un groupe implanté dans le monde entier depuis près de 20 ans. Ce fichier est téléchargeable par les 2 ou 3000 sociétés qui sont comme la mienne donc demander un changement de fichier n'est pas possible.

En tout cas, merci pour votre aide. J'ai testé votre code mais ça ne fonctionne pas. ça met par exemple "10 au lieu de 10.2 dans le poids produit. Je vais quand même garder en mode test et peut être qu'en bidouillant un peu, j'arriverai à quelque chose. Pour l'instant, je manque de temps, je vais donc rester sur mon importation basique en transformant le fichier en xlsx, ça ne prend pas trop de temps mais ce n'est pas le but recherché. D'autant plus que j'ai d'autres fichiers comme celui-ci, bien plus gros qui eux prennent du temps, heureusement, utilisés seulement 1 ou 2 fois par semaine.

j'ai aussi fait des tests avec HimporteTexte. Je vais continuer mes investigations également là dessus. PCSoft ne sont pas très explicite sur le sujet et je ne trouve pas de tutos sur cette fonction. Dommage

Cordialement,
Posté le 17 janvier 2025 - 14:50
Bonjour,

Ce code te permettra de remplacer les virgules contenues dans les champs entre-guillemets par des points
Cela devrait résoudre ton problème

sRefFournisseur est une chaîne
sLongueurProduit est une chaîne
sLargeurProduit est une chaîne
sHauteurProduit est une chaîne
sPoidsProduit est une chaîne

i,j sont des entiers
bEntreGuillemets est un booléen=Faux

nMonfichierOuvert est une entier
sLigneLue est une chaîne
sLigneLueNew est une chaîne

//Ouvrir le fichier
nMonfichierOuvert = fOuvre(ComplèteRep(fRepExe) + "IMPORTATION CATALOGUES FOURNISSEURS\Colisage.csv",foLecture)

//Tester l'ouverture
SI nMonfichierOuvert <> - 1 ALORS
//Positionner sur la 1ère ligne
sLigneLue = fLitLigne(nMonfichierOuvert, Caract(10))

//Boucle de lecture
TANTQUE sLigneLue<> EOT

// On remplace les virgules par des points entre les guillemets
sLigneLueNew=""
POUR i=1 _À_ Taille(sLigneLue)
SELON sLigneLue[[i]]
CAS ","
SI bEntreGuillemets ALORS
sLigneLueNew+="."
SINON
sLigneLueNew+=","
FIN
CAS Caract(34)
bEntreGuillemets=(PAS bEntreGuillemets)
sLigneLueNew+=sLigneLue[[i]]

AUTRE CAS
sLigneLueNew+=sLigneLue[[i]]
FIN

FIN
sLigneLue=sLigneLueNew

//Lire les données, les extraire et les allouer
sRefFournisseur = ExtraitChaîne(sLigneLue,1,",")
sLongueurProduit = ExtraitChaîne(sLigneLue,11,",")
sLargeurProduit = ExtraitChaîne(sLigneLue,12,",")
sHauteurProduit = ExtraitChaîne(sLigneLue,13,",")
sPoidsProduit = ExtraitChaîne(sLigneLue,14,",")

HLitRecherchePremier(Fournisseur,REFFournisseur,sRefFournisseur)
SI HTrouve() ALORS

Fournisseur.LongueurProduit = sLongueurProduit
Fournisseur.LargeurProduit = sLargeurProduit
Fournisseur.HauteurProduit = sHauteurProduit
Fournisseur.PoidsProduit = sPoidsProduit

HModifie(Fournisseur)

SINON
FIN

sLigneLue = fLitLigne(nMonfichierOuvert,Caract(10))
FIN

SINON
Info("problème")
FIN



Trace("Importation des colisages terminée")
fFerme(nMonfichierOuvert)
Membre enregistré
751 messages
Posté le 17 janvier 2025 - 16:01
Bonjour Fabrice N,
j'avais bien pensé à traiter la ligne comme vous le proposez, mais j'ai finalement tenté avec les "Remplace" car je crains pour les temps de traitement : traiter chaque caractère par ligne multiplié par 400 000 lignes suivi du "HLitRecherchePremier" etc..., ça peut faire mal, non ?

Enfin, l'essai peut valoir le coup mais nous n'avons pas les données pour le test et je me pose une question : la disparition du point ne serait-elle pas due au format des données dans la rubrique HFSQL, et donc faut-il remplacer par un point.
La question est posée.

L'autre test à réaliser serait de remplacer toutes les virgules hors Guillemets (donc les virgules séparatrices de colonnes) en point-virgule ou en TAB.

Cdlt
Message modifié, 17 janvier 2025 - 16:05
Membre enregistré
201 messages
Posté le 17 janvier 2025 - 17:42
Bonjour Cédric,

Effectivement 400 000 lignes ça fait beaucoup ! j'avais pas vu :-)
Cela dit, à mon avis, le HlitRecherchePremier est plus chronophage que la boucle POUR
De plus si le processus s'exécute en tache de fond, ce n'est pas un problème.
Ce sera toujours plus efficace que de manipuler des fichiers Excel à la mano !

Ma partie de code peut aussi être aisément modifiée pour remplacer les virgules séparatrices de colonnes (hors guillemets) par des tabulations

// On remplace les séparateurs virgules "hors guillemets" par des tabulations
POUR i=1 _À_ Taille(sLigneLue)
SELON sLigneLue[[i]]
CAS ","
SI bEntreGuillemets ALORS
sLigneLueNew+=","
SINON
sLigneLueNew+=TAB
FIN

CAS Caract(34)
bEntreGuillemets=(PAS bEntreGuillemets)
sLigneLueNew+=sLigneLue[[i]]

AUTRE CAS
sLigneLueNew+=sLigneLue[[i]]
FIN
FIN
sLigneLue=sLigneLueNew


//Lire les données, les extraire et les allouer
sRefFournisseur = ExtraitChaîne(sLigneLue,1)
sLongueurProduit = ExtraitChaîne(sLigneLue,11)
sLargeurProduit = ExtraitChaîne(sLigneLue,12)
sHauteurProduit = ExtraitChaîne(sLigneLue,13)
sPoidsProduit = ExtraitChaîne(sLigneLue,14)


On peut utiliser la même logique pour remplacer les virgules séparatrices de colonnes (hors guillemets) par des points virgules

Cordialement
Message modifié, 17 janvier 2025 - 17:45