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 :

Optimisation d'une macro


Sujet :

Macros et VBA Excel

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Prestataire
    Inscrit en
    Février 2016
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre (Centre)

    Informations professionnelles :
    Activité : Prestataire
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Février 2016
    Messages : 5
    Par défaut Optimisation d'une macro
    Bonjour a tous

    Je viens de créer une macro par "tâtonnement" qui me permet pour chaque ligne d'un tableau de saisie de commande (commande CETA) d'extraire uniquement les produits présents. Ainsi j'obtiens un "bon de livraison" en aperçu avant impression pour chaque client avec les seuls produits commandé.
    Cependant cette macro est très lente et malgré les discussions sur le sujet dans ce forum je n'arrive pas à l’accélérer. J'ai bien essayé d'enlever les "select" mais les "SpecialCells(xlCellTypeVisible)" me pose problème.

    Voici la macro:

    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
    Sub essai()
    Application.ScreenUpdating = False
     
     
    For i = 3 To Sheets("Commande CETA").[A65000].End(xlUp).Row
    Range("compteur") = i - 2
     
    Sheets("Feuil2").Range("C6:D150").ClearContents
     
    Sheets("Commande CETA").Select
    ActiveSheet.Calculate
    If Cells(i, "B") <> 0 Then
    Range("C" & i, "DP" & i).SpecialCells(xlCellTypeVisible).Select
    Selection.Copy
    Worksheets("Feuil2").Select
    Range("D6").PasteSpecial Paste:=xlValues, Operation:=xlNone, SkipBlanks:= _
            False, Transpose:=True
    Sheets("Commande CETA").Select
    Range("Produit").SpecialCells(xlCellTypeVisible).Select
    Selection.Copy
    Worksheets("Feuil2").Select
    Range("C6").PasteSpecial Paste:=xlValues, Operation:=xlNone, SkipBlanks:= _
            False, Transpose:=True
     
    Range("C5").AutoFilter Field:=2, Criteria1:="<>"
     
     
    Sheets("Feuil2").PrintPreview
    End If
    Next
    Application.ScreenUpdating = True
     
    End Sub
    Je joins également le fichier (le bouton noir de la feuill2 lance la macro)Doc tranport2.xlsm

    Pourriez vous m'indiquer la démarche a suivre.

    Merci

  2. #2
    Membre confirmé
    Homme Profil pro
    Gestion comptable - Spécialiste Excel, Vba, - Débutant MySql, Javascript, Python, Php
    Inscrit en
    Mars 2010
    Messages
    48
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Gestion comptable - Spécialiste Excel, Vba, - Débutant MySql, Javascript, Python, Php

    Informations forums :
    Inscription : Mars 2010
    Messages : 48
    Par défaut améliorations 1
    Il y a en effet quelques améliorations possibles


    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
    Sub essai()
     
    'Application.ScreenUpdating = False
     
    with application
    .screenupdating= false
    .displayalerts=false
    .calculation=xlmanual 'commente si tu as besoin des calculs en temps réel
    end with
     
    dim feuil_CETA as worksheet
    dim feuil_2 as worksheet
    dim r as range
    dim der_lig as long
     
    with thisworkbook
    set feuil_CETA = .worksheets("Commande CETA")
    set feuil_2 = .worksheets("Feuil2")
    end with
     
    with feuil_CETA
     
    der_lig = .cells(.rows.count, 1).end(xlup).row
     
    For i = 3 To der_lig
    .Range("compteur") = i - 2 'feuille CETA?
     
    'feuil_2.activate en cas de bug
    feuil_2.Range("C6150").ClearContents
     
    .activate 'feuil commande CETA, évite Select qui est couteux
    .calculate 'très couteux si la feuille a beaucoup de formules, c'est mieux de lancer calculate en fin de script
     
    If .Cells(i, "B") <> 0 Then
     
    set r = .range("C" &i, "DP" &i)
    with r.SpecialCells(xlCellTypeVisible)
    .copy feuil_2.range("D6")
    .copy feuil_2.range("C6")
    end with
     
    .Range("C5").AutoFilter Field:=2, Criteria1:="<>"
     
    feuil_2.activate 'en cas de bug
    feuil_2.PrintPreview 'JE NE SUIS PAS SURE DE COMPRENDRE CETTE INSTRUCTION (elle prévisualise la feuille à l'intérieur de la boucle???) Ne faudrait-il pas la sortir de la boucle FOR?
    End If
    Next i
    end with 'feuil_CETA
     
    'Application.ScreenUpdating = True
     
    with application
    .screenupdating= true
    .displayalerts=true
    .calculation=xlautomatic 'commente si tu as besoin des calculs en temps réel
    end with
     
    End Sub

    Pascal

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Prestataire
    Inscrit en
    Février 2016
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre (Centre)

    Informations professionnelles :
    Activité : Prestataire
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Février 2016
    Messages : 5
    Par défaut
    Merci pour cette réponse.

    En fait le but de la macro est au final d'imprimer les "bon de transport" un par un mais pour l'instant j'ai mis l'instruction feuil_2.PrintPreview pour ne pas imprimer à chaque test. Je remplacerai une fois la macro terminée par Printout.

    Cependant je viens de tester le code modifié et la boucle ne se fait pas. J'ai toujours le même numéro de client avec aucun produit d'afficher.
    Par ailleurs dans ce code je ne vois pas comment la transposition d'horizontale en verticale a lieue?

    PS :dans mon code un smiley s'était glissé, il faillait lire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Sheets("Feuil2").Range("C6:D150").ClearContents
    Merci

  4. #4
    Modérateur
    Avatar de AlainTech
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Mai 2005
    Messages
    4 235
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 71
    Localisation : Belgique

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : Finance

    Informations forums :
    Inscription : Mai 2005
    Messages : 4 235
    Par défaut
    Citation Envoyé par syl150 Voir le message
    PS :dans mon code un smiley s'était glissé, il faillait lire Sheets("Feuil2").Range("C6150").ClearContents
    Bonjour,

    Quand on utilise les balises [code], on n'a pas ce souci.
    N'oubliez pas de cliquer sur quand vous avez obtenu ou trouvé vous-même la réponse à votre question.
    Si vous trouvez seul, pensez à poster votre solution. Elle peut servir à d'autres!
    Pensez aussi à voter pour les réponses qui vous ont aidés.
    ------------
    Je dois beaucoup de mes connaissances à mes erreurs!

  5. #5
    Membre confirmé
    Homme Profil pro
    Gestion comptable - Spécialiste Excel, Vba, - Débutant MySql, Javascript, Python, Php
    Inscrit en
    Mars 2010
    Messages
    48
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Gestion comptable - Spécialiste Excel, Vba, - Débutant MySql, Javascript, Python, Php

    Informations forums :
    Inscription : Mars 2010
    Messages : 48
    Par défaut
    oops, je n'ai pas vu l'argument .transpose de la méthode pastespecial.

    Dans ce cas, il faut modifier le script que j'ai posté à la ligne 36

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    set r = .range("C" &i, "DP" &i)
    with r.SpecialCells(xlCellTypeVisible)
    .copy feuil_2.range("D6")
    .copy feuil_2.range("C6")
    end with
    Les méthodes copy vont se faire sur 2 lignes, je ne sais pas si ça fonctionne sur une ligne, mais de mémoire ça doit ressembler à quelque chose comme ça

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    set r = .range("C" &i, "DP" &i)
    with r.SpecialCells(xlCellTypeVisible)
    .select
    .selection.copy
    feuil_2.range("D6").Select
    selection.PasteSpecial Paste:=xlValues, Operation:=xlNone, SkipBlanks:= _
            False, Transpose:=True
     
    feuil_2.range("C6").Select
    selection.PasteSpecial Paste:=xlValues, Operation:=xlNone, SkipBlanks:= _
            False, Transpose:=True
    end with
    C'est un script comme ça sans tester sous excel. Il y a très certainement des ajustements.

  6. #6
    Futur Membre du Club
    Homme Profil pro
    Prestataire
    Inscrit en
    Février 2016
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre (Centre)

    Informations professionnelles :
    Activité : Prestataire
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Février 2016
    Messages : 5
    Par défaut
    Merci pour vos réponses, j'essaye de me débrouiller avec ça et je vous retiens au courant.

  7. #7
    Futur Membre du Club
    Homme Profil pro
    Prestataire
    Inscrit en
    Février 2016
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre (Centre)

    Informations professionnelles :
    Activité : Prestataire
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Février 2016
    Messages : 5
    Par défaut
    Bonjour

    Merci pour votre aide, j'ai réussi à obtenir une macro fonctionnelle.

    J'ai encore une petite question d'optimisation. Est-il possible d'accélérer la macro suivante dans laquelle il y a la fonction Vlookup et la fonction Concatener.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    For ii = 10 To derlig3
    With feuil_doc
        .Range("C" & ii).Value = (WorksheetFunction.VLookup(.Range("A" & ii).Value, Sheets("Produits").Range("Produits"), 3, False)) * Range("B" & ii)
        .Range("D" & ii).Value = (WorksheetFunction.VLookup(.Range("A" & ii).Value, Sheets("Produits").Range("Produits"), 11, False)) * Range("C" & ii)
        .Range("E" & ii).Value = (WorksheetFunction.VLookup(.Range("A" & ii).Value, Sheets("Produits").Range("Produits"), 2, False)) & " x " & (Range("B" & ii) / (WorksheetFunction.VLookup(.Range("A" & ii).Value, Sheets("Produits").Range("Produits"), 2, False)))
        .Range("F" & ii).Value = (WorksheetFunction.VLookup(.Range("A" & ii).Value, Sheets("Produits").Range("Produits"), 12, False)) & " - " & (WorksheetFunction.VLookup(.Range("A" & ii).Value, Sheets("Produits").Range("Produits"), 5, False)) & " - " & (WorksheetFunction.VLookup(.Range("A" & ii).Value, Sheets("Produits").Range("Produits"), 6, False)) & " - " & (WorksheetFunction.VLookup(.Range("A" & ii).Value, Sheets("Produits").Range("Produits"), 7, False))
    End With
    Merci

  8. #8
    Membre confirmé
    Homme Profil pro
    Gestion comptable - Spécialiste Excel, Vba, - Débutant MySql, Javascript, Python, Php
    Inscrit en
    Mars 2010
    Messages
    48
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Gestion comptable - Spécialiste Excel, Vba, - Débutant MySql, Javascript, Python, Php

    Informations forums :
    Inscription : Mars 2010
    Messages : 48
    Par défaut
    Bonjour,

    Tu peux référencer la plage de données "Produits" au début du script avec:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    dim rg_Produits as range
    set rg_Produits = thisworkbook.worksheets("Produits").range("Produits")
    et de mettre la plage dans le script que tu veux optimiser

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    With feuil_doc
        .Range("C" & ii).Value = (WorksheetFunction.VLookup(.Range("A" & ii).Value, rg_Produits, 3, False)) * Range("B" & ii)
        .Range("D" & ii).Value = (WorksheetFunction.VLookup(.Range("A" & ii).Value, rg_Produits, 11, False)) * Range("C" & ii)
        .Range("E" & ii).Value = (WorksheetFunction.VLookup(.Range("A" & ii).Value, rg_Produits, 2, False)) & " x " & (Range("B" & ii) / (WorksheetFunction.VLookup(.Range("A" & ii).Value, rg_Produits, 2, False)))
        .Range("F" & ii).Value = (WorksheetFunction.VLookup(.Range("A" & ii).Value, rg_Produits, 12, False)) & " - " & (WorksheetFunction.VLookup(.Range("A" & ii).Value, rg_Produits, 5, False)) & " - " & (WorksheetFunction.VLookup(.Range("A" & ii).Value, rg_Produits, 6, False)) & " - " & (WorksheetFunction.VLookup(.Range("A" & ii).Value, rg_Produits, 7, False))
    End With
    et en fin de code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    set rg_Produits = nothing
    mais ce n'est pas indispensable

    Autre optimisation (accessoire):

    Le feuil_doc.Range("C" & ii).Value ainsi que tous les autres peuvent être remplacés par une référence unique sur une plage de données, ex.:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    set rg_fdoc = feuil_doc.range("A1")
    et ensuite dans le script ci-dessus, tu appliques la méthode offset, pour la première ligne dans la boucle, ça donnerait:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    rg_fdoc.offset(ii,3) = (WorksheetFunction.VLookup(.rg_fdoc.offset(ii,) , rg_Produits, 3, False)) * rg_fdoc.offset(ii,1)
    C'est ce que je peux voir comme principales optimisations, il doit y en avoir d'autres s'ils suscitent la curiosité des experts qui te lisent.

    Cordialement

    Pascal

  9. #9
    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
    bonsoir tous les 2
    ôtez moi le doute

    r a bien 2 cellules et non pas la ligne entière de C a DP

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    set r = .range("C" & i ,"DP" & i)'comme ca la plage r contiens que 2 cellules 
    with r.SpecialCells(xlCellTypeVisible)
    .copy feuil_2.range("D6")
    .copy feuil_2.range("C6")
    end with

    SI C EST PAS LE CAS VOUS AVEZ TOUT FAUX
    SE SERAIT PLUTOT
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    set r = .range("C" & i  ":DP" & i)' comme ca r contiens toutes les cellules de C à DP
    
    ce qui justifierait le xltype visible dans la sélection
    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

  10. #10
    Futur Membre du Club
    Homme Profil pro
    Prestataire
    Inscrit en
    Février 2016
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre (Centre)

    Informations professionnelles :
    Activité : Prestataire
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Février 2016
    Messages : 5
    Par défaut
    r a bien la ligne entière.
    La copie a bien lieue de C à DP avec l'expression ("C" & i ,"DP" & i) alors que ("C" & i ":DP" & i) m'indique "erreur de syntaxe".

    Merci

  11. #11
    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
    autant pour moi
    la syntaxe c'est ("C" & i & ":DP" & i).
    mais si tu me dis que ta version avec la virgule prends toute la ligne ton excel et ton VBA SONT EXOTIQUES

    PAR CE QUE CHEZ MOI C EST TA VERSION QUI BUGUE DU MOINS ELLE ME DONNE Cx ET DPx (2 CELLULES )

    EN GENERAL ON SE SERT DE LA FORMULE AVEC LA VIRGULE POUR LES PLAGES NON CONTIGUES

    exemple1

    set r= .range("A1","C3","H15" )--> 3 cellule

    exemple2
    set r= .range("A1:H15")---> toutes les cellules de a1 à h15

    ma foi c'est bizare
    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-2010] Optimisation d'une macro de recherche et copie
    Par alcalis16 dans le forum Excel
    Réponses: 5
    Dernier message: 09/07/2015, 10h00
  2. [XL-2007] Optimisation d'une macro + Application à tous les onglets
    Par Identifiant75 dans le forum Excel
    Réponses: 53
    Dernier message: 05/05/2015, 19h23
  3. Optimisation d'une macro lente
    Par Zebulon777 dans le forum Macros et VBA Excel
    Réponses: 8
    Dernier message: 11/12/2012, 22h35
  4. optimisation d'une macro
    Par Alphonss dans le forum Macros et VBA Excel
    Réponses: 12
    Dernier message: 29/10/2009, 15h07
  5. probleme d'optimisation d'une macro
    Par ylabarre dans le forum VBA Outlook
    Réponses: 5
    Dernier message: 28/09/2007, 16h40

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