10
votes

Façon efficace de supprimer la ligne entière si la cellule ne contient pas '@'

Je crée une solution rapide pour faire une vérification de la validité des emails. Je souhaite supprimer des lignes entières de données de contact qui ne contiennent pas de '@' dans la colonne "E". J'ai utilisé la macro ci-dessous, mais elle fonctionne trop lentement car Excel déplace toutes les lignes après la suppression.

J'ai essayé une autre technique comme ceci: Set RNG = Union (RNG, C.ENTREROW) et ensuite la suppression de toute la gamme, mais je ne pouvais pas empêcher les messages d'erreur.

J'ai également expérimenté simplement à ajouter chaque ligne à une sélection et, après que tout ait été sélectionné (comme dans Ctrl + Select). , le supprimant ensuite, mais je n'ai pas pu trouver la syntaxe appropriée pour cela.

Des idées? xxx


5 commentaires

Premièrement, limitez le nombre de cellules à traverser. I.e. Au lieu de Plage (E: E) , utilisez une plage avec des données dedans


Je me suis toujours demandé comment faire cela-- Comment puis-je sélectionner une plage qui inclut la première cellule jusqu'à la dernière cellule avec des données dedans?


rondebruin.nl/win/s4/win001.htm - Jetez un oeil à cette. Je suis sûr que cela vous répondra pour vous. Regd votre question, disons que vous êtes sur la cellule A1 contenant des données, appuyez maintenant sur Ctrl + Down Flèche. Cela sélectionnera toutes les cellules à partir de A1 jusqu'à la dernière cellule contenant des données (note: il ne devrait pas y avoir de cellules vides au milieu). Utilisation de VBA, vous pouvez LastCell = gamme ("A1"). Fin (XLDOWN)


Aussi - Ne supprimez pas. Éliminez la ligne, puis recourez la gamme à la fin


@ Fnostro- Toute références sur la façon de faire cela?


5 Réponses :


24
votes

Vous n'avez pas besoin d'une boucle pour faire cela. Un autofiltre est beaucoup plus efficace. (semblable au curseur vs. où la clause dans SQL)

autofiltre toutes les lignes qui ne contiennent pas "@", puis les supprimer comme ceci: xxx

Notes:

  • .Offset (1,0) nous empêche de supprimer la ligne de titre
  • .pecialcells (xlcelltyspevisible) Spécifie les lignes qui restent après que l'autofiltre ait été appliqué
  • .enTirerow.delete supprime toutes les lignes visibles, à l'exception de la ligne de titre

    traversez le code et vous pouvez voir ce que chaque ligne fait. Utilisez F8 dans l'éditeur VBA.


4 commentaires

Je reçois une erreur d'indice d'indice d'indice d'indice. Pourriez-vous expliquer deux choses? Qu'est-ce que 'Set Rng = Ws.Range ("A1: A" & Lastrow)? Pourquoi le "A1: A"? Et qu'est-ce que ".offset (1, 0) .Specialcells (xlcelltyspevisible) .entreprow.delete" faire?


Je viens de réaliser la colonne avec laquelle vous travaillez est E. L'erreur est parce que je recherche la mauvaise colonne. Changer "A" à "E", et cela devrait fonctionner. Réglage de la plage Spécifie la plage Nous allons à Autofilter (A1: A et quelle que soit la dernière ligne avec une valeur). Le .Offset (1,0) nous empêche de supprimer la ligne de titres.


Essayez-le maintenant - j'ai édité la colonne.


J'ai vu une autre réponse qui a copié les réponses filtrées à une feuille TEMP puis supprimée et copiée en arrière, mais en utilisant <> est beaucoup plus propre!



2
votes

Utilisation d'un exemple fourni par l'utilisateur Shahkalpeh, j'ai créé la macro suivante avec succès. Je suis toujours curieux d'apprendre d'autres techniques (comme celle référencée par Fnostro dans laquelle vous effacez le contenu, triez, puis supprimez). Je suis nouveau à VBA afin que tous les exemples seraient très utiles. xxx


1 commentaires

Bien fait pour obtenir le code de travail, mais dans la mesure du possible, évitez les boucles de portée - elles peuvent être très lentes sur des jeux de données plus importants. Utilisez autofilter , spécialcells ou des tableaux de variante si possible.



3
votes

Avez-vous essayé un simple filtre automatique à l'aide de " @ " comme des critères utilisez alors xxx

Remarque: il y a des astérisques avant et après le @ mais je n'ai pas 't sais comment les arrêter d'être analysé!


1 commentaires

Toutes mes excuses - votre réponse n'était pas là quand j'ai posté à l'origine. J'ai fait gâcher le critère cependant!



2
votes

Lorsque vous travaillez avec de nombreuses lignes et de nombreuses conditions, vous ferez mieux d'utiliser cette méthode de suppression de ligne

Option Explicit

Sub DeleteEmptyRows()
    Application.ScreenUpdating = False

    Dim ws As Worksheet
    Dim i&, lr&, rowsToDelete$, lookFor$

    '*!!!* set the condition for row deletion
    lookFor = "@"

    Set ws = ThisWorkbook.Sheets("Sheet1")
    lr = ws.Range("E" & Rows.Count).End(xlUp).Row

    ReDim arr(0)

    For i = 1 To lr
     If StrComp(CStr(ws.Range("E" & i).Text), lookFor, vbTextCompare) = 0 then
       ' nothing
     Else
        ReDim Preserve arr(UBound(arr) + 1)
        arr(UBound(arr) - 1) = i
     End If
    Next i

    If UBound(arr) > 0 Then
        ReDim Preserve arr(UBound(arr) - 1)
        For i = LBound(arr) To UBound(arr)
            rowsToDelete = rowsToDelete & arr(i) & ":" & arr(i) & ","
        Next i

        ws.Range(Left(rowsToDelete, Len(rowsToDelete) - 1)).Delete Shift:=xlUp
    Else
        Application.ScreenUpdating = True
        MsgBox "No more rows contain: " & lookFor & "or" & lookFor2 & ", therefore exiting"
        Exit Sub
    End If

    If Not Application.ScreenUpdating Then Application.ScreenUpdating = True
    Set ws = Nothing
End Sub


1 commentaires

Sélectionnez ralentit n'importe quel code et doit toujours être évité. Je doute que cela puisse aborder l'efficacité du filtre.



0
votes

au lieu de boucler et référencer chaque cellule 1 par 1, prenez tout et mettez-la dans une variante de réseau; Ensuite, bouclez le tableau de variante.

Démarreur: P>

Sub DeleteRowsWithValue(Value As String, Column As Long, StartingRow As Long, Optional Sheet)
Dim i As Long, LastRow As Long
Dim vData() As Variant
Dim DeleteAddress As String

    ' Sheet is a Variant, so we test if it was passed or not.
    If IsMissing(Sheet) Then Set Sheet = ActiveSheet
    ' Get the last row
    LastRow = Sheet.Cells(Sheet.Rows.Count, Column).End(xlUp).Row
    ' Make sure that there is work to be done
    If LastRow < StartingRow Then Exit Sub

    ' The Key to speeding up the function is only reading the cells once 
    ' and dumping the values to a variant array, vData
    vData = Sheet.Cells(StartingRow, Column) _
                 .Resize(LastRow - StartingRow + 1, 1).Value
    ' vData will look like vData(1 to nRows, 1 to 1)
    For i = LBound(vData) To UBound(vData)
        ' Find the value inside of the cell
        If InStr(vData(i, 1), Value) > 0 Then
            ' Adding the StartingRow so that everything lines up properly
            DeleteAddress = DeleteAddress & ",A" & (StartingRow + i - 1)
        End If
    Next
    If DeleteAddress <> vbNullString Then
        ' remove the first ","
        DeleteAddress = Mid(DeleteAddress, 2)
        ' Delete all the Rows
        Sheet.Range(DeleteAddress).EntireRow.Delete
    End If
End Sub


0 commentaires