Macro pour supprimer une ligne

Macro pour supprimer une ligne - VB/VBA/VBS - Programmation

Marsh Posté le 17-02-2013 à 08:37:40    

Bonjour à tous, je suis nouveau sur forum et j'ai besoin d'aide concernant une macro que je dois faire pour le boulot....
 
Je souhaite supprimer une ligne quand dans une cellule d'une colonne donnée en l'occurence  la colonne L, j'ai le nombre Zéro. L'objectif est de faire une moyenne de la colonne mais sans prendre les valeurs zéro qui fause forcement ma moyenne.
 
Info complémentaire, Le fichier à traiter se trouve dans l'onglet que j'ai nommé fichier. Les infos doivent me remonter dans la Feuil3 du classeur excell.
 
Voici ce que j'ai tenté mais ça ne marche pas. Quand j'execute la macro j'ai le message suivant qui apparaît: Erreur compilation instruction incorrecte d'une procédure"
 
'Sub
 
Set Plage = Fichier. Range ("L:L" )
 
For Each Cellule In Plage. Cells
 
If Cellule = 0 Then
 
Cellule.EntireRow.Delete
 
End If
 
Next
 
End Sub
 
 
MERCI POUR VOTRE AIDE
 

Reply

Marsh Posté le 17-02-2013 à 08:37:40   

Reply

Marsh Posté le 18-02-2013 à 09:23:15    

Bonjour,
essaye avec :
Set Plage = sheets("Fichier" ).Range ("L:L" )


---------------
Bel ours Vave, je me dois de l’admettre. -Skyl"win"-  Mais toi tu es intelligent -Homerde- - Ce génie -SkylWINd- JDD S16M72 10:43:46 GMT-DTC +1
Reply

Marsh Posté le 19-02-2013 à 19:02:09    

Bonjour,
 
J'ai essayé, je ne n'ai plus de message d'erreur la macro mouline mais elle ne m'efface pas toutes les lignes d'un seul coup il faut que je la relance plein de fois pour arriver à tout effacer. Il y a du mieux mais il doit manquer quelques chose.
 
merci

Reply

Marsh Posté le 20-02-2013 à 00:31:41    

 
           ' soir !   En fait c'est tout à fait logique vu le code ‼
 
           En le relisant, rien ne te saute aux yeux ?
           Que se passe-t-il lors de la suppression d'une ligne ?   (Zut j'en ai trop dit, cela doit te mettre sur la voie !)
 
           La suite au prochain épisode …
 

Reply

Marsh Posté le 21-02-2013 à 13:41:02    

Re bonjour,
 
 Je suppose qu'il faut lui dire qu'il faut aller à la ligne suivante par exemple? mais je ne sais pas comment on fait car je débute en macro et ce n'est pas évident. J'ai essaye & (1Up) après délete, ensuite après Next j'ai mis ligne  ou cellule ça n'y a rien fait!
 
A l'aide!!!!

Reply

Marsh Posté le 21-02-2013 à 17:07:15    

Marc L a écrit :

                      Que se passe-t-il lors de la suppression d'une ligne ?

           Rien qu'en supprimant manuellement une ligne, c'est évident …
 
           Supposons les premiers zéros se situent en lignes 11 & 12.
           En supprimant l'intégralité de la ligne 11 (manuellement comme par code), les lignes suivantes remontent d'un cran,
           la ligne 12 devenant la nouvelle ligne 11.    Mais dans le code, il y a le  Next  juste après la suppression,
           donc le code passe à la ligne 12 (l'ancienne ligne 13) sans traiter cette nouvelle ligne 11, l'ancienne n°12 …
           C'est donc juste logique, à chaque paire de zéros consécutifs, le deuxième n'est pas traité, d'où l'obligation de relancer le code …
 
           Comme vu récemment dans un autre post avec oovaveoo, deux solutions possibles.
 
           La première est une boucle classique, comme dans le code exposé, mais effectuant une remontée au lieu de scanner  
           les lignes en descente car, lors de la suppression d'une ligne, les suivantes remontant d'un cran ont déjà été traitées !
 
           En passant, des p'tites remarques concernant le code de départ :
 
           - définir une plage via une variable objet pour ne l'utiliser qu'une fois …  autant utiliser directement la plage dans le code !
 
           - La boucle scanne l'intégralité de la colonne même si, après la dernière cellule renseignée, beaucoup d'autres sont inutilisées,
             que de temps perdu !  (Proust si tu m'entends, …)  Pour éviter un tel gâchis, la remontée s'effectue depuis la dernière saisie.
             Je préfère de loin une boucle  For Each  pointant sur les éléments d'une collection mais elle ne peut convenir dans ce cas …
 
           - Une ligne est supprimée si la cellule = 0, et comme cela, tout simplement, et même si c'est logique,
             c'est un gouffre se chiffrant non plus en secondes mais en minutes ‼
             En effet, Excel considère une cellule vide, sans saisie, comme égale à zéro, le méchant piège ‼
             Franchement, vous avez dû trouver le temps long en exécutant votre code car, si par exemple 30 000 cellules vides
             suivent la dernière saisie de la colonne, c'est 30 000 suppressions inutiles ‼   Quoique qu'une pause café peut alors se justifier …
 
           Évidemment ce dernier point est aussi pris en compte (moins sensible quand même en remontant à partir de la dernière saisie)
           dans la première solution :

Code :
  1. Sub DelRowIf0()
  2.     With Worksheets("Fichier" )
  3.         For R = .Cells(.Rows.Count, 12).End(xlUp).Row To 1 Step -1
  4.             If .Cells(R, 12) > "" And .Cells(R, 12) = 0 Then .Cells(R, 12).EntireRow.Delete
  5.         Next
  6.     End With
  7. End Sub


           La deuxième solution repose sur les méthodes  Find  et  FindNext  :

Code :
  1. Sub Find0DelRow()
  2.     Application.ScreenUpdating = False
  3.     With Worksheets("Fichier" ).Columns(12)
  4.         Set Rg = .Find(0, , xlValues, xlWhole)
  5.         Do Until Rg Is Nothing
  6.             L = Rg.Row + (Rg.Row > 1)
  7.             Rg.EntireRow.Delete
  8.             Set Rg = .FindNext(.Cells(L))
  9.         Loop
  10.     End With
  11.     Application.ScreenUpdating = True
  12. End Sub


            A armes égales, le rafraîchissement de l'écran désactivé (ScreenUpdating à False),
            la première solution s'avère plus lente que cette dernière, pourtant dotée de plus de code et
            tout en scannant l'intégralité de la colonne, comme le vérifie ce tableau de mesures en secondes :

      Nombre de zéros   Rafraîchissement   DelRowIf0   Find0DelRow
       Test 1 : 1008                Avec     9,111        7,861
                                    Sans     3,574        2,449
 
       Test 2 :   27                Avec     2,074        0,218
                                    Sans     1,933        0,015

            Protocole de tests :   blocs de 28 cellules dont une à zéro répartis sur plus de 65 000 lignes.
 
            Plus la plage est grande et moins il y a de lignes à supprimer, plus la méthode  Find  est redoutable de rapidité …


Message édité par Marc L le 21-02-2013 à 17:23:23
Reply

Marsh Posté le 21-02-2013 à 17:41:29    

Marc L pour info, tu fais comment ton bench ?
Tu l'insère dans le code en mettant un départ l'heure début / fin ? (c'est ce que je fais)
Ou tu as un logiciel tiers qui le fait ?


---------------
Bel ours Vave, je me dois de l’admettre. -Skyl"win"-  Mais toi tu es intelligent -Homerde- - Ce génie -SkylWINd- JDD S16M72 10:43:46 GMT-DTC +1
Reply

Marsh Posté le 21-02-2013 à 17:45:37    

 
           Non, tout simple, comme toi …
 

Reply

Marsh Posté le 21-02-2013 à 18:29:05    

Ok, merci ;)


---------------
Bel ours Vave, je me dois de l’admettre. -Skyl"win"-  Mais toi tu es intelligent -Homerde- - Ce génie -SkylWINd- JDD S16M72 10:43:46 GMT-DTC +1
Reply

Marsh Posté le 21-02-2013 à 18:49:18    

Eh bien Marc, je ne peux que te remercier pour toutes ces bonnes infos!!! Je teste ça demain au boulot et je te tiens au courant.
 
Encore une fois merci de m'avoir consacré de votre temps.....

Reply

Marsh Posté le 21-02-2013 à 18:49:18   

Reply

Marsh Posté le 22-02-2013 à 19:31:56    

J'ai essaye ta macro ce matin. Aucun problème ça fonctionne parfaitement . Je te remercie encore pour ton aide.

Reply

Marsh Posté le 24-02-2013 à 11:34:16    

 
           Et laquelle as-tu choisi ?
 

Reply

Marsh Posté le 27-02-2013 à 01:27:11    

Salut,
 
j'ai pas testé mais je ferais ça :
 
Dim li_col as Integer
Dim ll_row as Long
 
Application.ScreenUpdating = False
 
ll_row = 1
 
While Sheets("Fichier" ).Cells(ll_row, 1).Value <> ""
 If Sheets("Fichier" ).Cells(ll_row, 12).Value = "0" Then  
  Cells(ll_row, 1).EntireRow.Delete
  ll_row = ll_row - 1
 End If
 ll_row = ll_row + 1
Wend
 
Application.ScreenUpdating = True
 
PS : Si ton fichier contient des milliers de lignes, cette méthode est lente..il vaut mieux faire un filtre sur la colonne J égale 0 et supprimer toutes les lignes, du style :  
 
        Cells.AutoFilter Field:=12, Criteria1:= "0"
        Application.DisplayAlerts = False
        Range(Cells(1, 1), Cells(1, 1).End(xlDown)).Rows.Delete
        Application.DisplayAlerts = True
        Range(Range("A1" ), Range("A1" ).End(xlToRight)).AutoFilter Field:=12
 
 
A+

Reply

Marsh Posté le 27-02-2013 à 20:50:07    

 
           Salut xtitusx !
 
           Effectivement t'as pas dû tester ton code car ta ligne While porte sur la première colonne au lieu de la douzième !
           Ta boucle s'arrête sur la première cellule vide, posant donc un souci dans le cas d'une plage avec des blancs …
 
           Ensuite c'est dommage de diminuer un compteur lors de la suppression d'une ligne pour de suite le ré-incrémenter,
           autant ne pas y toucher en utilisant une structure  If {…} Then {…} Else  :

     ll_row = 1
 
     While Sheets("Fichier" ).Cells(ll_row, 12) <> ""
        If Sheets("Fichier" ).Cells(ll_row, 12) = 0 Then Cells(ll_row, 12).EntireRow.Delete _
                                                    Else ll_row = ll_row + 1
     Wend

           A noter au passage :  une boucle  While {…} Wend  est obsolète, lui préférer  Do {…} Loop  bien plus rapide …
 
           Quant à la méthode du filtre de ton second code, logique tout à fait respectable, pour y avoir pensée & testée,
           rafraîchissement de l'écran désactivé, elle reste plus lente que la méthode Find, ce pourquoi je ne l'ai point évoquée.
 

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed