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 :

code très lent


Sujet :

Macros et VBA Excel

  1. #1
    Candidat au Club
    Femme Profil pro
    Ingénieur chercheur
    Inscrit en
    Avril 2016
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Avril 2016
    Messages : 3
    Points : 2
    Points
    2
    Par défaut code très lent
    Bonjour,

    Je suis nouvelle sur ce forum, et j'ai un pb équivalent à celui de cette discussion.

    Voici le contexte :
    J'ai un code vba dans une base access, qui compare des data d'un fichier excel et de la database, les tries et export le tout dans un fichier excel puis pdf.
    J'ai fait plusieurs macros liées les unes aux autres et l'un d'entre elle dure plus d'1 min et un autre 9 min !! Je cherche à optimiser le code afin de réduire ce temps de process.
    Pourriez-vous m'aider ?
    Ci-dessous quelques infos. Merci d'avance pour votre aide.
    Diane

    Le bout de code ci-dessous est pour la macro d'1 min: cette macro consiste à chercher les valeurs dans une plage de données de tous les onglets d'un fichier excel (jusqu'à 9 onglets - 2430 valeurs) et les coller dans une colonne dans un autre fichier ("strFilename").

    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
        For Each Freezer In ActiveWorkbook.Worksheets
            Set Plage = Freezer.Range("C5:L63")
            'Boucle
            For Each Cell In Plage
                If Cell.Value <> Empty Then
                    If Cell.Value <> "Rack ID" Then
                        'Copie les valeurs du freezer interface
                        Workbooks(strFilename).Worksheets(1).Range("B" & LinB).Value = Cell.Value
                        'copie les couleurs
                        Workbooks(strFilename).Worksheets(1).Range("B" & LinB).Interior.Color = Cell.Interior.Color
                        'copie le nom du freezer
                        Workbooks(strFilename).Worksheets(1).Range("A" & LinB).Value = Freezer.Name
     
                        LinB = LinB + 1
                    Else
                    End If
                End If
            Next
        Next
        End With
    Le second bout de code ci-dessous (9 min) consiste à comparer et supprimer parmi les 2430 valeurs collées précédemment à celles initialement dans le fichier strFilename (64 valeurs max).

    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
    derlig = Workbooks(strFilename).Worksheets(1).Range("B" & Rows.Count).End(xlUp).Row
     
        For i = 2 To derlig
            FindString = Workbooks(strFilename).Worksheets(1).Range("B" & i).Value
            If Trim(FindString) <> "" Then
                With Sheets(1).Range("E2:E65")
                    Set Rng = .Find(What:=FindString, _
                                After:=.Cells(.Cells.Count), _
                                LookIn:=xlValues, _
                                LookAt:=xlWhole, _
                                SearchOrder:=xlByRows, _
                                SearchDirection:=xlNext, _
                                MatchCase:=False)
                    If Rng Is Nothing Then
                        Sheets(1).Range("A" & i).Delete Shift:=xlUp
                        Sheets(1).Range("B" & i).Delete Shift:=xlUp
     
                        i = i - 1
                    Else
                        Sheets(1).Range("C" & Rng.Row).Copy
                        Sheets(1).Range("F" & i).PasteSpecial xlPasteAll
                        Sheets(1).Range("D" & Rng.Row).Copy
                        Sheets(1).Range("G" & i).PasteSpecial xlPasteAll
     
                    End If
                End With
            End If
        Next

  2. #2
    Membre du Club
    Homme Profil pro
    Bénévole super actif pour association sportive
    Inscrit en
    Février 2015
    Messages
    64
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Bénévole super actif pour association sportive

    Informations forums :
    Inscription : Février 2015
    Messages : 64
    Points : 66
    Points
    66
    Par défaut
    Bonjour et bienvenu sur le forum.

    Pour la première macro (1min) je te conseille d'utiliser une image de la feuille dans laquelle tu viens scanner les valeurs qui sera de type Variant.
    Tu peux aller voir ici : http://silkyroad.developpez.com/vba/tableaux/ c'est bien expliqué, cf un de mes posts qui m'a fait découvrir ce super pouvoir http://www.developpez.net/forums/d14...-l-espace-fin/.
    En gros, au lieu de travailler sur chaque cellule, on ne travaille que sur une image allégée et qui en RAM dans l'ordi (accès plus rapide).

    Pour la deuxième macro, si tu connais les valeurs cherchées que tu veux supprimer, pourquoi ne pas faire un filtre automatique dans la colonne que tu scannes en sélectionnant toutes les valeurs visées.
    Une fois le tri effectué tu supprimes les N lignes concernées et le tour est joué.

    J'espère avoir compris ce que tu cherchais à faire et que cela puisse t'aider.

  3. #3
    Candidat au Club
    Femme Profil pro
    Ingénieur chercheur
    Inscrit en
    Avril 2016
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Avril 2016
    Messages : 3
    Points : 2
    Points
    2
    Par défaut Réponse à Poussemousse
    Merci Poussemousse pour ta réponse et le tuto. Parmi les exemples proposés, je ne sais pas exactement sur lequel m'appuyer
    Pour la 1ère macro, j'ai donc intégré le tableau de la façon suivante. Cependant j'ai encore quelques questions (voir ci-dessous ">>>>>").
    Sans erreur, le temps de process est encore de 43 sec...

    Pour la 2ème macro, malheureusement je ne connais pas les valeurs, elles changent systématiquement. Je vais essayer avec un tableau également.
    Merci d'avance pour toute aide complémentaire.

    Diane

    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
    Dim compt1 As Long, compt2 As Long
    Dim PlageV As Variant
     
        For Each Freezer In ActiveWorkbook.Worksheets '>>>>>>>> puis-je faire des worksheet un tableau également ??
            PlageV = Freezer.Range("C5:L63").Value
            PlageC = Freezer.Range("C5:L63").Interior.Color  '>>>>>> est-ce possible de travailler avec les couleurs des cellules?
     
            'Boucle
            For compt1 = LBound(PlageV, 1) To UBound(PlageV, 1)
            For compt2 = LBound(PlageV, 2) To UBound(PlageV, 2)
                If PlageV(compt1, compt2) <> Empty Then
                        If PlageV(compt1, compt2) <> "Rack ID" Then
                            'Copie les valeurs du freezer interface
                            Workbooks(strFilename).Worksheets(1).Range("B" & LinB).Value = PlageV(compt1, compt2)
                            'copie les couleurs
                            Workbooks(strFilename).Worksheets(1).Range("B" & LinB).Interior.Color = PlageC(compt1, compt2)  '>>>>>>> ici j'ai une erreur (pas étonnant), dois-je faire un 2ème ensemble de "For compt1, compt2 Next" ?
                            'copie le nom du freezer
                            Workbooks(strFilename).Worksheets(1).Range("A" & LinB).Value = Freezer.Name
     
                            LinB = LinB + 1
                        Else
                        End If
                End If
            Next compt2
            Next compt1
        Next
     
        End With

  4. #4
    Inactif  

    Homme Profil pro
    cuisiniste
    Inscrit en
    Avril 2009
    Messages
    15 379
    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 379
    Points : 12 075
    Points
    12 075
    Billets dans le blog
    8
    Par défaut re
    Bonsoir
    avant je pense que l'on est en presence d'un soucis de conception

    dis moi quelle est la valeur de LinB au 1 er tour hein!!!!
    Pour moi il vaut 0 ce qui par conséquence doit générer une erreur

    ensuite tu boucle sur "for each....." dans une plage de plusieurs colonnes (Freezer.Range("C5:L63")) donc 10 colonnes

    donc imaginons que sur la même ligne j'ai 10 valeurs différentes et pas une seule cellules vides et bien avec tes 3 lignes tu change 10 fois la cellules B et A
    c'est peut être un peu pour cela que c'est long


    bref toute une conception a revoir

    je ne regarde pas le 2 eme code ayant déjà ici matière a réflexion n'est ce pas ????
    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
    
    For Each Freezer In ActiveWorkbook.Worksheets
            Set Plage = Freezer.Range("C5:L63")
            'Boucle
            For Each Cell In Plage
                If Cell.Value <> Empty Then
                    If Cell.Value <> "Rack ID" Then
                        'Copie les valeurs du freezer interface
                        Workbooks(strFilename).Worksheets(1).Range("B" & LinB).Value = Cell.Value 'génère certainement une erreur au 1 er tour 
                        'copie les couleurs
                        Workbooks(strFilename).Worksheets(1).Range("B" & LinB).Interior.Color = Cell.Interior.Color' ici forcement pareil 
                        'copie le nom du freezer
                        Workbooks(strFilename).Worksheets(1).Range("A" & LinB).Value = Freezer.Name' idem 
     
                        LinB = LinB + 1
                    Else
                    End If
                End If
            Next
        Next
        End With
    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

  5. #5
    Inactif  

    Homme Profil pro
    cuisiniste
    Inscrit en
    Avril 2009
    Messages
    15 379
    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 379
    Points : 12 075
    Points
    12 075
    Billets dans le blog
    8
    Par défaut re
    je te propose ceci:

    afin que tu puisse analyser dans la fenêtre d'exécution (debug) les adresses de cellules concernées par tes critères
    je pense que ce chemin et mieux adapté a ton souhait

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    For Each Freezer In ActiveWorkbook.Worksheets
             With  Freezer .Range("$C$6:Ll$63")    ' plage a adapter
              .AutoFilter Field:=1, Criteria1:="<>", Criteria2:="<>Rack ID"  'on recherche les valeurs différentes de vide et de "rack id"
               'pour connaitre l'adress des cellules concernées par le filtre 
            debug .print .Parent.AutoFilter.Range.SpecialCells(xlCellTypeVisible)..Address
           .AutoFilter ' stop le filtre
        End With
    next
    Bonne méditation
    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
    Candidat au Club
    Femme Profil pro
    Ingénieur chercheur
    Inscrit en
    Avril 2016
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Avril 2016
    Messages : 3
    Points : 2
    Points
    2
    Par défaut Re
    Bonjour Patrick
    La macro initiale fonctionne sans erreur, mais est juste super lente.
    Les feuilles "freezer" sont verrouillées, pas possible d'appliquer un filtre. Et je ne veux pas les déverrouiller, il y a trop d'utilisateurs.
    Ce que je pense faire : coller l'ensemble des valeurs du range sélection dans une seule colonne et appliquer les filtres (cellule vide et "rack id") ensuite. Il faudrait lire les données du tableau (range sélectionné) de gauche à droite puis de bas en bas. En gros transformer un tableau a 2 dimensions en un tableau a 1 dimension ? Pouvez-vous m'aiguiller?
    Merci

  7. #7
    Inactif  

    Homme Profil pro
    cuisiniste
    Inscrit en
    Avril 2009
    Messages
    15 379
    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 379
    Points : 12 075
    Points
    12 075
    Billets dans le blog
    8
    Par défaut re
    heu......
    Ce que je pense faire : coller l'ensemble des valeurs du range sélection dans une seule colonne et appliquer les filtres (cellule vide et "rack id") ensuite. Il faudrait lire les données du tableau (range sélectionné) de gauche à droite puis de bas en bas. En gros transformer un tableau a 2 dimensions en un tableau a 1 dimension ? Pouvez-vous m'aiguiller?
    si tes cellules sont verrouillée et que tu ne peut pas faire de filtre c'est walouh ca aussi

    peut être déverrouiller les cellules si l'utilisateur voir le nom du PC correspond au tiens ca c'est possible

    exemple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if Envron("UserName") = "Diane " and  Environ("COMPUTERNAME")="diane-PC" then........
    si c'est ton pc qui lance c'est bon sinon walouh......
    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

Discussions similaires

  1. [XL-2007] Code très lent
    Par apdf1 dans le forum Macros et VBA Excel
    Réponses: 1
    Dernier message: 13/11/2011, 18h36
  2. DataTable personnalisé > éxécution du code très lent
    Par Stephane_br dans le forum VB.NET
    Réponses: 5
    Dernier message: 08/07/2011, 16h57
  3. [D2007] Achèvement de code très lent
    Par paradise dans le forum EDI
    Réponses: 8
    Dernier message: 07/10/2010, 13h06
  4. [E-00] Code Très Lent
    Par Scoubi7 dans le forum Macros et VBA Excel
    Réponses: 33
    Dernier message: 10/06/2009, 20h21
  5. Code VBA très lent - en phase d'execution
    Par Fairyanna dans le forum Macros et VBA Excel
    Réponses: 5
    Dernier message: 02/08/2008, 15h35

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