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 :

Aide pour optimisation/gain de temps sur une macro


Sujet :

Macros et VBA Excel

  1. #1
    Membre régulier Avatar de Nono Sto
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    350
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 350
    Points : 74
    Points
    74
    Par défaut Aide pour optimisation/gain de temps sur une macro
    Cheres amies, chers amis du forum

    Voici un bout de code qui s’exécute via une boucle:

    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
     
     
    Workbooks.Open Filename:=strWorksheetPath
        strWorksheetName = ActiveWorkbook.Name
     
        With ActiveWorkbook.Worksheets("TEST")
        Worksheets("TEST").Activate
    .
    .
    .
            gvVNTCriteriaVector = CreateCriteriaVector(dictReference)
            'filtre: affichage du complémentaire de l'ensemble des refernces de la peronnes concerné
            .Range(.Cells(4, 1), .Cells(4, 1).End(xlToRight)).AutoFilter Field:=20, Criteria1:=Array(gvVNTCriteriaVector), Operator:=xlFilterValues
            'destruction des lignes HS
            Call DeleteRow(Nrow, Ncol)
            .Range(.Cells(4, 1), .Cells(4, 1).End(xlToRight)).AutoFilter
            'actualisation des TCD et recalcul
            Application.Calculate
            Workbooks(strWorksheetName).Close True
            j = j + 1
     
        End With
    Et le code de la sub DeleteRow

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    Sub DeleteRow(ByVal intRowTabSize As Long, ByVal intColTabSize As Long)
     
    Dim rngRangeRef, rngRangeDel As Range
     
        Set rngRangeRef = ActiveSheet.Range(ActiveSheet.Cells(5, 1), ActiveSheet.Cells(intRowTabSize + 3, intColTabSize + 3))
        Set rngRangeDel = rngRangeRef.Resize(ActiveSheet.Range(ActiveSheet.Cells(5, 1), ActiveSheet.Cells(intRowTabSize + 3, intColTabSize + 3)).Rows.Count)
        rngRangeDel.SpecialCells(xlCellTypeVisible).Delete shift:=xlUp
     
    End Sub
    Et je trouve que la sélection des valeur du filtre via la commande Array, et la destruction des ligne prennent beaucoup de temps. De plus le recalcule de tout les TCD et autre feuille prend aussi bcp de temps. Dés lors pour la création des fichier pour l’équipe entière (environ 40 personne) cela prend 1H05....Les fichiers creer sont diffrerent pour chacune des personnes, c'est - à - dire que le vecteur gvVNTCriteriaVector est modifier a chaque fois.

    A part ce bout de code le reste vas tres vite.

    Auriez vous une idée SVP?

    Merci

  2. #2
    Membre actif
    Homme Profil pro
    Chargé d'études RH
    Inscrit en
    Août 2014
    Messages
    162
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Chargé d'études RH
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2014
    Messages : 162
    Points : 207
    Points
    207
    Par défaut
    Bonjour,

    J'ai également l'habitude de supprimer des lignes vides, ce qui peut prendre beaucoup de temps. En règle générale, je met souvent cela en début de mon code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
            With Application
                .DisplayAlerts = False
                .ScreenUpdating = False
                .DisplayStatusBar = False
                .Calculation = xlCalculationManual
            End With
    et à la fin :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
        With Application
            .Calculation = xlCalculationAutomatic
            .DisplayStatusBar = True
            .CutCopyMode = False
            .StatusBar = False
            .DisplayAlerts = True
            .ScreenUpdating = True
        End With
    Attention, ce code désactive des boites de dialogues qui sont peut être utiles dans ton code. Si c'est le cas, tu peux supprimer les lignes "DisplayAlerts = true" et "DispalyAlerts = false"

    Ca me fait toujours gagner du temps, mais j'imagine que tu y a peut être déjà pensé.
    Dans ce cas, est il envisageable de copier/coller tes données à conserver sur une nouvelle feuille et de supprimer l'ancienne feuille (qui contient les lignes à détruire) ?

    Autrement, les vrais experts d'excel vont arriver à la rescousse

  3. #3
    Membre averti
    Homme Profil pro
    Ingénieur
    Inscrit en
    Juin 2011
    Messages
    212
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Doubs (Franche Comté)

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

    Informations forums :
    Inscription : Juin 2011
    Messages : 212
    Points : 334
    Points
    334
    Par défaut
    Bonjour,

    Cela me rappelle quelque chose...
    http://www.developpez.net/forums/d15...ement-d-macro/

    Cordialement.

  4. #4
    Expert éminent sénior
    Avatar de Marc-L
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    9 468
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2013
    Messages : 9 468
    Points : 18 674
    Points
    18 674
    Par défaut



    Bonjour, bonjour !

    Pour accélérer une suppression de lignes, il faut au préalable trier la plage, si, si !
    Car si les lignes à supprimer se suivent dans une plage contigüe, la suppression n'en sera que plus rapide …


    ______________________________________________________________________________________________________
    Je suis Paris, …

  5. #5
    Membre éprouvé Avatar de issoram
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2009
    Messages
    665
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2009
    Messages : 665
    Points : 929
    Points
    929
    Par défaut
    Bonjour,

    Et je trouve que la sélection des valeur du filtre via la commande Array, et la destruction des ligne prennent beaucoup de temps. De plus le recalcule de tout les TCD et autre feuille prend aussi bcp de temps
    As-tu un ordre de grandeur du temps pris par chacune des 3 opérations: filtre, suppression des lignes, recalcul des TCD?

    Si la solution de Marc ne donne pas un gain de temps suffisant à tes yeux, je vois deux solutions possibles:
    1. Un filtre avancé pour extraire directement les données don tu as besoin et "alimenter" tes TCD (c'est ce que j'ai compris)
    2. L'utilisation de tableaux mais là ça oblige à écrire plus de code


    Bon courage.

  6. #6
    Membre régulier Avatar de Nono Sto
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    350
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 350
    Points : 74
    Points
    74
    Par défaut
    Citation Envoyé par Marc-L Voir le message



    Bonjour, bonjour !

    Pour accélérer une suppression de lignes, il faut au préalable trier la plage, si, si !
    Car si les lignes à supprimer se suivent dans une plage contigüe, la suppression n'en sera que plus rapide …


    ______________________________________________________________________________________________________
    Je suis Paris, …
    Enorme, mon vecteur avec les valeurs pour le filtre est classé par ordre alpha croissant, j'ai filtre le tableau a filtrer/supprimer aussi par ordre alpha, résultat temps d’exécution divisé par 2.....

    Citation Envoyé par issoram
    L'utilisation de tableaux mais là ça oblige à écrire plus de code
    A ce stade si je veux encore amélioré je vais devoir réfléchir a passer par des variable tableaux....

    Pour rappel:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    'filtre: affichage du complémentaire de l'ensemble des refernces de la peronnes concerné
    .Range(.Cells(4, 1), .Cells(4, 1).End(xlToRight)).AutoFilter Field:=20, Criteria1:=Array(gvVNTCriteriaVector), Operator:=xlFilterValues
    'destruction des lignes HS
    Call DeleteRow(Nrow, Ncol)
    et:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    Sub DeleteRow(ByVal intRowTabSize As Long, ByVal intColTabSize As Long)
     
    Dim rngRangeRef, rngRangeDel As Range
     
        Set rngRangeRef = ActiveSheet.Range(ActiveSheet.Cells(5, 1), ActiveSheet.Cells(intRowTabSize + 3, intColTabSize + 3))
        Set rngRangeDel = rngRangeRef.Resize(ActiveSheet.Range(ActiveSheet.Cells(5, 1), ActiveSheet.Cells(intRowTabSize + 3, intColTabSize + 3)).Rows.Count)
        rngRangeDel.SpecialCells(xlCellTypeVisible).Delete shift:=xlUp
     
    End Sub
    Alors je n'ai pas bcp d'idée, dans un premier copier le tableau complet dans une variable tableau (Variant ou String d'ailleurs? sachant que par la suite le format de la cellule est pris en compte dans les TCD, et il peut avoir de tous les type nombre, date...), bon sa sava.

    Mais en suite comment éliminer les ligne du tableau a partir du vector de reference: une double boucle ou je testerais ligne par ligne une valeur issue du vecteur, ou il ya mieux ?

    Enfin comment redimensionner en une seul fois le tableaux en eliminant les ligne vide?

    Merci

  7. #7
    Expert éminent sénior
    Avatar de Marc-L
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    9 468
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2013
    Messages : 9 468
    Points : 18 674
    Points
    18 674
    Par défaut
    Citation Envoyé par Nono Sto Voir le message
    résultat temps d’exécution divisé par 2
    Seulement ?!

    Une fois la liste triée, vérifier manuellement après un filtre pour les lignes à supprimer
    si leurs numéros de lignes se suivent bien sans "saut" …

  8. #8
    Membre régulier Avatar de Nono Sto
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    350
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 350
    Points : 74
    Points
    74
    Par défaut
    Il y a structurellement des saut car le vecteur des critère de filtre a des sauts, par exemple je peux a avoir a supprimer la reference AXXXX, puis la reference ZXXX, du coup il ne sont pas aligné.

  9. #9
    Expert éminent sénior
    Avatar de Marc-L
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    9 468
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2013
    Messages : 9 468
    Points : 18 674
    Points
    18 674
    Par défaut

    Je me disais aussi …

    En te débrouillant pour que les lignes à supprimer se suivent
    (par exemple utilisation d'une colonne supplémentaire pour le critère de filtre), ce serait bien plus rapide !

  10. #10
    Membre régulier Avatar de Nono Sto
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    350
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 350
    Points : 74
    Points
    74
    Par défaut
    J'ai essayé de passer par des tableaux VBA et de supprimer les lignes via une double boucle:

    J'appelle en boucle une fonction qui prend en paramètre le tableau a réduire, et une clef pour le test:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    For i = 1 To UBound(gvVNTCriteriaVector)
           vntDataArray = DeleteRow(vntDataArray, gvVNTCriteriaVector(i))
    Next i
    gvVNTCriteriaVector est le vecteur des valeurs dont il faudra supprimer ligne si il est repéré, on boucle dessus....

    Je reinjecte le meme tableau a chaque foi pour supprimer toute les valeurs.

    La fonction de suppression:

    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 DeleteRow(DataArray As Variant, ByVal Keys As Variant) As Variant
     
    Dim i, j, k, n As Long
    Dim LngStart, LngEnd, LngColStart, LngColEnd As Long
     
      LngStart = LBound(DataArray): LngEnd = UBound(DataArray)
      LngColStart = LBound(DataArray, 2): LngColEnd = UBound(DataArray, 2)
     
      For i = LBound(DataArray) To UBound(DataArray)
        If DataArray(i, 20) <> Keys Then n = n + 1
      Next
     
      Dim t(): ReDim t(LBound(DataArray) To LBound(DataArray) + n - 1, LngColStart To LngColEnd) As Variant
     
      j = LBound(DataArray)
     
      For i = LngStart To LngEnd
        If DataArray(i, 20) <> Keys Then
           For k = LngColStart To LngColEnd: t(j, k) = DataArray(i, k): Next k
           j = j + 1
        End If
      Next i
     
      If n > 0 Then
        DeleteRow = t()
      Else
        Dim a(): ReDim a(1 To 1, LngColStart To LngColEnd) As Variant
        DeleteRow = a()
      End If
    Deux problèmes: un c'est archi long et la macro plante une fois sur deux car memoire insuffisante.....

    Please help me.....

Discussions similaires

  1. Besoin d'aide pour optimiser une petite query sql
    Par AsmCode dans le forum MS SQL Server
    Réponses: 5
    Dernier message: 21/01/2009, 15h52
  2. Aide pour Optimiser une Requete
    Par Thanwiel dans le forum Langage SQL
    Réponses: 10
    Dernier message: 06/12/2007, 11h31
  3. petite aide sur une macro pour transfere de valeur
    Par fpouzou dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 03/06/2007, 17h54
  4. besoin d'aide pour optimiser une requête
    Par jisse dans le forum Langage SQL
    Réponses: 4
    Dernier message: 27/01/2006, 10h41
  5. Aide pour optimiser une requete
    Par Akanath dans le forum MS SQL Server
    Réponses: 1
    Dernier message: 15/09/2005, 12h05

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