问题描述
我有一个大型数据表,我想根据 3 组条件在 VBA 中进行搜索.可以假设每个行条目都是唯一的.表格/数据本身的格式不能因要求而改变.(我已经看过几篇关于相关问题的帖子,但还没有找到一个可行的解决方案.)
I have a large data sheet that I want to search in VBA based on 3 sets of criteria. Each row entry can be assumed to be unique. The format of the sheet/data itself cannot be changed due to requirements. (I've seen several posts on related questions but haven't found a working solution for this yet.)
起初我使用了经典的 VBA find 方法一个循环:
At first I used the classic VBA find method in a loop:
Set foundItem = itemRange.Find(What:=itemName, Lookin:=xlValues, lookat:=xlWhole, SearchOrder:=xlByRows)
If Not foundItem Is Nothing Then
firstMatchAddr = foundItem.Address
Do
' *Check the other fields in this row for a match and exit if found*
Set foundItem = itemRange.FindNext(foundItem)
Loop While foundItem.Address <> firstMatchAddr And Not foundItem Is Nothing
End If
但是因为这需要在大量数据上多次调用,所以速度并不好.
But because this needs to be called a number of times on large sets of data, the speed of this was no good.
我做了一些搜索,发现我可以使用 匹配 带有 index 的方法.所以我尝试了很多变体都没有成功,例如:
I did some searching and found that I could use the match method with index. So I unsuccessfully tried many variations of that such as:
result = Evaluate("=MATCH(1, (""" & criteria1Name & """=A2:A" & lastRow & ")*(""" & criteria2Name & """=B2:B" & lastRow & ")*(""" & criteria3Name & """=C2:C" & lastRow & "), 0)")
和
result = Application.WorksheetFunction.Index(resultRange, Application.WorksheetFunction.Match((criteria1Name = criteria1Range)*(criteria2Name = criteria2Range)*(criteria3Name = criteria3Range))
和
result = Application.WorksheetFunction.Index(resultRange, Application.WorksheetFunction.Match((criteria1Range=criteria1Name )*(criteria2Range=criteria2Name )*(criteria3Range=criteria3Name ))
然后我尝试使用 AutoFilter 进行排序:>
Then I tried using AutoFilter to sort:
.Range(.Cells(1,1), .Cells(lastRow, lastCol)).AutoFilter Field:=1, Criteria1:="=" & criteria1Name
.Range(.Cells(1,1), .Cells(lastRow, lastCol)).AutoFilter Field:=2, Criteria1:="=" & criteria2Name
.Range(.Cells(1,1), .Cells(lastRow, lastCol)).AutoFilter Field:=3, Criteria1:="=" & criteria3Name
但是因为其中一个排序列包含日期,所以我在让自动筛选器正常工作时遇到了问题.
But because one of the sorting columns contains dates, I had issues getting AutoFilter to work properly.
我的问题是,如何根据多个条件在 Excel VBA 中搜索列,不循环,返回行号或我在该行的单元格中的值对感兴趣?
My question is, how can I search through columns in Excel VBA based on multiple criteria, without looping, returning either the row number or the value in the cell of that row that I am interested in?
推荐答案
您可以使用高级过滤器.将列标题放在工作表的单独部分(或完全不同的工作表).在这些列标题下,将您要查找的条件放在每列中.然后将该范围(包括标题)命名为标准".然后宏变成:
You could use an Advanced Filter. Put the column headers in a separate part of the sheet (or a different sheet altogether). Under those column headers, put the criteria you're looking for in each column. Then name that range (including the headers) something like "Criteria". Then the macro becomes:
Sub Macro1()
Sheets("Sheet1").Range("A1").CurrentRegion.AdvancedFilter xlFilterInPlace, Range("Criteria")
End Sub
作为下面我的评论的后续,让 VBA 在幕后创建标准范围:
As a follow up to my comment below, to have the VBA create the criteria range behind the scenes:
Sub Macro1()
'Code up here that defines the criteria
Application.ScreenUpdating = False
Application.DisplayAlerts = False
With Sheets.Add
'Create the advanced filter criteria range
.Range("A1") = "HeaderA"
.Range("B1") = "HeaderB"
.Range("C1") = "HeaderC"
.Range("A2") = criteria1Name
.Range("B2") = criteria2Name
.Range("C2") = criteria3Name
'Alternately, to save space:
'.Range("A1:C1").Value = Array("HeaderA", "HeaderB", "HeaderC")
'.Range("A2:C2").Value = Array(criteria1Name, criteria2Name, criteria3Name)
'Then perform the advanced filter
Sheets("Sheet1").Range("A1").CurrentRegion.AdvancedFilter xlFilterInPlace, .Range("A1:C2")
'Remove behind the scenes sheet now that the filter is completed
.Delete
End With
Application.ScreenUpdating = True
Application.DisplayAlerts = True
End Sub
这篇关于VBA (Excel):基于不循环的多个搜索条件查找的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!