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 :

Macro très lente, comment l'optimiser ?


Sujet :

Macros et VBA Excel

  1. #1
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2020
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2020
    Messages : 4
    Points : 2
    Points
    2
    Par défaut Macro très lente, comment l'optimiser ?
    Bonjour,
    J'ai développé une macro qui sert à copier-coller les données d'un tableau vers un autre.
    Les deux tableaux étant différents en taille et ne comportant pas toujours les mêmes références, j'ai donc fait en sorte qu'il s'y prenne ligne par ligne.
    Il m'a pris 12h pour tourner, donc j'imagine qu'il reste largement optimisable bien que j'aie du mal à voir comment.
    Auriez-vous une idée ?

    Merci !

    Code VBA : 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
    Sub integration()
    Worksheets("Feuil1").Activate
    Worksheets("Feuil3").Activate
     
    Dim i As Long
    Dim j As Long
     
    Application.ScreenUpdating = False
     
    For i = 2 To 49000  'tous les produits avec l'historique
        For j = 5 To 10000      'tous les produits du fichier de prevs
        Sheets("Feuil3").Select
            If (Range("A" & i).Value <> Range("A" & (i + 6)).Value) Then        'on regarde quand on change de produit pour avoir des cases vides
                If Worksheets("Feuil3").Range("A" & i).Value = Worksheets("Feuil1").Range("A" & j).Value Then   'on récupère la bonne référence dans l'autre produit
                    Range("R" & (i + 5), "R" & (i + 10)).Select     'on copie-colle
                    Selection.Copy
                    Sheets("Feuil1").Select
                    Range("AO" & j, "AO" & j + 6).Select
                    Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
                    :=False, Transpose:=False
                    Application.CutCopyMode = False
                    i = i + 6   'on passe au prochain article
                End If
            End If
        Next
    Next
     
    Application.ScreenUpdating = True
     
    End Sub

  2. #2
    Expert confirmé Avatar de BENNASR
    Homme Profil pro
    Responsable comptable & financier
    Inscrit en
    Décembre 2013
    Messages
    2 948
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Tunisie

    Informations professionnelles :
    Activité : Responsable comptable & financier
    Secteur : Finance

    Informations forums :
    Inscription : Décembre 2013
    Messages : 2 948
    Points : 5 174
    Points
    5 174
    Par défaut
    Bonjour
    Au départ je suis autodidacte donc méfiez de mes propositions
    1-j'ai vu sur ce forum il est vivement recommandé d'éviter .select
    au départ définir vos deux onglets avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Dim F1 As Worksheet
    Dim f2 As Worksheet
     
    Set F1 = Sheets("feuil1")
    Set f2 = Sheets("feuil3")
    ,
    ,
    ,
    If f2.Range("A" & i).Value = f1.Range("A" & j).Value Then
    ,
    donc au lieu de faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Range("R" & (i + 5), "R" & (i + 10)).Select     'on copie-colle
                    Selection.Copy
    faire directement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    f1.Range("R" & (i + 5), "R" & (i + 10)).Copy    'on copie-colle
    2- je ne comprends pas ces deux variables qui sont fixées à 49000 et 10000, s'il s'agit d'une dernière ligne non vide d'une colonne il y a lieu de le déterminer avec formule

    Pour copier d'un onglet à l'autre il est recommandé d'utiliser les filtres qui consomme moins de temps

    Vous pouvez afficher un capture écran des données de départ et expliquer d'avantage ce que tu veux faire pour si je peux t'aider car j'ai pas arriver à comprendre la demande
    Bonne Continuation

  3. #3
    Expert éminent sénior Avatar de Menhir
    Homme Profil pro
    Ingénieur
    Inscrit en
    Juin 2007
    Messages
    16 037
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Finistère (Bretagne)

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 16 037
    Points : 32 866
    Points
    32 866
    Par défaut
    Supprime les Select/Activate/Selection.

    Code VBA : 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 integration()
    Dim i As Long, j As Long
    Dim WSSource As Worksheet, WSDest As Worksheet
     
    Set WSDest = Worksheets("Feuil1")
    Set WSSource = Worksheets("Feuil3")
     
    Application.ScreenUpdating = False
     
    For i = 2 To 49000  'tous les produits avec l'historique
        For j = 5 To 10000      'tous les produits du fichier de prevs
            If WSSource.Cells(i, "A".Value <> WSSource.Cells(i + 6, "A").Value Then        'on regarde quand on change de produit pour avoir des cases vides
                If WSSource.Cells(i, "A").Value = WSDest.Cells(j, "A".Value Then   'on récupère la bonne référence dans l'autre produit
                    WSSource.Range("R" & (i + 5), "R" & (i + 10)).Copy
                    WSDest.Range("AO" & j, "AO" & j + 6).PasteSpecial Paste:=xlPasteValues
                    i = i + 6   'on passe au prochain article
                End If
            End If
        Next
    Next
     
    Application.ScreenUpdating = True
     
    End Sub

    Le i = i + 6 me semble étrange à l'intérieur d'un For i =, mais je l'ai laissé, ne connaissant pas la structure de tes données.

    Cela dit, tes boucles font quand même un demi milliard de tours.
    Donc soit il est possible de corrigé algorithme lui-même, soit ça va forcément prendre un certain temps.

  4. #4
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2020
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2020
    Messages : 4
    Points : 2
    Points
    2
    Par défaut
    Merci pour vos réponses !

    Les variables fixées à 49000 et 10000 correspondent à la fin des colonnes en question.
    Niveau des filtres, ce serait copier si codeArticle de la feuil3 = codeArticle de la feuil1 ?
    i = i + 6 correspond à un saut pour sauter les 6 valeurs suivantes en cas de réussite (elles correspondent à des lignes vides dans le tableau de la feuil3).

    En gros feuil3 correspond à l'historique des ventes et feuil1 est le fichier de prévision des ventes. Les deux fichiers étant formatés différemment et contenant parfois certaines références arrêtées, je ne vois que cette solution pour un résultat fiable pour le moment.
    Pour expliquer plus en détail j'ai des valeurs calculées dans la feuil3 par rapport à l'historique de chaque produit (des prévisions de vente). Je les colles dans la feuil1, là où elles correspondent au même produit.

  5. #5
    Expert éminent sénior
    Avatar de Mat.M
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    8 393
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2006
    Messages : 8 393
    Points : 20 496
    Points
    20 496
    Par défaut
    Citation Envoyé par Gourlae Voir le message
    Il m'a pris 12h pour tourner, donc j'imagine qu'il reste largement optimisable bien que j'aie du mal à voir comment.
    forcément si on fait une boucle de 49000 x 10000 itérations je vous laisse faire le calcul c'est certain que ça va pédaler !
    Chercher dans le MSDN s'il est possible par code de faire un copier-coller d'un objet Sheet vers un autre je suis sûr que ça doit exister
    Surtout que si vous faire Sheets("Feuil3").Select , le tableur doit tout mettre en mémoire le contenu des cellules

  6. #6
    Expert éminent sénior Avatar de Menhir
    Homme Profil pro
    Ingénieur
    Inscrit en
    Juin 2007
    Messages
    16 037
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Finistère (Bretagne)

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 16 037
    Points : 32 866
    Points
    32 866
    Par défaut
    Citation Envoyé par Gourlae Voir le message
    i = i + 6 correspond à un saut pour sauter les 6 valeurs suivantes en cas de réussite (elles correspondent à des lignes vides dans le tableau de la feuil3).
    Dans ce cas, pourquoi ne pas avoir simplement mis un Step au For To ?

  7. #7
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2020
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2020
    Messages : 4
    Points : 2
    Points
    2
    Par défaut
    Citation Envoyé par Menhir Voir le message
    Dans ce cas, pourquoi ne pas avoir simplement mis un Step au For To ?
    Je souhaite que cette étape ne se fasse que si les if sont vérifiés, et pas seulement quand le for tourne (peut-être que cela revient au même).

  8. #8
    Expert éminent sénior Avatar de Menhir
    Homme Profil pro
    Ingénieur
    Inscrit en
    Juin 2007
    Messages
    16 037
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Finistère (Bretagne)

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 16 037
    Points : 32 866
    Points
    32 866
    Par défaut
    Ca veut dire que si le If n'est pas déclenché, les lignes vides aussi seront scrutées ?
    Il y a sans doute là un gain de temps à obtenir : diviser par 6 le nombre de boucles.

  9. #9
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2020
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2020
    Messages : 4
    Points : 2
    Points
    2
    Par défaut
    Citation Envoyé par Menhir Voir le message
    Ca veut dire que si le If n'est pas déclenché, les lignes vides aussi seront scrutées ?
    Il y a sans doute là un gain de temps à obtenir : diviser par 6 le nombre de boucles.
    C'est vrai, mais comme le fichier d'historique comporte des écarts entre différents produits (parfois 12 mois d'historique, parfois 36, parfois 15), sauter de 6 en 6 reviendrait à prendre le risque de "sauter" un produit.

Discussions similaires

  1. [XL-2003] Macro VBA très lente, comment l'optimiser
    Par nuphius dans le forum Macros et VBA Excel
    Réponses: 8
    Dernier message: 17/06/2015, 21h45
  2. Sélection d'une plage de dates par macro très lente
    Par yvesduc dans le forum QlikView
    Réponses: 1
    Dernier message: 11/03/2010, 15h48
  3. Requête trop lente, comment l'optimiser?
    Par getz85 dans le forum Langage SQL
    Réponses: 19
    Dernier message: 29/01/2008, 13h40
  4. Treeview liste d'images + champ image : très lent, comment faire ?
    Par Cazaux-Moutou-Philippe dans le forum WinDev
    Réponses: 3
    Dernier message: 01/11/2006, 17h59
  5. Très lent comment optimiser svp ?
    Par dev7 dans le forum PostgreSQL
    Réponses: 1
    Dernier message: 02/06/2006, 12h16

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