find一切不是
我们的一个客户给我发送了这个巨大的 excel文件,我的任务之一就是构build一个能清理less量数据的macros。 现在,我find了一个excellent example
,其中一个用户build议使用Excel查找方法来加快这个过程… BTW是完美的工作。
但是 ,在我的情况下,我想保持匹配的行,并删除其余的。 我如何在VBA中做到这一点? 例如,他们在说什么
Set rFound = .Columns(1).Find(What:="Cat", After:=.Cells(1, 1), LookIn:=xlValues, LookAt:=...)
我怎样才能将“什么”的值设置为“不”? 我尝试了几个不同的东西,如:
- 昏暗的猫作为string|| 猫=“猫”|| 设置notCat <>猫…..什么:= notCat
- DIM notCat <>“猫”…..什么:= notCat
- 什么:<> “猫”
- 什么:=“<>”&猫 … { 我不知道他们为什么这样build议,它只是将string从'猫'改为'<>猫'…我认为是错误的 }
这可能是一个非常愚蠢的问题…但我只是无法find正确的答案,并感到非常沮丧:(任何帮助将不胜感激!
With ActiveSheet.Range(Range("A1"), Cells(Rows.Count, 1).End(xlUp)) .AutoFilter Field:=1, Criteria1:="<>cat" .Offset(1, 0).SpecialCells(xlCellTypeVisible).EntireRow.Delete .AutoFilter End With
根据我上面的评论,还有@TimWilliams的回答,我认为AutoFilter
可能是这样做的方式。
我一直忘记Excel没有范围Difference
方法(与Intersect
相反,但这并不意味着你不能用一些UDF创造性的类似逻辑。
看看Chip Pearson出色的FindAll
方法 。 通常,Excel的.Find
方法只返回一个单元格区域(或Nothing
)。 这对于你的问题并不是特别有用,因为它需要你做一个笨重的迭代和FindNext
直到你用尽了这个范围。
使用FindAll
方法返回所有匹配单元格的范围。 然后,我们可以遍历列中的单元格,并testing它们是否与FindAll
方法返回的范围相交。 如果它们不相交,那么就没有匹配,所以我们可以删除这一行。
Sub TestFindAll() Dim ws As Worksheet Dim col As Range Dim allFound As Range Dim c As Long Dim cl As Range Set ws = ActiveSheet Set col = Intersect(ws.Columns(1), ws.UsedRange) Set allFound = FindAll(col, "Cat", xlValues, xlPart) For c = col.Cells.Count To 1 Step -1 Set cl = col.Cells(c) If Intersect(allFound, cl) Is Nothing Then 'cl.Interior.ColorIndex = 39 '## I use this line for debugging cl.EntireRow.Delete End If Next End Sub 'http://www.cpearson.com/excel/findall.aspx Function FindAll(SearchRange As Range, _ FindWhat As Variant, _ Optional LookIn As XlFindLookIn = xlValues, _ Optional LookAt As XlLookAt = xlWhole, _ Optional SearchOrder As XlSearchOrder = xlByRows, _ Optional MatchCase As Boolean = False, _ Optional BeginsWith As String = vbNullString, _ Optional EndsWith As String = vbNullString, _ Optional BeginEndCompare As VbCompareMethod = vbTextCompare) As Range ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' FindAll ' This searches the range specified by SearchRange and returns a Range object ' that contains all the cells in which FindWhat was found. The search parameters to ' this function have the same meaning and effect as they do with the ' Range.Find method. If the value was not found, the function return Nothing. If ' BeginsWith is not an empty string, only those cells that begin with BeginWith ' are included in the result. If EndsWith is not an empty string, only those cells ' that end with EndsWith are included in the result. Note that if a cell contains ' a single word that matches either BeginsWith or EndsWith, it is included in the ' result. If BeginsWith or EndsWith is not an empty string, the LookAt parameter ' is automatically changed to xlPart. The tests for BeginsWith and EndsWith may be ' case-sensitive by setting BeginEndCompare to vbBinaryCompare. For case-insensitive ' comparisons, set BeginEndCompare to vbTextCompare. If this parameter is omitted, ' it defaults to vbTextCompare. The comparisons for BeginsWith and EndsWith are ' in an OR relationship. That is, if both BeginsWith and EndsWith are provided, ' a match if found if the text begins with BeginsWith OR the text ends with EndsWith. ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' Dim FoundCell As Range Dim FirstFound As Range Dim LastCell As Range Dim ResultRange As Range Dim XLookAt As XlLookAt Dim Include As Boolean Dim CompMode As VbCompareMethod Dim Area As Range Dim MaxRow As Long Dim MaxCol As Long Dim BeginB As Boolean Dim EndB As Boolean CompMode = BeginEndCompare If BeginsWith <> vbNullString Or EndsWith <> vbNullString Then XLookAt = xlPart Else XLookAt = LookAt End If ' this loop in Areas is to find the last cell ' of all the areas. That is, the cell whose row ' and column are greater than or equal to any cell ' in any Area. For Each Area In SearchRange.Areas With Area If .Cells(.Cells.Count).Row > MaxRow Then MaxRow = .Cells(.Cells.Count).Row End If If .Cells(.Cells.Count).Column > MaxCol Then MaxCol = .Cells(.Cells.Count).Column End If End With Next Area Set LastCell = SearchRange.Worksheet.Cells(MaxRow, MaxCol) On Error GoTo 0 Set FoundCell = SearchRange.Find(what:=FindWhat, _ after:=LastCell, _ LookIn:=LookIn, _ LookAt:=XLookAt, _ SearchOrder:=SearchOrder, _ MatchCase:=MatchCase) If Not FoundCell Is Nothing Then Set FirstFound = FoundCell Do Until False ' Loop forever. We'll "Exit Do" when necessary. Include = False If BeginsWith = vbNullString And EndsWith = vbNullString Then Include = True Else If BeginsWith <> vbNullString Then If StrComp(Left(FoundCell.Text, Len(BeginsWith)), BeginsWith, BeginEndCompare) = 0 Then Include = True End If End If If EndsWith <> vbNullString Then If StrComp(Right(FoundCell.Text, Len(EndsWith)), EndsWith, BeginEndCompare) = 0 Then Include = True End If End If End If If Include = True Then If ResultRange Is Nothing Then Set ResultRange = FoundCell Else Set ResultRange = Application.Union(ResultRange, FoundCell) End If End If Set FoundCell = SearchRange.FindNext(after:=FoundCell) If (FoundCell Is Nothing) Then Exit Do End If If (FoundCell.Address = FirstFound.Address) Then Exit Do End If Loop End If Set FindAll = ResultRange End Function