|
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
nMonfichierOuvert = fOuvre(ComplèteRep(fRepExe) + "IMPORTATION CATALOGUES FOURNISSEURS\Colisage.csv",foLecture)
SI nMonfichierOuvert <> - 1 ALORS sLigneLue = fLitLigne(nMonfichierOuvert, Caract(10)) TANTQUE sLigneLue<> EOT 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 pointMessage 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. CdltMessage 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
nMonfichierOuvert = fOuvre(ComplèteRep(fRepExe) + "IMPORTATION CATALOGUES FOURNISSEURS\Colisage.csv",foLecture)
SI nMonfichierOuvert <> - 1 ALORS sLigneLue = fLitLigne(nMonfichierOuvert, Caract(10))
TANTQUE sLigneLue<> EOT
POUR x = nNbOccurrence - 1 _À_ 1 PAS -2 nPosition1 = PositionOccurrence(sLigneLue, Caract(34), x, DepuisDébut) nPosition2 = PositionOccurrence(sLigneLue, Caract(34), x + 1, DepuisDébut) sMachaine = Milieu(sLigneLue, nPosition1, ((nPosition2 - nPosition1) + 1)) sMachaine = Remplace(sMachaine, Caract(34), "") sMachaine = Remplace(sMachaine, ",", ".") sLigneLue = Remplace(sLigneLue, nPosition1, ((nPosition2 - nPosition1) + 1), sMachaine) FIN
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
CdltMessage 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
nMonfichierOuvert = fOuvre(ComplèteRep(fRepExe) + "IMPORTATION CATALOGUES FOURNISSEURS\Colisage.csv",foLecture)
SI nMonfichierOuvert <> - 1 ALORS sLigneLue = fLitLigne(nMonfichierOuvert, Caract(10))
TANTQUE sLigneLue<> EOT 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 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.
CdltMessage 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
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
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
CordialementMessage modifié, 17 janvier 2025 - 17:45 |
| |
| |
| | | |
|
| | | | |
| | |
|