Reputation: 637
I am trying to create a filter to remove rows that do not contain either one of the specified text. There are 3 situations and I am having some difficult in writing the last one (Point 3). (Excel version: 2010)
1. IF cell value = text THEN next row [complete]
2. IF cell value <> text THEN next text [complete]
3. IF cell value <> any of the text THEN delete row [not sure how to write this]
Sub Filter()
Dim i As Integer
Dim word(1 To 20) As String
Dim iRow As Integer, iCol As Integer
word(1) = "AA"
word(2) = "BB"
word(3) = "CC"
word(4) = "DD"
word(5) = "EE"
word(6) = "FF"
word(7) = "GG"
word(8) = "HH"
word(9) = "XXX"
iCol = ActiveCell.Column
For iRow = ActiveCell.End(xlDown).Row To 1 Step -1
For i = 1 To UBound(word)
If Cells(iRow, iCol).Value = word(i) Then
GoTo NextRow
Else
GoTo Nextword
End If
Nextword:
Next i
NextRow:
Next iRow
End Sub
Upvotes: 1
Views: 202
Reputation: 29421
beware relying on ActiveCell
, it may not be what you'd expect to: you'd much better reference the range you know you have to start from
anyhow, assuming your ActiveCell
is the header of a column with data following down below it, you could use AutoFilter()
and sort of a "inverse" of filtered cells
Option Explicit
Sub Filter()
Dim dataToKeep As Range
Dim iArea As Long
Dim words As Variant
words = Array("AA", "BB", "CC", "DD", "EE", "FF", "GG", "HH", "XXX")
With Range(ActiveCell, ActiveCell.End(xlDown))
.AutoFilter Field:=1, Criteria1:=words, Operator:=xlFilterValues
If Application.WorksheetFunction.Subtotal(103, .Cells) > 1 Then
Set dataToKeep = .SpecialCells(xlCellTypeVisible)
Else
.Offset(1).Resize(.Rows.Count - 1).EntireRow.Delete
End If
.Parent.AutoFilterMode = False
End With
If Not dataToKeep Is Nothing Then
With dataToKeep.Areas
If Intersect(.Item(.Count), ActiveCell.End(xlDown)) Is Nothing Then .Parent.Parent.Range(.Item(.Count).Cells(.Item(.Count).Rows.Count, 1).Offset(1), ActiveCell.End(xlDown)).EntireRow.Delete
For iArea = .Count To 2 Step -1
.Parent.Parent.Range(.Item(iArea).Cells(1, 1).Offset(-1), .Item(iArea - 1).Cells(.Item(iArea - 1).Rows.Count, 1).Offset(1)).EntireRow.Delete
Next
End With
End If
End Sub
Upvotes: 2
Reputation: 23974
Just keep a Boolean
variable saying whether you have matched any of the words:
Sub Filter()
Dim i As Integer
Dim word(1 To 20) As String
Dim iRow As Integer, iCol As Integer
Dim Matched As Boolean
word(1) = "AA"
word(2) = "BB"
word(3) = "CC"
word(4) = "DD"
word(5) = "EE"
word(6) = "FF"
word(7) = "GG"
word(8) = "HH"
word(9) = "XXX"
iCol = ActiveCell.Column
For iRow = ActiveCell.End(xlDown).Row To 1 Step -1
Matched = False
For i = 1 To UBound(word) ' Note: This is 1 To 20, not 1 To 9
' positions 10 To 20 still exist even though
' they have not been assigned a value
If Cells(iRow, iCol).Value = word(i) Then
Matched = True
Exit For
End If
Next i
If Not Matched Then
Rows(iRow).Delete
End If
Next iRow
End Sub
Upvotes: 3