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 :

Execution du code qui ralentit brusquement [XL-2016]


Sujet :

Macros et VBA Excel

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Novembre 2013
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique

    Informations forums :
    Inscription : Novembre 2013
    Messages : 22
    Par défaut Execution du code qui ralentit brusquement
    Bonjour à tous,

    J'ai un souci peu banal ... et je n’avoue ne pas savoir comment le résoudre. En fait, j'ai un tableau à de 600 lignes environ. Ce tableau est issu d’une extraction de base de données et se compose en deux parties : Colle A à D et Colonne E à H (donc 2 fois quatre colonnes).

    - Ces deux colonnes traitent des mêmes objets (mêmes infos et tout à part la référence de l’objet). Pour info, la présentation est ainsi car il existe un lien de filiation entre les deux objets de chaque ligne.
    - L’algorithme a pour objectif de remettre de l’ordre en insérant/déplaçant sous « A1 : D1 » les cellules « E1 :H1 », sous « A2 : D2 » les cellules « E2 :H2 » etc
    - Donc à la fin de l’exécution le tableau a doublé sa taille (le range a une taille variable donc)

    J’espère être clair sur la contextualisation

    Mon code est le suivant et il fonctionne.
    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
    Sub test_mere_fille()
     
    Application.ScreenUpdating = False
     
    []
     
    i = 3
     
    doublon = False
     
    Do While Worksheets("BBC").Cells(i, 1).Value <> "" ‘parcourt le tableau tant qu’il y a des cellules non vide en colonnes A
     
        suiv = i + 1
     
        'existe-t-il une fille (au moins une)
        If Cells(i, 9).Value <> "" Then
           fille_trouvee = True
           nb_insert = 1 ‘prevision d’inserer au moins une ligne
     
            'tant que le contenu de la cellule est le même que celui de la cellule suivante (cas ou un objet mère a plusieurs objets filles)
            While Cells(suiv, 1).Value = Cells(i, 1)
                doublon = True 'flag qui dit que des doublons sont trouvés
                nb_insert = nb_insert + 1 'calcule le nombre de doublons et déduit le nombre de ligne à insérer (incrémente à chaque itération)
                suiv = suiv + 1
            Wend
     
        'si une fille ou des doublons ou plus sont trouvés
            If fille_trouvee = True Or doublon = True Then
                doublon = False 'reinitialise la valeur
                fille_trouvee = False ''reinitialise la valeur
                With Worksheets("BBC")
                    .Rows(i + nb_insert).Resize(nb_insert).Insert 'insere le bon nombre de ligne
                    .Range("I" & i & ":P" & i + nb_insert - 1).Cut .Range("A" & i + nb_insert) 'déplace les cellules concernées
     
                    If nb_insert <> 1 Then 'supprime les mère doublons
                        Worksheets("BBC").Rows(i & ":" & i + nb_insert - 2).Delete
                    End If
     
                .Rows(i + 1 & ":" & i + nb_insert).Group ‘groupe les lignes histoire de garder la trace de la structure initiale
                End With
     
               End If
     
        End If
     
        i = i + nb_insert + 1 'reajuste la valeur de i après insert
     
    Loop
     
    Application.ScreenUpdating = True
     
    'ActiveSheet.Outline.SummaryRow = 0 'mets le '+' en haut
     
    End Sub
    Mon problème c'est que l’exécution va arriver à la 200/300 lignes en 2 secondes puis le code va se mettre tout d'un coup à ramer, et ce ralentissement ne va faire que s'accroitre a chaque itération. L’exécution va s'achever après une bonne vingtaine de minutes, ce qui n'est pas acceptable.

    Petite animation qui présente le problème :

    Nom : Animation 0.gif
Affichages : 796
Taille : 339,4 Ko

    Application.ScreeUpdating est bien sur False.

    On voit bien que ce sont les instructions du groupes With qui rament
    Quelqu'un aurait un avis sur la question ?

    Merci d'avance.

    Tonio

  2. #2
    Expert éminent
    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
    Par défaut


    Bonjour,

    en fait c'est classique : l'insertion rame, phénomène récurrent depuis toujours !

    Une voie à explorer est l'utilisation d'une variable tableau pour le montage final …


    ______________________________________________________________________________________________________
    Je suis Paris, Charlie, Bruxelles, …

  3. #3
    Membre averti
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Novembre 2013
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique

    Informations forums :
    Inscription : Novembre 2013
    Messages : 22
    Par défaut
    Bonjour,

    Merci pour ta réponse. En fait j'ai essayé de passer par la méthode suivante trouvée ici. Je pense que les deux idées se rejoignent.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Dim rg As Range
    Dim v as Variant
    Set rg = Worksheets("MaFeuille").Range("A1:G10000")
    v = rg
    'On travaille sur v ...
    rg = v
    De ce que j'ai compris en fouinant par ci par là, c'est qu'il faut limiter autant que possible les accès aux feuilles.

    Mais je n'arrive a écrire l'équivalent de la boucle With en commençant par With v. J'ai toujours un probleme d'objet mal défini ou autre, alors que si je mets With rg ça fonctionne ...

    Tonio

  4. #4
    Expert éminent
    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
    Par défaut


    Les deux variables ne sont pas du même type de donnée et With n'est pas une boucle !

    Autre voie : copier les données vers une nouvelle plage …

  5. #5
    Membre averti
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Novembre 2013
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique

    Informations forums :
    Inscription : Novembre 2013
    Messages : 22
    Par défaut
    Re,

    Citation Envoyé par Marc-L Voir le message

    Autre voie : copier les données vers une nouvelle plage …
    C'est a dire ? Dès lors que je copie des données vers une autre plage je fais quoi après ? Il y aura toujours des insert a faire à un moment donné ... non ?

    Sinon, après quelques heures de recherches cela reste vain ...
    La solution semble effectivement passer par là.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Dim montab As Variant
    montab = Worksheets("BBC").Range("A2:P" & Dernligne)
    montab.insert(i) ?
    montab.rows(i).resize(i).Insert ?
    montab ... QUOI !??? lol

    Rien ne marche, le net ne m'est que de peu d'aide et la votre serait bienvenue ...

    En fait le grand mystère reste : comme insérer une ligne à une variable de type variant ? Je ne suis même pas sûr de me poser la bonne question ...

    Je ne peux même pas tester une astuce qui fait :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Dim rg1 as range, rg2 as range
    set rg1 = Worksheets("BBC").Range("A2:P" & Dernligne)
    rg2 = rg1
    Comme si un range ne pouvait être égal a un autre. J'ai toujours trouvé l'objet "range" pénible à utiliser et essayé d’éviter de l'utiliser mais là j'arrive pas a passer outre.

    Merci a vous.

    Tonio

    Edit : En fait j'essaie d'abstraire la probleme en ne travaillant que sur des variables et plus sur la feuille excel directement ...

  6. #6
    Membre émérite
    Homme Profil pro
    Directeur
    Inscrit en
    Avril 2003
    Messages
    724
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Directeur

    Informations forums :
    Inscription : Avril 2003
    Messages : 724
    Par défaut
    Salut,

    Peux tu nous passer un classeur, avec des données de simulation?
    Ça serait plus facile pour mettre en évidence le problème et essayer
    de trouver une meilleure programmation.
    Cordialement,

  7. #7
    Expert confirmé
    Homme Profil pro
    aucune
    Inscrit en
    Avril 2016
    Messages
    7 563
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 84
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : aucune

    Informations forums :
    Inscription : Avril 2016
    Messages : 7 563
    Par défaut
    Bonjour,
    Rien n'est jamais aussi lourd et maladroit que de modifier la valeur de i pour retomber sur ses pattes comme ici :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    i = i + nb_insert + 1 'reajuste la valeur de i après insert
    On évite tout cela en traitant de bas en haut, tout simplement, en en ajoutant toujours en-dessous de sorte à ne jamais se faire de croche-pieds.

  8. #8
    Expert éminent
    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
    Par défaut
    Citation Envoyé par T0n10 Voir le message
    C'est a dire ? Dès lors que je copie des données vers une autre plage je fais quoi après ? Il y aura toujours des insert a faire à un moment donné ... non ?
    Non, sans insertion évidemment sinon ce ne serait pas une autre voie


    Citation Envoyé par T0n10 Voir le message
    En faisant du pas a pas on comprend vite a quoi sert cet algo.
    Ben voyons ‼ Pour ceux qui ont le temps sinon on zappe, on ne répond même pas !
    Conformément aux règles de ce forum, une explication claire & exhaustive incite à apporter la meilleure réponse possible …

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

Discussions similaires

  1. Réponses: 3
    Dernier message: 28/08/2007, 10h15
  2. [MySQL] partie de code qui ne s'execute pas
    Par ayisse dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 13/07/2007, 17h40
  3. batch qui execute du code
    Par fbu78 dans le forum Access
    Réponses: 2
    Dernier message: 21/09/2005, 22h31
  4. code qui s'execute plusieurs fois
    Par khelif dans le forum JBuilder
    Réponses: 1
    Dernier message: 10/03/2005, 21h56
  5. [C#]Comment executer du code qui se trouve dans une string ?
    Par freddyboy dans le forum Windows Forms
    Réponses: 4
    Dernier message: 28/02/2005, 16h31

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