IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
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 :

Lecture/écriture de fichier code trop lent


Sujet :

Macros et VBA Excel

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    103
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 103
    Par défaut Lecture/écriture de fichier code trop lent
    Bonjour à tous,

    Suite à mon message sur le traitement d'un fichier xml en vba ici que j'ai résolu, JP m'a conseillé de poster un nouveau message pour voir si il y aurait moyen d'améliorer mon code pour qui actuellement très lent.

    Donc voilà en gros je dois parcourir un fichier texte pour rechercher des caractères spécifiques et les remplacer par d'autres.
    Pour cela j'ai décidé d'tuliser les FSO pour ouvrir le fichier texte, lire une ligne, la modifiée le cas échéant et l'écrire dans un nouveau fichier texte. Je n'ai pas trouver de solution pour modifier à la volée un fichier, je suis obligé d'en créer un nouveau et de copier le premier dedans. Pour la lecture tout ce passe bien mais l'écriture par les FSO était très lente, je suis donc passer avec les fonctions directe ce qui m'a fait gagner un peu de temps d'éxécution.

    Voici mon code :
    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
    Function XMLFilePreTreatment(ByVal InputFileName As String) As String
     
        Dim i As Long
        Dim Text As String
        Dim intFic As Integer
     
        Dim oFSO As Scripting.FileSystemObject
        Dim oTxtIn As Scripting.TextStream
        'Instanciation du FSO
        Set oFSO = New Scripting.FileSystemObject
        intFic = FreeFile
        XMLFilePreTreatment = (Split(InputFileName, ".")(0) & "_Corrected." & Split(InputFileName, ".")(1))
     
        'Ouverture des fichiers
        Set oTxtIn = oFSO.OpenTextFile(InputFileName, ForReading)
        Open XMLFilePreTreatment For Output As intFic
     
        'Traitement du fichier
        With oTxtIn
            Do While Not .AtEndOfStream
                Text = .ReadLine                    'Lecture de la ligne
                Text = Replace(Text, "&#", "##")    'Modification le cas échéant
                Print #intFic, Text                 'Ecriture dans un nouveau fichier
            Loop
        End With
     
        oTxtIn.Close
        Close intFic
     
    End Function
    A noter que ce code est long a éxécuter car les fichiers texte que je traite sont assez important, par exemple cela a pris 12 min sur un fichier 18,5Mo, 251 700 lignes et 18 906 486 caractères. Et ce fichier est plus petit que le standard. En standard je suis plutôt de l'ordre de 70Mo, 1 731 512 lignes ou encore 70 923 984 caratères.

    Donc voilà mon code est quand même très simple mais peut être y a-t-il encore un moyen de l'optimiser pour réduire le temps d'éxécution. Si vous avez des idées .

  2. #2
    Inactif  

    Homme Profil pro
    cuisiniste
    Inscrit en
    Avril 2009
    Messages
    15 374
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cuisiniste
    Secteur : Bâtiment

    Informations forums :
    Inscription : Avril 2009
    Messages : 15 374
    Billets dans le blog
    8
    Par défaut re
    Bonjour
    c'est du jamais vu un fichier texte de 70 mega
    selon moi il y a déjà un soucis a ce niveau la
    ensuite pourquoi ouvrir avec fso et écrire avec open fait le avec les deux avec open




    après vu la taille des fichier bon courage mais pour moi cela va etre certainement la cause de problèmes de mémoire attention au (White-screen)

    perso je rêverais la conception des fichiers textes
    mes fichiers dans les contributions:
    mail avec CDO en vba et mail avec CDO en vbs dans un HTA
    survol des bouton dans userform
    prendre un cliché d'un range

    si ton problème est résolu n'oublie pas de pointer : : ça peut servir aux autres
    et n'oublie pas de voter

  3. #3
    Membre émérite
    Homme Profil pro
    ingénieur d'étude
    Inscrit en
    Juin 2013
    Messages
    563
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : ingénieur d'étude
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2013
    Messages : 563
    Par défaut
    Bonjour,

    Il est envisageable de stocker quelques centaines/milliers de lignes dans une string avant d'appliquer le Replace, puis d'écrire toutes ces lignes d'un seul coup.
    En limitant les accès disques, ça pourrait faire gagner un petit peu de temps.

    Mais le plus logique me semblerait de passer par un utilitaire dédié, type Powershell.
    Avez-vous essayé de traiter l'un de vos fichiers sous Linux, avec un bon vieux 'sed'.
    Ca vous donnerait une idée de ce qui peut se faire de mieux en termes de temps d'exécution, et donc de savoir si vous avez beaucoup à gagner ou pas.

    Cordialement,

  4. #4
    Membre extrêmement actif Avatar de mjpmjp
    Homme Profil pro
    Retraité
    Inscrit en
    Avril 2012
    Messages
    1 133
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hautes Alpes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Santé

    Informations forums :
    Inscription : Avril 2012
    Messages : 1 133
    Par défaut
    bonjour,
    mise à part la méthode directe (à voir en dernier....prise de tête)
    pour VBA c'est OU lecture OU écriture alors on va faire les 2

    en lecture l'original
    et en parallèle
    en écriture le double (qui est vide au départ )

    on cherche la ligne à modifier
    si pas la ligne on copy dans double
    si c'est la ligne on modifie et on écrit dans double

    @+JP
    Caractéristiques (WEB) phpMyAdmin 4-74 , PHP 5-631 , Apache 2-427 , MySQL 5-719
    Présentation NAS DS-3615xs + 20Go , DSM 6.1.6-15266 Up1 , 12 * WD 4To WD4000F9YZ (10 raid 6+ )+(2 raid 1+) , LinkSys comutateur-switch lgs528p-eu , Onduleur UPS 720W Power Boxx Lcd (4*UPS + 4*MOD)
    Mes contributions (EXCEL) Form GRAPHIQUE: Gestion des boutons , Liste Onglet dynamique...GESTION de FILM

  5. #5
    Inactif  

    Homme Profil pro
    cuisiniste
    Inscrit en
    Avril 2009
    Messages
    15 374
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cuisiniste
    Secteur : Bâtiment

    Informations forums :
    Inscription : Avril 2009
    Messages : 15 374
    Billets dans le blog
    8
    Par défaut re
    re
    contrairement a ce que tu crois mjpmjp les if/else prennent de la ressource
    de toute façon sur des fichier aussi important je vois comment réduire sans risquer le white-screen

    je vais faire des test j'ai une idée
    il me reste a écrire un fichier d'autant de ligne
    mes fichiers dans les contributions:
    mail avec CDO en vba et mail avec CDO en vbs dans un HTA
    survol des bouton dans userform
    prendre un cliché d'un range

    si ton problème est résolu n'oublie pas de pointer : : ça peut servir aux autres
    et n'oublie pas de voter

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    103
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 103
    Par défaut
    Oui c'est pour cela que finalement j'ai opté pour la suppression du test if et direct l'application de la fonction replace.

  7. #7
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    103
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 103
    Par défaut
    Bonjour à tous,

    Merci pour vos réponses.

    @patricktoulon :
    c'est du jamais vu un fichier texte de 70 mega
    selon moi il y a déjà un soucis a ce niveau la
    Bah en fait c'est pas vraiment des fichiers textes, mais des fichiers xml que je parcours en tant que fichier texte mais je ne voulais entrer dans les détails pour pas compliquer le truc (et puis c'est déjà tout raconté dans mon premier post).

    ensuite pourquoi ouvrir avec fso et écrire avec open fait le avec les deux avec open
    Bonne question en fait c'est purement historique, j'ai commencé avec les FSO, je me suis rendu compte que l'écriture c'était long donc jai changé mais comme la lecture était rapide j'ai pas changé.

    @JP :
    faire un double du fichier , qui après traitement finira à la poubelle ...
    C'est déjà plus ou moins ce que je fait.

    parcourir ce double en lecture /écriture
    Il ne me semble pas que ça soit possible en VBA. en plus dès que tu ouvre un fichier en mode Ecriture il eest "vidé" de tout son contenu.

    rechercher ce qui dans ton cas pause problème : avec InStr(Data,"LanguageISO=" & Chr(34) & "ZH") > 0
    la ligne de traduction avec caractères chinois que l'on distingue par : Translation LanguageISO="ZH"

    dans cette ligne remplacer comme tu là dit "&#" par "##" avec : Replace(Data, "&#", "##")
    Finalement il s'avère que le ZH n'est plus suffisant, j'ai trouvé des caractères chinois dans d'autres lignes sans avoir le Zh avant, d'où le fait que je ne cherche plus ça mais directement le &#.

    @Ben_L :
    Il est envisageable de stocker quelques centaines/milliers de lignes dans une string avant d'appliquer le Replace, puis d'écrire toutes ces lignes d'un seul coup.
    En limitant les accès disques, ça pourrait faire gagner un petit peu de temps.
    J'avais envisagé cette solution à un moment mais je ne sais plus si je l'ai testée.

    Mais le plus logique me semblerait de passer par un utilitaire dédié, type Powershell.
    Avez-vous essayé de traiter l'un de vos fichiers sous Linux, avec un bon vieux 'sed'.
    Pour être honnête vous me parlez en chinois. A la base je bosse dans l'électronique et la programmation de µC embarqué et il m'arrive de faire du VBA... souvent .



    Sinon je viens de refaire un calcul sur l'éxécution de ma fonction et il s'avère que j'avais largement surévaluer le temps d'éxécution, pour un fichier de 70Mo j'ai eu un temps d'éxécution de 13.3 min. Ce qui est long mais encore acceptable...

  8. #8
    Membre extrêmement actif Avatar de mjpmjp
    Homme Profil pro
    Retraité
    Inscrit en
    Avril 2012
    Messages
    1 133
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hautes Alpes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Santé

    Informations forums :
    Inscription : Avril 2012
    Messages : 1 133
    Par défaut
    bonjour Coco47,
    une première piste :
    faire un double du fichier , qui après traitement finira à la poubelle ...
    parcourir ce double en lecture /écriture
    rechercher ce qui dans ton cas pause problème : avec InStr(Data,"LanguageISO=" & Chr(34) & "ZH") > 0la ligne de traduction avec caractères chinois que l'on distingue par : Translation LanguageISO="ZH"

    dans cette ligne remplacer comme tu là dit "&#" par "##" avec : Replace(Data, "&#", "##")et écrire cette ligne dans le double

    c'est ICI qu'il faut trouver comment supprimer et remplacer cette ligne OU modifier la directement

    @+JP
    Caractéristiques (WEB) phpMyAdmin 4-74 , PHP 5-631 , Apache 2-427 , MySQL 5-719
    Présentation NAS DS-3615xs + 20Go , DSM 6.1.6-15266 Up1 , 12 * WD 4To WD4000F9YZ (10 raid 6+ )+(2 raid 1+) , LinkSys comutateur-switch lgs528p-eu , Onduleur UPS 720W Power Boxx Lcd (4*UPS + 4*MOD)
    Mes contributions (EXCEL) Form GRAPHIQUE: Gestion des boutons , Liste Onglet dynamique...GESTION de FILM

Discussions similaires

  1. Code trop lent pour une écriture sur disque
    Par Anarchy64 dans le forum C
    Réponses: 6
    Dernier message: 12/12/2013, 19h54
  2. Lecture/écriture de fichiers de configuration
    Par Matthieu Brucher dans le forum Boost
    Réponses: 13
    Dernier message: 10/11/2008, 19h31
  3. [VS2005]lecture/écriture dans fichier binaire
    Par shadowmoon dans le forum Windows Forms
    Réponses: 10
    Dernier message: 25/09/2007, 17h30
  4. Lecture/écriture de fichiers UTF 16 LE
    Par Pill_S dans le forum Delphi
    Réponses: 8
    Dernier message: 19/12/2006, 18h08
  5. [Eclipse] Editeur de code trop lent
    Par Benzeghiba dans le forum Eclipse Java
    Réponses: 6
    Dernier message: 10/11/2005, 14h02

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo