XL 2019 Fichier ".txt" de plus de 2.000.000 de lignes !

Titof06

XLDnaute Junior
Bonjour,

J'ai à traiter un fichier texte de plus de 2.000.000 de lignes.

Excel n'accepte qu'environ 1.500.000 lignes.

Je dois extraire des informations relatives à des mises à jour de fournisseurs et par rapport à une date précise.

Est-ce que quelqu'un pourrait me conseiller un logiciel ou une façon de sortir des informations de ce méga fichier texte, svp ?

Par avance, Merci 👍

Bonne Journée, Titof06 :)
 

oguruma

XLDnaute Occasionnel
Bonjour oguruma,

Un grand merci pour ces aides 👍

Il n'y a pas d'urgence, MERCI ENCORE !

Titof06
Hi, voici c'est dans le forum des trucs & astuces ainsi ça sera plus facilement accessible pour tous

voici les liens où télécharger les fichiers de données et Excel

Attention rétention à 21 jours !
 
Dernière édition:

oguruma

XLDnaute Occasionnel
Bonjour,

J'ai à traiter un fichier texte de plus de 2.000.000 de lignes.

Excel n'accepte qu'environ 1.500.000 lignes.

Je dois extraire des informations relatives à des mises à jour de fournisseurs et par rapport à une date précise.

Est-ce que quelqu'un pourrait me conseiller un logiciel ou une façon de sortir des informations de ce méga fichier texte, svp ?

Par avance, Merci 👍

Bonne Journée, Titof06 :)
Bonjour suite à ma hier réponse hier soir tu as une nouvelle version dans la réponse à ce post avec en plus un fichier Excel et son fichier Exemple light qui fonctionnera aussi avec un de tes gros fichiers si tu veux le mettre en pratique

 

job75

XLDnaute Barbatruc
Bonjour Titof06, oguruma, le forum,

Je reviens sur ce fil avec une autre solution.

Au lieu de créer des fichiers textes on crée des fichiers CSV.

Ces fichiers sont ensuite ouverts et copiés pour créer les feuilles :
VB:
Sub Creer_feuilles_fournisseurs()
Dim datedeb As Date, datefin As Date, coldate%, chemin$, fournisseurs$, fichier$, w As Worksheet
Dim Source, n%, d As Object, x%, tablo, ub&, i&, s, dat$, code$, j&, nomfeuille$, wb As Workbook
datedeb = DateValue("01/03/2024") 'à adapter
datefin = Date 'date du jour
coldate = 8 'numéro de colonne à adapter
chemin = ThisWorkbook.Path & "\"
fournisseurs = chemin & "Fournisseurs\"
If Dir(fournisseurs, vbDirectory) = "" Then MkDir fournisseurs 'crée le sous-dossier
fichier = Dir(fournisseurs & "*.csv")
'---vide le sous-dossier---
While fichier <> ""
    Kill fournisseurs & fichier
    fichier = Dir
Wend
'---supprime les feuillea---
Application.ScreenUpdating = False
Application.DisplayAlerts = False
For Each w In Worksheets
    If UCase(w.Name) <> "ACCUEIL" Then w.Delete
Next w
'---création des fichiers et feuilles fournisseurs---
Source = Array("famrem_sacha_Pour Test.txt", "hzn_sacha_Pour Test.txt") 'à adapter
For n = 0 To UBound(Source)
    Set d = CreateObject("Scripting.Dictionary")
    x = FreeFile
    Open chemin & Source(n) For Input As #x 'ouverture en lecture séquentielle
    tablo = Split(Input(LOF(x), #x), vbCrLf)
    ub = UBound(tablo)
    Close #x
    '---création des fichiers---
    For i = 1 To ub
        s = Split(tablo(i), ";", coldate + 1)
        If UBound(s) + 2 > coldate Then
            dat = s(coldate - 1)
            If IsDate(dat) Then
                If CDate(dat) >= datedeb And CDate(dat) <= datefin Then
                    code = s(0) 'code fournisseur
                    If Not d.exists(code) Then
                        d(code) = ""
                        fichier = fournisseurs & "F" & Format(n + 1, "00") & code & ".csv"
                        x = FreeFile
                        Open fichier For Output As #x 'ouverture en écriture séquentielle
                        Print #x, tablo(0)
                        For j = i To ub
                            s = Split(tablo(j), ";", coldate + 1)
                            If UBound(s) + 2 > coldate Then
                                If s(0) = code Then
                                    dat = s(coldate - 1)
                                    If IsDate(dat) Then If CDate(dat) >= datedeb And CDate(dat) <= datefin Then Print #x, tablo(j)
                                End If
                            End If
                        Next j
                        Close #x
                    End If
                End If
            End If
        End If
    Next i
    '---création des feuilles---
    If d.Count Then
        tablo = d.keys
        For i = 0 To UBound(tablo)
            nomfeuille = "F" & Format(n + 1, "00") & tablo(i)
            fichier = fournisseurs & nomfeuille & ".csv"
            Set wb = Workbooks.Open(fichier, Local:=True) 'ouverture du fichier
            ActiveSheet.Copy After:=ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count)
            ActiveSheet.Columns.AutoFit 'ajustement largeurs
            wb.Close
        Next i
    End If
Next n
Sheets(1).Activate
End Sub
Avec le fichier de 2 000 000 de lignes la création de la feuille se fait chez moi en 32 secondes au lieu de 48 secondes :


A+
 

Pièces jointes

  • Créer feuilles fournisseurs.xlsm
    26.9 KB · Affichages: 5
  • famrem_sacha_Pour Test.txt
    586 bytes · Affichages: 5
  • hzn_sacha_Pour Test.txt
    1.4 KB · Affichages: 5

oguruma

XLDnaute Occasionnel
Bonjour Titof06, oguruma, le forum,

Je reviens sur ce fil avec une autre solution.

Au lieu de créer des fichiers textes on crée des fichiers CSV.

Ces fichiers sont ensuite ouverts et copiés pour créer les feuilles :
VB:
Sub Creer_feuilles_fournisseurs()
Dim datedeb As Date, datefin As Date, coldate%, chemin$, fournisseurs$, fichier$, w As Worksheet
Dim Source, n%, d As Object, x%, tablo, ub&, i&, s, dat$, code$, j&, nomfeuille$, wb As Workbook
datedeb = DateValue("01/03/2024") 'à adapter
datefin = Date 'date du jour
coldate = 8 'numéro de colonne à adapter
chemin = ThisWorkbook.Path & "\"
fournisseurs = chemin & "Fournisseurs\"
If Dir(fournisseurs, vbDirectory) = "" Then MkDir fournisseurs 'crée le sous-dossier
fichier = Dir(fournisseurs & "*.csv")
'---vide le sous-dossier---
While fichier <> ""
    Kill fournisseurs & fichier
    fichier = Dir
Wend
'---supprime les feuillea---
Application.ScreenUpdating = False
Application.DisplayAlerts = False
For Each w In Worksheets
    If UCase(w.Name) <> "ACCUEIL" Then w.Delete
Next w
'---création des fichiers et feuilles fournisseurs---
Source = Array("famrem_sacha_Pour Test.txt", "hzn_sacha_Pour Test.txt") 'à adapter
For n = 0 To UBound(Source)
    Set d = CreateObject("Scripting.Dictionary")
    x = FreeFile
    Open chemin & Source(n) For Input As #x 'ouverture en lecture séquentielle
    tablo = Split(Input(LOF(x), #x), vbCrLf)
    ub = UBound(tablo)
    Close #x
    '---création des fichiers---
    For i = 1 To ub
        s = Split(tablo(i), ";", coldate + 1)
        If UBound(s) + 2 > coldate Then
            dat = s(coldate - 1)
            If IsDate(dat) Then
                If CDate(dat) >= datedeb And CDate(dat) <= datefin Then
                    code = s(0) 'code fournisseur
                    If Not d.exists(code) Then
                        d(code) = ""
                        fichier = fournisseurs & "F" & Format(n + 1, "00") & code & ".csv"
                        x = FreeFile
                        Open fichier For Output As #x 'ouverture en écriture séquentielle
                        Print #x, tablo(0)
                        For j = i To ub
                            s = Split(tablo(j), ";", coldate + 1)
                            If UBound(s) + 2 > coldate Then
                                If s(0) = code Then
                                    dat = s(coldate - 1)
                                    If IsDate(dat) Then If CDate(dat) >= datedeb And CDate(dat) <= datefin Then Print #x, tablo(j)
                                End If
                            End If
                        Next j
                        Close #x
                    End If
                End If
            End If
        End If
    Next i
    '---création des feuilles---
    If d.Count Then
        tablo = d.keys
        For i = 0 To UBound(tablo)
            nomfeuille = "F" & Format(n + 1, "00") & tablo(i)
            fichier = fournisseurs & nomfeuille & ".csv"
            Set wb = Workbooks.Open(fichier, Local:=True) 'ouverture du fichier
            ActiveSheet.Copy After:=ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count)
            ActiveSheet.Columns.AutoFit 'ajustement largeurs
            wb.Close
        Next i
    End If
Next n
Sheets(1).Activate
End Sub
Avec le fichier de 2 000 000 de lignes la création de la feuille se fait chez moi en 32 secondes au lieu de 48 secondes :


A+
Bonjour, plusieurs choses...
Certes ta solution est plus rapide car tu charges tout en mémoire via un tableau.
Cependant elle est propriétaire car ton code tient compte du contenu du fichier où tu règles des problèmes de dates, etc. etc.
Et en plus il faut le maintenir.
A l'issue je ne vois qu'une seule feuille qui contient la totalité des lignes excel.
Personnellement je ne vois pas l'intérêt de charger dans une feuille 1 045 000 lignes... elles ne seront jamais exploitées en lecture par un utilisateur métier.
Ma solution en effet plus coûteuse en temps et en revanche générique, elle a pour but de charger un fichier dans un modèle données afin de l'exploiter via des TCD ou autre en filtrant les donnée ou tout simplement agréger les données pour en tirer des KPI ou des KRI afin de les présenter dans un tableau de bord.
Après choix en mettre le "nez" dans du VBA (ton code certes performant mais réservé déjà aux initiés dans le domaines). Le passage à Pwq et PowerPivot peut sembler déroutant au premier abord mais avec un peu d'investissement on arrive très vite à quelque chose.
Après les deux solutions se discutent en effet :) merci pour ta contribution :)
 

Titof06

XLDnaute Junior
Bonjour à vous 3,

Je vous remercie pour vos diverses solutions.

Je vais adapter ces solutions à mon besoin.

Je tenais à vous remercier pour ces propositions qui vont bien me dépanner dans ce que je dois extraire comme informations.

à bientôt 👍

Titof06 :)
 

job75

XLDnaute Barbatruc
Bonjour le forum,

Bien noter que la feuille de 1 000 000 de lignes est un cas limite, je l'ai créée pour tester la macro.

En réalité il y aura beaucoup de feuilles fournisseurs, filtrées sur leurs dates en colonne 8, avec chacune quelques milliers de lignes.

Il sera toujours possible de modifier la macro pour filtrer sur d'autres colonnes.

A+
 

Titof06

XLDnaute Junior
Bonjour job75,

Même si le traitement met du temps, cela me convient parfaitement dans ces dispositions.

Je vais traiter plus de 2.000.000 de lignes, le temps de traitement ne sera pas un problème lorsque la solution est trouvée, comme c'est le cas pour moi.

Je testerai également avec l'option PowerQuery et PowerPivot.

Encore un grand merci 👍 👍

Titof06 :)
 

oguruma

XLDnaute Occasionnel
Bonjour job75,

Même si le traitement met du temps, cela me convient parfaitement dans ces dispositions.

Je vais traiter plus de 2.000.000 de lignes, le temps de traitement ne sera pas un problème lorsque la solution est trouvée, comme c'est le cas pour moi.

Je testerai également avec l'option PowerQuery et PowerPivot.

Encore un grand merci 👍 👍

Titof06 :)
Bonjour la Teams "2000 000" en fait qq soit la solution et le temps... le tout est de charger les données au moins une fois, le deal ce sera donc la patience. On ne va pas s'amuser à faire du refresh toutes les heures.... sauf en cas de mise à jour... reste dans ce cas à en déterminer la fréquence...
La cible primaire reste : le chargement de 2 000 000 de lignes voir plus..... et ensuite de les exploiter via des TCD etc. etc. etc.
Dans l'étude fonctionnelle voir aussi si on a vraiment besoin des 2 000 000 (cas d'exemple dans la volumétrie) et dans ce cas passer par un nettoyage préalable en pwq avec des filtres ou d'éclater le fichier de 2000 000 en plusieurs et on rejoint dans ce la solution VBA de job75 qui proposait une solution similaire.....

En synthèse tout est dans l'analyse du besoin : que veut réellement l'utilisateur métier ? :) ce que nous informaticiens avons toujours les plus grandes difficultés à faire dire à nos utilisateurs... qui ne maîtrisent peut-être pas les données qu'ils nous confient... (cas vécu perso à de nombreuses reprises) --> en phase ?
 

oguruma

XLDnaute Occasionnel
Bonjour le forum,

Bien noter que la feuille de 1 000 000 de lignes est un cas limite, je l'ai créée pour tester la macro.

En réalité il y aura beaucoup de feuilles fournisseurs, filtrées sur leurs dates en colonne 8, avec chacune quelques milliers de lignes.

Il sera toujours possible de modifier la macro pour filtrer sur d'autres colonnes.

A+
Hello, "Il sera toujours possible de modifier la macro pour filtrer sur d'autres colonnes." c'est en fait la partie qui me gêne un peu. Perso je me mets "dans la peau" d'un User Friendly à qui je livre une application sans qu'il ait à retoucher quoique ce soit dans la conception du classeur Excel. Même si on livre avec du Pwq on peut des requêtes à "tiroir" avec les critères définis par l'utilisateur et il n'aura plus qu'à les sélectionner via une liste déroulante par exemple. J'avais fait cela dans un de mes projets précédent. Livraison d'un fichier "clic and run" où il n'avait qu'à renseigner la dernière version de son fichier de données.
Je dis toujours nos utilisateurs "sont de grands enfants". le VBA c'est bien pour les personnes averties c'est comme si tu remettais une caisse à outils dangereux à un enfant de 5 ans aie aie aie :)
 

oguruma

XLDnaute Occasionnel
Bonjour @oguruma

Tu peux donner un exemple de rendu, c'est à dire dans le fichier texte (txt ou csv)
Il y a certes 2 000 000 de lignes mais qu'elle en serait la règle pour en extraire uniquement les lignes qui correspondent à des valeurs dans des colonnes.
Tu peux me donner un exemple :
la première ligne de titre = la ligne 1
Il y a x colonnes qui ont des titres (des champs)
Qu elle sont les conditions (les x N° de colonnes)

J'aimerais bien essayer d en extraire juste les lignes que l'ont souhaite sur cette infinité de lignes.

Je vais en tester la rapidité j ai une idée de code très différente de @job75 (les tableaux je connais je m ennuie maintenant avec cela)

Je vais essayer un VBA différent mais il me faudrait un exemple pour que je puisse travailler sur votre même base pour en comparer les vitesses de traitements.

Pourquoi pas partager ensuite et apprendre votre méthode et si la mienne et au point je vous la partage et vous l explique points par points mais je dois réfléchir à cette méthode suite à votre résultat = données d entré / donné de sortie

Au plaisir de vous lire
Hello, ok ça marche je reviens vers toi dès que j'ai un peu de temps pour te faire ce montage avec un fichier avec moins de volumétrie pour des raisons pratiques.
J'avais je crois à ce propos si ça peut aider fait un post sur la constructions de RQ Pwq à tiroirs.... sinon je dois avoir cela en magasin ;)
 

Titof06

XLDnaute Junior
Bonjour oguruma,

Oui, ce que tu dis est très réel.

Mais je reçois un fichier qui sera en moyenne aux alentours des 2.000.000 de lignes, et la société qui nous envoie ce fichier ne peut pas faire moins....d'après ce qu'ils disent.
Je pense qu'il pourrait réduire la fenêtre de date afin de limiter le nombre de lignes, c'est ce que je leur ai proposé, mais apparemment, ce n'est pas possible pour eux.

J'ai fait le test avec la solution de job75 (qui met du temps, mais fonctionne bien), et je vais essayer de réduire le nombre de lignes avec PowerQuery et PowerPivot, voir si je peux gagner du temps de traitement.

Le traitement est à faire chaque début de semaine, afin de voir ce qui s'est passé la semaine précédente.

Ce fichier est une mise à jour tarifaire de plusieurs fournisseurs en plomberie-chauffage-sanitaire-climatisation.
Il y a donc beaucoup de fournisseurs et références par fournisseur. On le reçoit via un serveur FTP.

Merci pour tous ces échanges, très constructifs pour moi.

Bonne journée à tous 👍

Titof06 :)
 

oguruma

XLDnaute Occasionnel
Bonjour oguruma,

Oui, ce que tu dis est très réel.

Mais je reçois un fichier qui sera en moyenne aux alentours des 2.000.000 de lignes, et la société qui nous envoie ce fichier ne peut pas faire moins....d'après ce qu'ils disent.
Je pense qu'il pourrait réduire la fenêtre de date afin de limiter le nombre de lignes, c'est ce que je leur ai proposé, mais apparemment, ce n'est pas possible pour eux.

J'ai fait le test avec la solution de job75 (qui met du temps, mais fonctionne bien), et je vais essayer de réduire le nombre de lignes avec PowerQuery et PowerPivot, voir si je peux gagner du temps de traitement.

Le traitement est à faire chaque début de semaine, afin de voir ce qui s'est passé la semaine précédente.

Ce fichier est une mise à jour tarifaire de plusieurs fournisseurs en plomberie-chauffage-sanitaire-climatisation.
Il y a donc beaucoup de fournisseurs et références par fournisseur. On le reçoit via un serveur FTP.

Merci pour tous ces échanges, très constructifs pour moi.

Bonne journée à tous 👍

Titof06 :)
Question à ce poser aussi : Excel est-il le bon outil ? (à la lecture de ta réponse). Une base ACCESS avec une mise à jour différentielle serait peut-être la solution ? ou dans véhicule plus lourd.... une base Oracle ou SQLServer ou en mode open source avec du "mySQL" mais on sort de la bureautique pour arriver à de L'INFORMATIQUE ;) solution plus couteuse certes mais qui offre d'autres portes en termes de requêtes.
Et cette solution passe donc par la DSI ;)
Ou plan "B" PowerBI Desktop avec l'infrastructure serveur complète, c-a-d que PowerBI va charger les données à partir d'un serveur de BDD via des requêtes prédéfinies.
 

Titof06

XLDnaute Junior
Bonjour oguruma,

Oui, c'est aussi vrai, mais là, je ne gère pas ce genre de décision.

On est une entreprise indépendante, mais intégrée dans un groupement qui gère tout cela.

Donc un peu les pieds et poings liés !

On fait donc avec les moyens du bord.

Encore Merci.

Bonne journée,

Titof06 :)
 

job75

XLDnaute Barbatruc
Je viens de créer le fichier texte de 2 000 000 de lignes avec 200 fournisseurs de 10 000 lignes chacun.

Avec la macro du post #33 les 200 fichiers CSV se créent chez moi en 284 secondes.

Les 200 feuilles en 234 secondes.
 

Discussions similaires

Statistiques des forums

Discussions
315 098
Messages
2 116 198
Membres
112 681
dernier inscrit
romain38