2013-07-10 4 views
1

J'ai un problème intéressant. J'ai essayé de chercher sur ce site et Google, mais il y a seulement quelques problèmes liés, aucun qui répond vraiment à ce besoin spécifique.(Excel 2003 VBA) Supprimer des lignes entières en fonction de plusieurs conditions dans une colonne

J'ai une feuille de calcul avec 10 colonnes (appelons-les A-J). Je dois supprimer toutes les lignes qui n'ont pas la valeur "30", "60", "90", "120" ou vierges dans les cellules de la colonne H.

Bien qu'il y ait plusieurs façons de faire cela, toutes ont utilisé des boucles, ce qui ne fonctionne pas pour moi car cet ensemble de données a plus de 25k lignes et cela prend 10 minutes et plus - trop longtemps. Je ai regardé les options de filtre automatique en conjonction avec la fonction .Find (par exemple, trouver toutes les lignes avec des cellules H qui ne répondent pas aux critères et supprimer) mais AutoFilter sur 2003 ne fonctionne qu'avec 2 critères, alors que j'ai 5 vérifier par contre. Je ne suis pas sûr de savoir comment procéder.

Toute aide est appréciée.

+0

Vous pouvez traiter ceci rapidement en utilisant une boucle si vous avez d'abord lu le jeu de données entier dans un tableau à deux dimensions, et copiez les "bonnes" lignes dans un deuxième tableau de même taille. Puis vider le "bon" tableau à la feuille.Sauf si vous avez un formatage de cellule que vous devez conserver. Peut-être montrer le code que vous avez déjà qui est trop lent? –

Répondre

0

Vous pouvez essayer l'option Filtre avancé où vous pouvez donner plus de deux critères pour filtrer la liste. Après avoir filtré la liste correspondant aux critères que vous avez définis, la liste filtrée peut être copiée vers un autre emplacement (option disponible) et le reste supprimé.

2

Cette supprimé toutes les lignes correspondantes (~ 10%) dans un échantillon de 25k lignes dans 20sec

Sub tt() 

Dim rw As Range 
Dim all As Range 
Dim t 
Dim b As Boolean 

t = Timer 
For Each rw In Range("A1").CurrentRegion.Rows 

    If rw.Cells(8).Value < 1 Then 

     If b Then 
      Set all = Application.Union(rw, all) 
     Else 
      Set all = rw 
      b = True 
     End If 

    End If 

Next rw 

If not all is nothing then all.EntireRow.Delete 

Debug.Print "elapsed: " & Timer - t 

End Sub 
0

Vous pouvez ajouter une colonne à la condition de votre propre:

=IF(OR(H1=30;H1=60;H1=90;H1=120;H1="");"DELETE";"") 

(la la formule est donnée pour la ligne 1, vous devez la copier-coller sur toute la plage)

Ensuite, utilisez le filtrage et le tri pour sélectionner les lignes à supprimer.

0

Quelques conseils de vitesse:

  1. Lorsque vous utilisez des données, attribuer des valeurs à tableau et tableau utiliser au lieu de * .Value;
  2. Lorsque vous travaillez avec des colonnes entières, ignorez les colonnes vides en bas;
  3. Lorsque vous effectuez des modifications intensives dans la feuille de calcul, désactivez la mise à jour de l'écran et le calcul automatique.

Déclarant, je voudrais utiliser ce code:

Sub Macro1() 
    Dim su As Boolean, cm As XlCalculation 
    Dim r As Long, v(), r_offset As Long 

    su = Application.ScreenUpdating 
    Application.ScreenUpdating = False 'Disable screen updating 
    cm = Application.Calculation 
    Application.Calculation = xlCalculationManual 'Disable automatic calculation 

    'Only use used values 
    With Intersect(Range("H:H"), Range("H:H").Worksheet.UsedRange) 
     v = .Value 'Assign values to array 
     r_offset = .Row - LBound(v) 'Mapping between array first index and worksheet row number 
    End With 

    'Check all row from bottom (so don't need to deal with row number changes after deletion) 
    For r = UBound(v) To LBound(v) Step -1 
     Select Case v(r, 1) 
     Case "30", "60", "90", "120", Empty 'Do nothing 
     Case Else 
      Sheet1.Rows(r + r_offset).EntireRow.Delete 
     End Select 
    Next 
    Application.ScreenUpdating = su 'Restore screen updating 
    Application.Calculation = cm 'Restore calculation mode 
End Sub 
0

Merci à tous ceux qui ont proposé des solutions. Entre temps j'ai fini par trouver un moyen de le faire en < 1 seconde - apparemment je ne me suis pas rendu compte que AutoFilter aurait pu supporter les critères de comparaison (plus grand que, moins que etc). En utilisant une série d'autofiltres, j'ai simplement filtré pour, puis supprimé toutes les lignes qui ont filtré à "< 30", "30120".

Pas élégant, mais il a fait l'affaire.

Questions connexes