Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Macros et VBA Excel Discussion :

VBA - Traitement d'un fichier texte rapatrié ligne par ligne


Sujet :

Macros et VBA Excel

  1. #1
    Nouveau membre du Club
    VBA - Traitement d'un fichier texte rapatrié ligne par ligne
    Bonjour,
    Je possède une macro excel, modifiée maintes fois, qui permet de :
    1/ rapatrier un dossier de plusieurs fichiers texte.
    2/ Dans chacun de ces fichiers texte, il y a des informations séparées par des ";", ceci avec beaucoup de ligne

    => la macro permet d'importer dans une feuille excel les informations en remplaçant le ";" par un changement de colonne.

    Mon problème est le suivant : Il y a 10 feuilles dans le classeur, et chaque feuille comporte facilement 500 000 lignes (selon les fichiers texte)

    Je voudrais savoir si il n'y a pas un moyen d’accélérer le processus qui prend facilement 45mn-1h si les fichiers texte sont gros
    (utilisation de buffer ? suppression d'une instruction redondante que je ne trouve pas ? je me suis un peu perdu)

    En fait je voudrais la même fonction que la fonction de rapatriement d'un fichier csv dans l'onglet données, qui est bien plus rapide que ma macro avec un rapatriement fait à la main, point virgule par point virgule...


    La boucle de rapatriement est la suivante :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
     
     
    Private Sub LigneAvecSplit(nomsfich As String)
     
        Dim Tbl
        Dim Ligne As String, Chemin As String
        Dim i As Integer
        Dim j As Long
     
        'Chemin = ThisWorkbook.Path
        Chemin = UserForm1.TextBox1.Text
        'NomFicTxt = "\Archives\" & nomsfich & ".txt"
        NomFicTxt = "\" & nomsfich & ".txt"
     
        'ouvre le fichier
        Open Chemin & NomFicTxt For Input As #1
     
            'boucle sur toutes les lignes du fichier
            Do While Not EOF(1)
     
                'récupère la ligne entière
                Line Input #1, Ligne
     
                'sépare les différentes valeurs en les stockant dans un tableau
                j = j + 1
                Tbl = Split(Ligne, ";")
     
                'puis les inscrit dans les cellules des différentes colonnes
                For i = 0 To UBound(Tbl)
     
                    Sheets(nomsfich).Cells(j, i + 1) = Tbl(i)
     
                Next i
     
            Loop
     
        Close #1
     
    End Sub


    Merci d'avance pour votre lecture

  2. #2
    Expert éminent sénior
    Bonjour
    Citation Envoyé par neflerine Voir le message


    En fait je voudrais la même fonction que la fonction de rapatriement d'un fichier csv dans l'onglet données, qui est bien plus rapide que ma macro avec un rapatriement fait à la main, point virgule par point virgule...
    Tu dois faire allusion à PowerQuery qui peut rapatrier tous les fichiers d'un dossier

    Mais 10 feuilles de 500 000 lignes c'est lourd pour Excel

    Tu peux préciser le contexte et la finalité ?
    Chris

    Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson.
    Confucius

    ----------------------------------------------------------------------------------------------
    En cas de résolution, n'hésitez pas cliquer sur c'est toujours apprécié...

  3. #3
    Membre actif
    Bonjour,

    Votre code insère ligne par ligne votre fichier texte dans Excel. De plus vous n'utilisez pas application.screenupdating = false qui permet de figer l'écran et de gagner beaucoup de temps.

    Si on garde le principe VBA je vous conseille de reporter vos lignes CSV dans un tableau mémoire puis de reporter ce tableau principal dans Excel.
    C'est toujours sympa de savoir si on vous a aidé ou non. Pensez-y

    N'hésitez pas à marquer le sujet comme résolu le cas échéant.

  4. #4
    Nouveau membre du Club
    Merci j'ai résolu mon problème en faisant très simple:
    Avec l'enregistreur de macro, j'ai fais la fonction d'importation de fichier txt/csv.

    Que du séquentiel, aucune boucle.

    Par contre j'ai a présent besoin de fusionner mes différentes feuilles en une seule appelée "synthèse"
    Sachant que mes différents feuilles n’ont pas toutes les mêmes noms de colonnes exemple :

    Feuille synthèse : colonne 1 2 3 4 5
    (La feuille synthèse contient de base toutes les noms de colonnes qui existent)

    Feuille 1 : Colonne 1 2 3
    Feuille 2 : Colonne 1 5 6

    La colonne 1 correspond à l'ID de la donnée, mais je n'ai pas d'idée comment fusionner tout cela

    Donc pour resumer j'ai plusieurs feuilles avec des colonnes differentes (à part l'ID qui se retrouve dans toutes les feuilles) et j'aimerais les fusionner dans un onglet synthese.
    J'ai cherché, mais je trouve toujours des exemple avec des feuilles au squelette identique, ce qui n'est pas mon cas.

  5. #5
    Nouveau membre du Club
    Est il possible d'effectuer un test ? Par exemple va chercher une colonne 2 dans synthese, et recopie la à son emplacement

  6. #6
    Responsable
    Office & Excel

    Salut

    Merci de préciser ta version d'Excel. Je suppose et j'espère que tu es au moins en 2010.

    Citation Envoyé par neflerine Voir le message
    [...]

    Par contre j'ai a présent besoin de fusionner mes différentes feuilles en une seule appelée "synthèse"
    Sachant que mes différents feuilles n’ont pas toutes les mêmes noms de colonnes exemple :
    [...]
    Ce que tu expliques, ainsi que le rapatriement des fichiers CSV, pourrait être réalisé avec l'outil que tu as évoqué et que Chris a nommé: Power Query. Mais comme le dit Chris, il faudrait que tu précises un peu la situation de départ et la finalité. Tu peux t'inspirer de cette vidéo sur mon blog qui explique comment fusionner des tables sur base d'une colonne commune, et de nombreuses réponses Power Query ont été apportées sur le forum à ce sujet. Un tout petit peu de recherche devrait de permettre de trouver ton bonheur.
    "Plus les hommes seront éclairés, plus ils seront libres" (Voltaire)
    ---------------
    Mes remarques et critiques sont purement techniques. Ne les prenez jamais pour des attaques personnelles...
    Le VBA ne palliera jamais une mauvaise conception de classeur ou un manque de connaissances des outils natifs d'Excel...
    Ce ne sont pas des bonnes pratiques parce que ce sont les miennes, ce sont les miennes parce que ce sont des bonnes pratiques
    VBA pour Excel? Pensez D'ABORD en EXCEL avant de penser en VBA...
    Vous avez apprécié la réponse? =>
    ---------------

  7. #7
    Nouveau membre du Club
    Merci beaucoup pour ces conseils, je vais potasser tout cela et je reviens vers vous pour dire comment j'ai procédé (ou essayé tout du moins )

  8. #8
    Nouveau membre du Club
    Bonjoir.
    Je suis en Excel 2007 et ce code passera dans plusieurs version dexcel, raison pour laquelle j'aurais souhaité rester simple dans le code (pas de power query finalement).

    J'aimerais savoir quelle operation dans ma boucle Do While not EOF est longue et fastidieuse pour le processeur et comment l'optimiser.

    Est ce le fait d'écrire ligne par ligne Tbl(i) dans la feuille excel ?
    Stocker mon fichier texte dans un tableau multidimensionnel est il la solution ?

    Ou peut etre qu'il y a encore plus simple pour optimiser cette boucle ?

    Merci a vous bon dimanche

  9. #9
    Responsable
    Office & Excel

    Excel 2007 => Exit Power Query qui n'est dispo qu'à partir de la 2010.

    Je m'orienterais vers une solution ADODB qui me récupère un fichier de 100000 lignes de façon instantanée.

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    Sub Test()
      Dim cn As Object
      Dim rs As Object
      Dim Path As String, Filename As String
      Dim Target As Range
     
      Path = "c:\data\Temp\"
      Filename = "source.csv"
      If Not Range("tableau1").ListObject.DataBodyRange Is Nothing Then Range("tableau1").ListObject.DataBodyRange.Delete
      Set Target = Range("tableau1").ListObject.ListRows.Add().Range(1)
     
      Set cn = CreateObject("ADODB.Connection")
      cn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & Path & ";Extended Properties=""text;HDR=Yes;FMT=Delimited;CharacterSet=65001"";"
      cn.Open
      Set rs = cn.Execute("select * from " & Filename)
      If Not rs.EOF Then
        Target.CopyFromRecordset rs
        rs.Close
        cn.Close
        Set rs = Nothing
        Set cn = Nothing
        Range("tableau1[Prénom]").TextToColumns Destination:=Target, DataType:=xlDelimited, semicolon:=True
      End If
    End Sub


    Quelques précisions:
    • On remarque que le dossier est considéré comme une base de données, le fichier CSV comme une table;
    • Normalement, on peut préciser le délimiteur dans la chaine de connexion avec Delimiter(, mais chez moi, cette info n'est pas prise en compte. On peut modifier la clé de registre mais je n'aime pas que mon code vba modifie un truc externe;
    • CharacterSet=65001 => utf-8. J'espère que ton csv est en utf8, sinon il faudra adapter;
    • Comme le séparateur ; n'est pas reconnu, j'ai dû utiliser TextToColumn pour séparer les données sur les lignes;
    • Ce genre de truc se teste toujours car CSV n'est pas une norme et il y a des bonnes et des moins bonnes façons de créer un fichier CSV;
    • On pourrait tendre vers du générique, mais ce n'est pas le propos ici. J'illustre une façon de faire que tu dois adapter à ta situation.
    "Plus les hommes seront éclairés, plus ils seront libres" (Voltaire)
    ---------------
    Mes remarques et critiques sont purement techniques. Ne les prenez jamais pour des attaques personnelles...
    Le VBA ne palliera jamais une mauvaise conception de classeur ou un manque de connaissances des outils natifs d'Excel...
    Ce ne sont pas des bonnes pratiques parce que ce sont les miennes, ce sont les miennes parce que ce sont des bonnes pratiques
    VBA pour Excel? Pensez D'ABORD en EXCEL avant de penser en VBA...
    Vous avez apprécié la réponse? =>
    ---------------

  10. #10
    Responsable
    Office & Excel

    Pour éviter de devoir passer par TextToColumns, on pourrait passer par un fichier Schema.ini placé dans le dossier du fichier

    Ce fichier aura le contenu suivant:
    Code ini :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    [source.csv]
    Format=Delimited(<img src="images/smilies/icon_wink.gif" border="0" alt="" title=";)" class="inlineimg" />
    DecimalSymbol=.


    On se passe alors de la dernière ligne. Le fichier schema.ini, qui peut être créé par VBA avant la manip et supprimé après, peut être complété par plein d'autres infos ( https://docs.microsoft.com/en-us/sql...l-server-ver15)

    Voici alors le code (sans la création du fichier INI qu'il faut soit créer à la main soit par macro, pour le supprimer après, par exemple)
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    Sub Test()
      Dim cn As Object
      Dim rs As Object
      Dim Path As String, Filename As String
      Dim Target As Range
     
      Path = "c:\data\Temp\"
      Filename = "source.csv"
      If Not Range("tableau1").ListObject.DataBodyRange Is Nothing Then Range("tableau1").ListObject.DataBodyRange.Delete
      Set Target = Range("tableau1").ListObject.ListRows.Add().Range(1)
     
      Set cn = CreateObject("ADODB.Connection")
      cn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & Path & ";Extended Properties='text;HDR=Yes;CharacterSet=65001';"
      cn.Open
      Set rs = cn.Execute("select * from " & Filename)
      If Not rs.EOF Then
        Target.CopyFromRecordset rs
        rs.Close
        cn.Close
        Set rs = Nothing
        Set cn = Nothing
      End If
    End Sub
    "Plus les hommes seront éclairés, plus ils seront libres" (Voltaire)
    ---------------
    Mes remarques et critiques sont purement techniques. Ne les prenez jamais pour des attaques personnelles...
    Le VBA ne palliera jamais une mauvaise conception de classeur ou un manque de connaissances des outils natifs d'Excel...
    Ce ne sont pas des bonnes pratiques parce que ce sont les miennes, ce sont les miennes parce que ce sont des bonnes pratiques
    VBA pour Excel? Pensez D'ABORD en EXCEL avant de penser en VBA...
    Vous avez apprécié la réponse? =>
    ---------------

  11. #11
    Nouveau membre du Club
    Merci pour cette rapidité et efficacité.

    Ton code est propre et fonctionnel et utilise le système d'exécution de requête (Select * from...)

    De mon côté je lisais le cours vba publié sur developpez et jai trouvé le code suivant qui me plait beaucoup.
    Pour ma compréhension j'aimerais savoir si ce code n'utilisant pas le système de requête est optimisé
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    Public Sub LireFichierTexte()
     
    Dim NumFichier As Integer, TabLigne() As String, tabCol() As String, Recup As String
    Dim cmpt1 As Long, cmpt2 As Long
     
    NumFichier = FreeFile
    Open Chemin & "texte.txt" For Binary Access Read As #NumFichier Recup = String(LOF(NumFichier), " ")
     
    Get #NumFichier, Close #NumFichier
     
    , Recup
     
    With Worksheets("Feuil1").Range("A1")
    TabLigne = Split(Recup, vbCrLf)
    For cmpt1 = 0 To UBound(TabLigne)  tabCol = Split(TabLigne(cmpt1), ",") For cmpt2 = 0 To UBound(tabCol)
    .Offset(cmpt1, cmpt2).Value = tabCol(cmpt2)
    Next cmpt2
    Next cmpt1
    End With
     
    End Sub

    1ere question
    Qu'en penses tu ? par rapport a ton code et a mon code inital ?

    2eme question
    Pour moi l'opération couteuse en processeur est le fait de copier ligne par ligne dans la feuille excel. Si on stocke les lignes dans un tableau multidimensionnel (disons de 1000 lignes) et que l'on effectue la copie toutes les 1000 lignes, est ce que ce sera plus rapide ?
    On agirait un peu comme une sorte de buffer.
    Mes fichiers texte sont des notifications d'alarmes et peuvent parfois contenir plus de 500 000 lignes

  12. #12
    Responsable
    Office & Excel

    Le problème du Split, c'est que tu peux avoir des caractères de séparation dans le texte (si tu as un texte comme ceci, par exemple avec des mots-clé "VBA;Excel;Formules" ou "VBA,Excel,Formules"), tu vas avoir un gros souci lors de l'utilisation de Split(), selon, bien sûr, le séparateur de champs qui sera , ou ;

    Un ADODB avec un schema.ini a plus de chances de garantir une extraction propre.

    Sinon, d'une façon générale, passer par un array que l'on alimente par boucle puis que l'on pousse en une fois dans une plage redimensionnée sera plus rapide que de pousser ligne par ligne, surtout dans un tableau structuré qui a tendance à être plus lent avec ce genre de traitement.
    "Plus les hommes seront éclairés, plus ils seront libres" (Voltaire)
    ---------------
    Mes remarques et critiques sont purement techniques. Ne les prenez jamais pour des attaques personnelles...
    Le VBA ne palliera jamais une mauvaise conception de classeur ou un manque de connaissances des outils natifs d'Excel...
    Ce ne sont pas des bonnes pratiques parce que ce sont les miennes, ce sont les miennes parce que ce sont des bonnes pratiques
    VBA pour Excel? Pensez D'ABORD en EXCEL avant de penser en VBA...
    Vous avez apprécié la réponse? =>
    ---------------

  13. #13
    Nouveau membre du Club
    Merci.
    En réfléchissant un peu au problème, les csv à importer ont un nombre de colonnes variables, donc je ne vois pas comment gérer plusieurs dimensions de manière dynamiques

    Pour un fichier csv mon tableau sera Tab (indice, colonnes 1, colonnes 2, colonnes 3) mais comme cela peut varier je vais rester sur ta solution qui me parait plus universelle.

    Dommage, pour la beauté de la chose, j'aurais bien voulu comprendre cet aspect

  14. #14
    Nouveau membre du Club
    J'ai essayé (pour l'apprentissage) de faire la lecture ligne par ligne et de placer le résultat dans un tableau 2D dans lequel je met Tab(Colonne, Ligne).
    Ligne en dernier car on ne peut redimensionner que la dernière dimension. avec Redim Preserve.

    Le problème est que lors de l'affectation de mon tableau dans ma feuille Excel avec Range(Cells...).Select = Tableau2d il me met l'inverse (colonne = ligne et ligne = colonne)

    Avec la boucle en commentaire plus bas dans le code ca marche très bien mais très lent. Connaissez vous l'astuce ?

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    'Redim preserve : Attention on à le droit de redimensionner uniquement la dernière dimension la plus à droite
     
    Sub EditInput()
    Application.Calculation = xlManual
    Application.ScreenUpdating = False
     
    Dim Index As Long
    Dim data() As Variant
    Dim i As Long
    Dim plage As Range
    Dim ReadFile As String
    ReadFile = ThisWorkbook.Path & "\Commandes.txt"
    Const ForReading = 1, ForWriting = 2, ForAppending = 3
     
    Set fs = CreateObject("Scripting.FileSystemObject")
    Set fin = fs.OpenTextFile(ReadFile, ForReading, TristateFalse)
    Index = 0
     
     
     
    Do While fin.AtEndOfStream <> True
     
    ReadData = fin.readline
    Splitdata = Split(ReadData, ";")
     
    ReDim Preserve data(0 To UBound(Splitdata), 0 To Index)
     
    For i = 0 To UBound(Splitdata)
    data(i, Index) = Splitdata(i)
    Next i
     
    Index = Index + 1
     
    Loop
    fin.Close
    'data (colonne, lignes)
     
    Worksheets("Feuil1").Range("A1").Resize(UBound(data, 2) + 1, UBound(data, 1) + 1).Value = data
     
     
    'For i = 0 To UBound(data, 2)
    '    For j = 0 To UBound(data, 1)
    '         Set plage = Worksheets("Feuil1").Range(Worksheets("Feuil1").Cells(i + 1, j + 1), Worksheets("Feuil1").Cells(i + 1, j + 1)) = data(j, i)
    '    Next j
    'Next i
     
     
     
     Application.Calculation = xlAutomatic
     Application.ScreenUpdating = True
     
    End Sub

  15. #15
    Responsable
    Office & Excel

    Pour repousser le tableau "inversé" dans Excel, tu peux utiliser Application.Transpose(MyArray)


    Mais sur des gros tableaux, il n'y a pas de miracles. Pense à mettre Application.ScreenUpdating = False en début de macro, et peut-être aussi à passer en mode de calcul manuel en début et à rétablir en fin.
    "Plus les hommes seront éclairés, plus ils seront libres" (Voltaire)
    ---------------
    Mes remarques et critiques sont purement techniques. Ne les prenez jamais pour des attaques personnelles...
    Le VBA ne palliera jamais une mauvaise conception de classeur ou un manque de connaissances des outils natifs d'Excel...
    Ce ne sont pas des bonnes pratiques parce que ce sont les miennes, ce sont les miennes parce que ce sont des bonnes pratiques
    VBA pour Excel? Pensez D'ABORD en EXCEL avant de penser en VBA...
    Vous avez apprécié la réponse? =>
    ---------------

  16. #16
    Nouveau membre du Club
    Je viens de reussir la lecture ligne par ligne Splittée dans un tableau en mettant chaque ligne dans un tableau 2D tampon de contenant 100 lignes et x colonnes

    Le problème vient au moment de passer le tableau 2D, il manque toujours la 100eme ligne à chaque passage

    J'ai repris ma boucle initiale postée dans mon premier post et adapté avec un tampon pour copier 100 lignes par 100 lignes dans Excel.
    Il manque cette dernière ligne à chaque fois, mais niveau rapidité ya pas photo, il a lu et ecrit un fichier txt de 10mo en 5 secondes, aussi rapide qu'une requète je trouve.

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    Private Sub LigneAvecSplit()
     
        Dim Tbl
        Dim Ligne As String, Chemin As String
        Dim i, j As Integer
        Dim tab2D() As Variant
        Dim ligneencours As Long
     
        'Chemin = ThisWorkbook.Path
        Chemin = ThisWorkbook.Path & "\Commandes.txt"
        'NomFicTxt = "\Archives\" & nomsfich & ".txt"
        'NomFicTxt = "\" & nomsfich & ".txt"
     
         Open Chemin For Input As #1
        Line Input #1, Ligne
        Tbl = Split(Ligne, ";")
        ReDim Preserve tab2D(100, 0 To UBound(Tbl))
        Close #1
     
        'ouvre le fichier
        Open Chemin For Input As #2
     
            'boucle sur toutes les lignes du fichier
            Do While Not EOF(2)
     
                i = i + 1
     
                'récupère la ligne entière et sépare les différentes valeurs en les stockant dans un tableau
                Line Input #2, Ligne
                Tbl = Split(Ligne, ";")
     
                'inscrit chaque ligne dans tab2D
                For j = 0 To UBound(Tbl)
                    tab2D(i, j) = Tbl(j)
                Next j
     
                If i = 100 Then
     
                    Worksheets("Feuil1").Range("A1").Offset(ligneencours, 0).Resize(UBound(tab2D, 1) + 1, UBound(tab2D, 2) + 1).Value = tab2D
                    ligneencours = ligneencours + i
                    i = 0
                End If
     
            Loop
     
        Close #2
     
    End Sub

  17. #17
    Responsable
    Office & Excel

    Dans tes déclarations, tu dois préciser le type de i, sinon c'est un variant qui est vide. En le typant As Integer, il vaudra 0 au départ

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    Dim i as integer, j As Integer


    Au début de la boucle Do While Not EOF(2), tu dois supprimer la ligne i = i +1 puisque tu commences à 0. Il faut voir si ton offset est correct après cela. A toi de tester, je ne l'ai pas fait
    "Plus les hommes seront éclairés, plus ils seront libres" (Voltaire)
    ---------------
    Mes remarques et critiques sont purement techniques. Ne les prenez jamais pour des attaques personnelles...
    Le VBA ne palliera jamais une mauvaise conception de classeur ou un manque de connaissances des outils natifs d'Excel...
    Ce ne sont pas des bonnes pratiques parce que ce sont les miennes, ce sont les miennes parce que ce sont des bonnes pratiques
    VBA pour Excel? Pensez D'ABORD en EXCEL avant de penser en VBA...
    Vous avez apprécié la réponse? =>
    ---------------

  18. #18
    Nouveau membre du Club
    Ça marche du tonnerre merci !!

    D'ailleurs ya t-il une autre solution pour compter le nombre de colonne ? Car J'ouvre une premiere fois le fichier pour compter le nombre de colonnes, ensuite je dimensionne mon tableau 2D et ensuite je rouvre une 2eme fois le fichier pour faire mes traitements.

    J'ai mis le chronomètre :
    Pour un fichier de 30mo
    ligne par ligne classique est hors jeu. plus de 5 minutes
    Ligne par ligne avec tampon tableau 2D est equivalent à la requete que tu m'as donné, de l’ordre de 15 secondes pour 500k lignes et 10 colonnes.

    Mais cette nouvelle solution me fait de l'oeil car je peux mettre un compteur pour suivre l'évolution de l'opération (c'est en fait cela que je n'appreciais pas dans la solution requete SQL)


    D'ailleurs pour ta requete est-il possible de mettre les options contenue dans le.ini dans la macro en dur ?

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    [source.csv]
    Format=Delimited(<img src="images/smilies/icon_wink.gif" border="0" alt="" title=";)" class="inlineimg" />
    DecimalSymbol=.

  19. #19
    Responsable
    Office & Excel

    Tu pourrais déporter le dimensionnement du tableau dans la boucle, lorsque i vaut 0. De plus, le Preserve n'est pas nécessaire puisque ton tableau ne contient encore rien.

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    Private Sub LigneAvecSplit()
      Dim Tbl
      Dim Ligne As String, Chemin As String
      Dim i As Integer, j As Integer
      Dim tab2D() As Variant
      Dim ligneencours As Long
     
      'Chemin = ThisWorkbook.Path
      Chemin = "C:\Users\Muta\Desktop\Archives\Nouveau dossier\Commandes.txt"
      'NomFicTxt = "\Archives\" & nomsfich & ".txt"
      'NomFicTxt = "\" & nomsfich & ".txt"
     
      'ouvre le fichier
      Open Chemin For Input As #2
        'boucle sur toutes les lignes du fichier
        Do While Not EOF(2)
        'récupère la ligne entière et sépare les différentes valeurs en les stockant dans un tableau
        Line Input #2, Ligne
        Tbl = Split(Ligne, ";")
        If i = 0 Then ReDim tab2D(100, 0 To UBound(Tbl)) ' Preserve Inutile
     
        'inscrit chaque ligne dans tab2D
        For j = 0 To UBound(Tbl)
          tab2D(i, j) = Tbl(j)
        Next j
     
        If i = 100 Then
          Worksheets("Feuil1").Range("A1").Offset(ligneencours, 0).Resize(UBound(tab2D, 1) + 1, UBound(tab2D, 2) + 1).Value = tab2D
          ligneencours = ligneencours + i
          i = 0
        End If
      Loop
     
      Close #2
    End Sub



    Attention que ton compteur va sensiblement ralentir le process puisque tu vas demander une opération d'affichage qui est coûteuse, que ce soit par la statusbar ou autre...
    "Plus les hommes seront éclairés, plus ils seront libres" (Voltaire)
    ---------------
    Mes remarques et critiques sont purement techniques. Ne les prenez jamais pour des attaques personnelles...
    Le VBA ne palliera jamais une mauvaise conception de classeur ou un manque de connaissances des outils natifs d'Excel...
    Ce ne sont pas des bonnes pratiques parce que ce sont les miennes, ce sont les miennes parce que ce sont des bonnes pratiques
    VBA pour Excel? Pensez D'ABORD en EXCEL avant de penser en VBA...
    Vous avez apprécié la réponse? =>
    ---------------

  20. #20
    Nouveau membre du Club
    Voila comme ca c'est parfait.
    J'ai rajouté un compteur toute les 1000 lignes uniquement ce qui me parait plutot pas mal
    Que pense tu de cette solution par rapport à une requete de ton point de vue ?

    Je trouve que sans le fichier .ici j'ai une préférence pour la tienne mais je voulais y arriver et aller jusqu'au bout de mon histoire de "buffer"

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    Private Sub LigneAvecSplit()
     
    Application.Calculation = xlManual
    Application.ScreenUpdating = False
     
        Dim Tbl
        Dim Ligne As String, Chemin As String
        Dim i, j As Integer
        Dim tab2D() As Variant
        Dim ligneencours As Long
        Dim time As Date
        time = Timer
     
     
        Chemin = ThisWorkbook.Path  & "\Commandes.txt"
     
        'ouvre le fichier
        Open Chemin For Input As #2
     
            'boucle sur toutes les lignes du fichier
            Do While Not EOF(2)
    	If i = 0 Then ReDim tab2D(1000, 0 To UBound(Tbl))
                'récupère la ligne entière et sépare les différentes valeurs en les stockant dans un tableau
                Line Input #2, Ligne
                Tbl = Split(Ligne, ";")
     
                'inscrit chaque ligne dans tab2D
                For j = 0 To UBound(Tbl)
                    tab2D(i, j) = Tbl(j)
                Next j
     
                i = i + 1
     
                If i = 1001 Then
     
                    Worksheets("Feuil1").Range("A1").Offset(ligneencours, 0).Resize(UBound(tab2D, 1) + 1, UBound(tab2D, 2) + 1).Value = tab2D
                    ligneencours = ligneencours + i
                    i = 0
                    Debug.Print "Lignes Rapatriées : " & ligneencours
                    DoEvents
                End If
     
            Loop
     
        Close #2
     
        Debug.Print Timer - time & " secondes"
     
        'For i = 0 To UBound(data, 2)
    '    For j = 0 To UBound(data, 1)
    '        Worksheets("Feuil1").Range(Worksheets("Feuil1").Cells(i + 1, j + 1), Worksheets("Feuil1").Cells(i + 1, j + 1)) = data(j, i)
    '    Next j
    'Next i
     
    Application.Calculation = xlAutomatic
    Application.ScreenUpdating = True
     
    End Sub

###raw>template_hook.ano_emploi###