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 :

Diminuer le temps d'une macro


Sujet :

Macros et VBA Excel

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre Expert Avatar de Gado2600
    Homme Profil pro
    Développeur Office VBA
    Inscrit en
    Mai 2013
    Messages
    909
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur Office VBA

    Informations forums :
    Inscription : Mai 2013
    Messages : 909
    Par défaut Diminuer le temps d'une macro
    Bonjour,

    Je suis actuellement sur un projet sous Excel où je dois importer plusieurs fichiers.
    La particularité de cette importation est que j'ai 3 types de fichiers (.csv) :
    • Ventes
    • Rebus
    • Casses

    J'ai donc mis en place une macro qui va s'appeler pour chacun de ces types de fichiers (stockés dans un même répertoire). Cette macro ouvrira 90 fichiers csv par types (soit 270 fichiers au total), pour récupérer des informations et les dispersées dans un fichier Excel.
    Le système fonctionne, avec exactement les mêmes données dans mes 270 fichiers pour mes tests (mis à part leurs noms, rien ne les différencies).

    Le soucis est que l'importation de toutes les Ventes prend environ 2min35, les Rebus prend 2min52 et les Casses prend 3min36. Ils sont importés dans le même ordre.
    Je perd donc du temps d'importation au fur et à mesure que j'ouvre et je ferme mes fichiers. Existerait-il quelque chose qui permettrait de réduire cet écart de temps à 0 ?

    Merci par avance.

    Cordialement,

  2. #2
    Membre émérite Avatar de Nico Chg
    Homme Profil pro
    Apprenti ingénieur Business Development
    Inscrit en
    Juillet 2014
    Messages
    352
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Apprenti ingénieur Business Development
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Juillet 2014
    Messages : 352
    Par défaut
    Bonjour !

    Réduire le temps à 0 me semble physiquement compliqué, mais on peut toujours faire quelque chose !

    Peux tu poster le code que tu utilise pour importer tes fichiers ? De mémoire, importer un csv ne prenait pas autant de temps (je ne sais pas pour 270 en revanche )

  3. #3
    Membre Expert
    Homme Profil pro
    Ingénieur
    Inscrit en
    Août 2010
    Messages
    730
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2010
    Messages : 730
    Par défaut
    Bonjour,

    C'est l'ouverture dans Excel qui prend beaucoup de temps.

    Moi je verrai bien la concaténation du texte des fichiers csv du même type afin d'en faire un seul fichier que tu ouvrirais alors dans Excel (soit 3 fichiers au total).
    Tu aurais juste à supprimer les entêtes de colonne en doublon avant ou après avoir concaténé.

    J'ai déjà traité environ 500 fichiers texte via VBA (analysés par expression régulière) et ça ne prenait que quelques secondes de mémoire (max 30 mais je crois que c'était moins) alors que j'appliquais 4 ou 5 expressions régulières relativement complexes.

  4. #4
    Membre Expert Avatar de Gado2600
    Homme Profil pro
    Développeur Office VBA
    Inscrit en
    Mai 2013
    Messages
    909
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur Office VBA

    Informations forums :
    Inscription : Mai 2013
    Messages : 909
    Par défaut
    Bonjour,

    Merci pour la réponse.

    Il ne s'agit pas vraiment d'une importation. Il s'agit ici d'exécuter une macro qui se déroule en 3 étapes :
    1. Ouvrir un fichier CSV
      Récupérer des informations via des boucles et dupliquer ces informations via des données stockées dans des tableaux précédemment initialisés
      Fermer le fichier CSV et passer au suivant


    L'étape 2 contenant des données exactement identiques sur tous les fichiers csv, cela ne changera rien sur le temps de calcul.

    Le code est le suivant (exécuter une fois par type de fichier dont j'ai besoin) :
    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
    ' Contrôle si le répertoire existe ou non
        If Dir(strFolder, vbDirectory) <> "" Then
     
            strTypeFile = ".csv"
            ' Récupération de la liste des fichiers dont j'ai besoin
            strFiles = Dir(strFolder & F_Fichiers.Cells(intLig, M00_Variables.FIC_col_Name) & "*" & strTypeFile)
     
            Do While Len(strFiles) > 0
    ' Ouverture
                 Workbooks.OpenText Filename:=strFolder & strFiles, DataType:=xlDelimited, semicolon:=True, comma:=False, local:=True
                 Set excelWkBookImp = ActiveWorkbook
    ' Partie de récupération des informations
    ' ...
    ' Fin de la récupération des informations
    ' Fermeture
                 excelWkBookImp.Close xlNo
                 Set excelWkBookImp = Nothing
                 Application.CutCopyMode = False
                strFiles = Dir()
            Loop
    Cordialement,

  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 HEU
    BONJOUR

    2min35 soit 155 secondes pour 90 fichiers soit 1,722222222222222 secondes pour chaque fichier

    je trouve que ca fonctionne plutôt bien moi pour une ouverture csv, tri , transfert sur un fichier Excel

    pour gagner quelques millièmes tu pourrais mettre en début de macro
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Application.screenupdating=false
    mais bon
    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 Expert Avatar de Gado2600
    Homme Profil pro
    Développeur Office VBA
    Inscrit en
    Mai 2013
    Messages
    909
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur Office VBA

    Informations forums :
    Inscription : Mai 2013
    Messages : 909
    Par défaut
    Bonjour,

    Promethee : je suis d'accord, utiliser des fichiers .txt est 15000 fois plus rapide que des fichiers Excel mais c'est une contrainte technique du projet...
    Quand aux expressions régulières, je ne suis pas très à l'aise dedans mais je ne pense pas que cela puisse m'aider sur la suite du processus. Pour compléter les informations, je dois disperser les informations dans une feuille Excel en fonction de la date du CSV, du magasin concerné par la donnée et de son article (un magasin pouvant avoir plusieurs articles, avant qu'on me pose la question ^^) et de son type de fichier (d'où 3 fois le même processus pour gagner un léger temps de calcul)

    Patricktoulon : 1,72 secondes pour les 90 premiers fichiers, c'est pas mal oui. Cependant, c'est une moyenne pour les 90 premiers.
    Avec le ScreenUpdating j'ai les résultats suivants :
    Ventes : 98 secondes (1,09 secondes en moyenne)
    Rebus : 172 secondes (1,91 secondes en moyenne)
    Casses : 216 secondes (2,40 secondes en moyenne)

    Je parle de moyenne car, pour moi, les premiers fichiers prennent un peu moins d'une seconde et que ce temps augmente au fur et à mesure que j'ouvre et ferme des fichiers...

    Mon objectif étant de réaliser ces importations en un minimum de temps (comme tout programme que l'on réalise), je n'aime pas vraiment avoir ce problème temporel. Si je peux rester sur un temps constant, cela serait mieux pour moi.

    Cordialement,

  7. #7
    Membre Expert
    Homme Profil pro
    Ingénieur
    Inscrit en
    Août 2010
    Messages
    730
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2010
    Messages : 730
    Par défaut
    Bonjour,

    On ne s'est pas compris.
    Je te parle de manipuler tes csv comme des fichiers texte pour les concaténer.
    Les expressions régulières, tu n'en as pas besoin, c'était juste pour illustrer qu'un traitement relativement lourd sur 500 fichiers me prenait peu de temps.

    Voici un exemple de test fait rapidement (parcourant 90 fois le même fichier csv):
    Le test 1 basé sur ta méthode prend 15s sur mon pc.

    Le test2 prend max 1s...

    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
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    Option Explicit
     
    Private Function ReadTxtFile(txtFile As String) As String
        'This function returns the whole content of a text file as one string.
        Dim fso As Object
        Dim f As Object
     
        Const ForReading As Integer = 1
     
        Set fso = CreateObject("Scripting.FileSystemObject")
     
        On Error Resume Next
        Set f = fso.OpenTextFile(txtFile, ForReading)
        On Error GoTo 0
        If f Is Nothing Then Err.Raise vbObjectError + 10001, , "File " & txtFile & " could not be found."
     
        'If empty file, an error is raised; continue
        On Error Resume Next
        ReadTxtFile = f.ReadAll
        f.Close
     
    End Function
     
     
    Private Sub WriteTxtFile(txtFile As String, txt As String, Optional overwriteWithoutWarning As Boolean = False, Optional append As Boolean = False)
        'This function enables to replace the content of a text file by the string parameter 'txt'.
        'The file is created if it does not exist.
        Const ForReading = 1, ForWriting = 2, ForAppending = 8, TristateFalse = 0
        Dim fs0, f As Object
        Dim userChoice As Integer
     
        'Ask for overwriting to user if necessary
        If Not append And Not overwriteWithoutWarning And Dir(txtFile) <> "" Then
            userChoice = MsgBox("File """ & VBA.Right(txtFile, VBA.Len(txtFile) - VBA.InStrRev(txtFile, "\")) & """ already exists in folder """ & VBA.Left(txtFile, VBA.InStrRev(txtFile, "\") - 1) & """; do you want to overwrite it?", vbYesNo)
        Else
            userChoice = vbYes
        End If
     
        If userChoice <> vbYes Then Err.Raise vbObjectError + 10001, , "User refused to overwrite file """ & txtFile & """."
     
        Set fs0 = CreateObject("Scripting.FileSystemObject")
        Set f = fs0.OpenTextFile(txtFile, IIf(append, ForAppending, ForWriting), True, TristateFalse)
        f.write txt
        f.Close
    End Sub
     
     
    Sub test1()
        Dim strTypeFile As String
        Dim strFiles As String
        Dim excelWkBookImp As Workbook
        Dim strFolder As String
        Dim i As Long
     
        i = 0
        strTypeFile = ".csv"
        strFolder = ThisWorkbook.Path & "\"
        ' Récupération de la liste des fichiers dont j'ai besoin
        strFiles = Dir(strFolder & "*" & strTypeFile)
     
        Do While Len(strFiles) > 0 And i < 90
            ' Ouverture
             Workbooks.OpenText Filename:=strFolder & strFiles, DataType:=xlDelimited, semicolon:=True, comma:=False, local:=True
             Set excelWkBookImp = ActiveWorkbook
            ' Partie de récupération des informations
            ' ...
            ' Fin de la récupération des informations
            ' Fermeture
             excelWkBookImp.Close xlNo
             Set excelWkBookImp = Nothing
             Application.CutCopyMode = False
     
            i = i + 1 'strFiles = Dir()
        Loop
    End Sub
     
    Sub test2()
        Dim strTypeFile As String
        Dim strFiles As String
        Dim excelWkBookImp As Workbook
        Dim strFolder As String
        Dim i As Long
     
        Dim concatStr As String
        Dim newtxt As String
     
        i = 0
        strTypeFile = ".csv"
        strFolder = ThisWorkbook.Path & "\"
        ' Récupération de la liste des fichiers dont j'ai besoin
        strFiles = Dir(strFolder & "*" & strTypeFile)
     
        Do While Len(strFiles) > 0 And i < 90
            ' Ouverture
            newtxt = ReadTxtFile(strFolder & strFiles)
            Debug.Print "@" & newtxt
            newtxt = VBA.Mid(newtxt, VBA.InStr(newtxt, vbCrLf) + 2)
            Debug.Print "|" & newtxt
            concatStr = concatStr & newtxt
     
            i = i + 1 'strFiles = Dir()
        Loop
     
        Debug.Print concatStr
        'concatStr = VBA.Replace(concatStr, vbCrLf & vbCrLf, vbCrLf)
        'Debug.Print concatStr
     
        WriteTxtFile strFolder & "toto.csv", concatStr, True
     
         Workbooks.OpenText Filename:=strFolder & "toto.csv", DataType:=xlDelimited, semicolon:=True, comma:=False, local:=True
         Set excelWkBookImp = ActiveWorkbook
        ' Partie de récupération des informations
        ' ...
        ' Fin de la récupération des informations
        ' Fermeture
         excelWkBookImp.Close xlNo
         Set excelWkBookImp = Nothing
         Application.CutCopyMode = False
     
        'Supprimer fichier toto.csv
     
    End Sub
    NB: Il ne faudra pas oublier de conserver un jeu d'entêtes (je me suis pas embêté à le faire).

  8. #8
    Membre Expert Avatar de Gado2600
    Homme Profil pro
    Développeur Office VBA
    Inscrit en
    Mai 2013
    Messages
    909
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur Office VBA

    Informations forums :
    Inscription : Mai 2013
    Messages : 909
    Par défaut
    Merci pour les bouts de code.
    J'ai lu rapidement ce que tu as mis. Je vais tester cela dans la journée et vous dirais ce qu'il en est.

    Cordialement,

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [XL-2010] Diminuer le temps d’exécution d'une macro
    Par idate dans le forum Macros et VBA Excel
    Réponses: 19
    Dernier message: 22/04/2014, 09h18
  2. [XL-2007] Oter une protection sur feuille le temps d'une macro
    Par jose_67 dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 11/02/2010, 20h13
  3. Temps d'éxécution d'une macro
    Par PiliSql dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 04/05/2008, 21h58
  4. diminuer le temps d'accées à une liste
    Par ouinih dans le forum C++
    Réponses: 4
    Dernier message: 16/06/2007, 13h47
  5. Allongement d'uin temps d'exécution d'une macro
    Par avanrill dans le forum Access
    Réponses: 2
    Dernier message: 06/03/2006, 19h29

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