Lenteur de suppression

Résolu
Fahora Messages postés 949 Statut Membre -  
Fahora Messages postés 949 Statut Membre -
Bonjour,

Je souhaite supprimer des lignes d'un tableau selon si une cellule est vide ou non.
Cela fonctionne très bien, je pense avoir réussi. Le seul problème est la lenteur de l’exécution de la macro.

Je vous joins le bout de code concernant la partie suppression des lignes.


NbLig = Cells.SpecialCells(xlCellTypeLastCell).Row

For i = 2 To NbLig
If Not (IsEmpty(Cells(i, 22))) Then
Cells(i, 1).EntireRow.Delete
i = i - 1
End If
Next i


Je sais que je pourrais inverser le pas et partir du bas pour remonter dans les lignes afin d'en "sauter" aucune, mais est ce que ça accélérerait vraiment le programme ?
Je suis preneur de tout conseil.

Merci d'avance !

Cordialement,



--
Nos seules limites sont celles que nous nous imposons nous-même.
La politesse et un merci ne tuent pas. Il existe un bouton pour "Résolu" pour confirmer que     votre problème n'en est plus un. Fahora

5 réponses

  1. Utilisateur anonyme
     
    Personnellement j'ai testé ton code et il n'y a aucune lenteur...
    0
    1. Fahora Messages postés 949 Statut Membre 68
       
      Bonjour , et merci de la réponse.

      Je n'ai pas beaucoup de lignes , mais j'ai quelques onglets pour lequel cette maccro est utilisée. En tout et pour tout , j'ai environ 900 lignes et la maccro met 30 minutes...

      Combien de temps prend t'elle pour toi , dans un tel échantillon ?
      0
    2. Utilisateur anonyme > Fahora Messages postés 949 Statut Membre
       
      J'ai retrouvé un vieux fichier avec 2569 lignes j'y ai ajouté les tiennes et il me faut 15 à 20 secondes...
      0
    3. Fahora Messages postés 949 Statut Membre 68
       
      Mon dieu ... Donc il y a un problème...

      Dans ma colonne (22), je n'ai pas de formule ou quoi ce soit... Juste une chaine de caractère...

      Dans le doute , est ce que le fait qu'il y ait une formule pourrait ralentir le process ?
      0
    4. Fahora Messages postés 949 Statut Membre 68
       
      Ah ,

      Je pense avoir compris ...

      J'ai une fonction qui vérifie à chaque changement du classeur ...

      Private Sub Worksheet_Change(ByVal Target As Excel.Range)
      'colonne à "surveiller" (ici colonne A)
      If Target.Column = 3 Then
      ' pour vérifier si la saisie n'existe pas déjà dans la colonne
      If Application.WorksheetFunction. _
      CountIf(Range("c:c"), Target.Value) > 1 Then
      MsgBox "Attention ! Numéro déjà saisie"
      Target.Value = ""
      Target.Select
      End If
      End If
      End Sub

      As tu une idée pour suspendre cette routine pendant la suppression des lignes ?
      0
    5. Utilisateur anonyme > Fahora Messages postés 949 Statut Membre
       

      Sub [lenomdetamacro] ()
      Worksheet_Change.Stop()
      'le code de ta macro supprimant des lignes
      Worksheet_Change.Start() 'pour redémarrer ta macro
      End Sub

      C'est ce que j'utilise moi quand je suis dans ton cas
      0
  2. f894009 Messages postés 17417 Date d'inscription   Statut Membre Dernière intervention   1 717
     
    Bonjour a vous deux,

    pour eviter l'interruption par les evenements Excel

        Application.EnableEvents = False   'stop 
        Application.EnableEvents = True    'start
    


    et
    figeage/defigeage ecran pour gain de temps
        Application.ScreenUpdating = False
        Application.ScreenUpdating = True
    
    0
    1. Utilisateur anonyme
       
      Merci de la précision ! :)
      0
    2. Fahora Messages postés 949 Statut Membre 68
       
      Bonjour F894009,

      Malheureusement, après essai. Ca n'augmente pas la vitesse de mon programme :(
      Ca reste à une suppression toutes les demi secondes a peut près ...
      On est bien d'accord que dans mon cas :

      Application.EnableEvents = False   

      Vient en premier dans mon code ?
      0
      1. Utilisateur anonyme > Fahora Messages postés 949 Statut Membre
         
        Oui ça vient en premier car il faut stopper avant de démarrer
        0
  3. eriiic Messages postés 24581 Date d'inscription   Statut Contributeur Dernière intervention   7 281
     
    Bonjour,

    une méthode beaucoup plus rapide : filtrer, supprimer les lignes filtrées.
    Récupère le plus gros à l'enregistreur de macro et fait les finitions à la main de façon que ça englobe la taille maxi de ta base.
    Si pb tu dis...
    Sinon dans une boucle de suppression il faut absolument faire de bas en haut. Non pas pour le temps mais pour que ce soit correct tout simplement.
    eric
    0
    1. Fahora Messages postés 949 Statut Membre 68
       
      Bonjour Eric et merci de ton intervention.

      Je vais essayer l'histoire du filtre.

      Je ne comprends pas trop en quoi le "correct" de bas en haut mais bon.
      0
    2. eriiic Messages postés 24581 Date d'inscription   Statut Contributeur Dernière intervention   7 281
       
      Bonjour,

      Je ne comprends pas trop en quoi le "correct" de bas en haut mais bon.
      Tu contrôles et supprimes la ligne 5, toutes remontent et la 6 devient la 5.
      Tu fais Next ligne, tu passes donc au contrôle de la 6.
      Seulement la 6 est l'ex 7 et tu n'as pas testé l'ex 6 devenue 5.
      Compris ou pas très clair ?
      eric
      0
    3. Fahora Messages postés 949 Statut Membre 68
       
      Oui oui , d'où l'interet de quand je supprime une ligne , j'enleve 1 à mon incrémentation
      0
    4. eriiic Messages postés 24581 Date d'inscription   Statut Contributeur Dernière intervention   7 281
       
      On peut aussi faire comme ça oui.
      Je n'avais pas regardé en détail vu que le topic était déjà bien avancé et que je proposais juste une autre méthode.
      0
    5. f894009 Messages postés 17417 Date d'inscription   Statut Membre Dernière intervention   1 717 > eriiic Messages postés 24581 Date d'inscription   Statut Contributeur Dernière intervention  
       
      Bonjour eriiic,

      Son probleme est plutot lie aux evenements feuille car il y a du code dans le VBA de la feuille de suppression (voir Fahora - 20 juil. 2016 à 11:41 ). Je lui ai mis les instructions pour, mais sans son fichier, pas vraiment possible de comprendre
      0
  4. eriiic Messages postés 24581 Date d'inscription   Statut Contributeur Dernière intervention   7 281
     
    exemple suppression par filtre : https://www.cjoint.com/c/FGvjYxtZ14Q

    PS: après avoir jeté un oeil à ton fichier si c'est toujours lent tu pourrais ajouter au début en plus de la désactivation des événements :
        With Application
            .ScreenUpdating = False
            .Calculation = xlCalculationManual
        End With
    
        With Sheets("Feuil1") ' pour chaque feuille
            ' >=2007: calcul formats conditionnels
            .EnableFormatConditionsCalculation = False
        End With

    et restaurer après

    En essayant continuellement, on finit par réussir. 
    Donc plus ça rate, plus on a de chances que ça marche.(les Shadoks)
    En plus du merci (si si, ça se fait !!!), penser à mettre en résolu. Merci
    0
    1. Fahora Messages postés 949 Statut Membre 68
       
      Merci Eric , Je teste ça.

      Comment faire pour faire un filtre sur tous ce qui n'est pas vide ?
      0
    2. f894009 Messages postés 17417 Date d'inscription   Statut Membre Dernière intervention   1 717 > Fahora Messages postés 949 Statut Membre
       
      Re,

      code eriiic modifie pour cellules non vide

      Sub supp()
          'Range("$A$1").AutoFilter Field:=1, Criteria1:="="      'cellules vide
          Range("$A$1").AutoFilter Field:=1, Criteria1:="<>"     'cellules non vide
          On Error Resume Next
          Range("_FilterDataBase").Offset(1, 0).Resize(Range("_FilterDataBase").Rows.Count - 1) _
                  .SpecialCells(xlCellTypeVisible).Delete Shift:=xlUp
          On Error GoTo 0
          Range("$A$1").AutoFilter Field:=1
      End Sub
      0
    3. Fahora Messages postés 949 Statut Membre 68
       
      Malheureusement , j'avais déjà essayé avec " <> " et ça me supprime tout...
      0
    4. Fahora Messages postés 949 Statut Membre 68
       
      Mon filtre est sur la colonne V, j'ai donc changé Range($A$1) par Range($V$1), on est bien d'accord ?
      0
    5. eriiic Messages postés 24581 Date d'inscription   Statut Contributeur Dernière intervention   7 281
       
      C'est le Field qui indique la colonne.
      La cellule importe peu, jamais compris à quoi elle servait.
      0
  5. Vous n’avez pas trouvé la réponse que vous recherchez ?

    Posez votre question
  6. Maurice
     
    Bonjour

    tu compte déjà 3000 ligne et moi 869 dur
    voila un model
    Sub Test()
    NbLig = Range("A" & Rows.Count).End(xlUp).Row
       For I = NbLig To 2 Step -1
           If Not (IsEmpty(Cells(I, 18))) Then
              Rows(I).Delete
           End If
       Next I
    End Sub
    
    

    A+
    Maurice
    -1
    1. f894009 Messages postés 17417 Date d'inscription   Statut Membre Dernière intervention   1 717
       
      Bonjour,

      Normal avec sa ligne de code:
      NbLig = Cells.SpecialCells(xlCellTypeLastCell).Row


      Il faut "simplement" ne pas oublier d'enregistrer a chaque modif de la feuille en cause et meme avec ca c'est pas le top

      La methode filtre de eriiic, elle est top, pas besion de comptage
      0