Excel中的VBA搜索多个选项卡上的字符串并返回位置
我已经形成了代码进行搜索的问题是试图让它找到多个结果。当前,它将返回每个选项卡上字符串的第一个位置,但随后将继续。当我实现当前注释掉的While循环时,它似乎找到了第一个结果,然后转义循环 我不确定VBA循环是否有我遗漏的怪癖,或者我的while检查不太正确,但我尝试过通过分解它并使用消息框进行调试,但除了缩小我认为while循环代码中存在的问题之外,没有任何效果Excel中的VBA搜索多个选项卡上的字符串并返回位置,excel,excel-2010,vba,Excel,Excel 2010,Vba,我已经形成了代码进行搜索的问题是试图让它找到多个结果。当前,它将返回每个选项卡上字符串的第一个位置,但随后将继续。当我实现当前注释掉的While循环时,它似乎找到了第一个结果,然后转义循环 我不确定VBA循环是否有我遗漏的怪癖,或者我的while检查不太正确,但我尝试过通过分解它并使用消息框进行调试,但除了缩小我认为while循环代码中存在的问题之外,没有任何效果 Public Function GetSearchArray(strSearch As String) As String Dim
Public Function GetSearchArray(strSearch As String) As String
Dim strResults As String
Dim SHT As Worksheet
Dim rFND As Range
Dim sFirstAddress As Range
For Each SHT In ThisWorkbook.Worksheets
'MsgBox "Looping over worksheets"
Set rFND = Nothing
With SHT.UsedRange
'MsgBox "Searching for" & strSearch
Set rFND = .Cells.Find(What:="*" & strSearch & "*", LookIn:=xlValues, LookAt:=xlPart, SearchOrder:=xlRows, SearchDirection:=xlNext, MatchCase:=False)
If Not rFND Is Nothing Then
'Save first result so we can exit the loop
If sFirstAddress Is Nothing Then
MsgBox "We have a result and sFirstAddress is nothing"
Set sFirstAddress = rFND
End If
'Need to loop within the sheet to keep finding results
'While (Not rFND Is Nothing) And rFND <> sFirstAddress
'Deal with the results and build a string
If strResults = "" Then
'MsgBox "No prev results"
strResults = "Worksheet(" & SHT.Index & ").Range(" & Chr(34) & rFND.Address & Chr(34) & ")"
MsgBox "First result " & strResults
Else
strResults = strResults & "|" & "Worksheet(" & SHT.Index & ").Range(" & Chr(34) & rFND.Address & Chr(34) & ")"
MsgBox strResults
End If
Set rFND = .FindNext(rFND)
'Wend
End If
End With
MsgBox "End sheet loop.."
Next
MsgBox "Finished going over sheets"
MsgBox strResults
End Function
公共函数GetSearchArray(strSearch作为字符串)作为字符串
作为字符串的Dim strresult
将SHT变暗为工作表
弱rFND As范围
Dim sFirstAddress作为范围
用于此工作簿中的每个SHT。工作表
“MsgBox”在工作表上循环
设置rFND=Nothing
使用SHT.UsedRange
“MsgBox”正在搜索“&strSearch”
Set rFND=.Cells.Find(What:=“*”&strearch&“*”,LookIn:=xlValues,LookAt:=xlPart,SearchOrder:=xlRows,SearchDirection:=xlNext,MatchCase:=False)
如果不是,那么rFND什么都不是
'保存第一个结果,以便退出循环
如果sFirstAddress不算什么,那么
MsgBox“我们有一个结果,sFirstAddress什么都不是”
设置sFirstAddress=rFND
如果结束
'需要在工作表中循环以不断查找结果
'While(非rFND为Nothing)和rFND sFirstAddress
'处理结果并生成字符串
如果strResults=“”,则
'MsgBox“没有上一个结果”
strResults=“工作表(“&SHT.Index&”)范围(“&Chr(34)&rFND.Address&Chr(34)&”)”
MsgBox“第一个结果”和strResults
其他的
strResults=strResults&“|”和“工作表(&SHT.Index&”)范围(&Chr(34)&rFND.Address&Chr(34)&”)
MsgBox strResults
如果结束
设置rFND=.FindNext(rFND)
“温德
如果结束
以
MsgBox“结束页循环…”
下一个
MsgBox“已完成检查表单”
MsgBox strResults
端函数
您需要循环回到Set rFND=.Cells.Find(What:=“*”&strearch&“*”,LookIn:=xlValues,LookAt:=xlPart,SearchOrder:=xlRows,SearchDirection:=xlNext,MatchCase:=False)
代码到达之前的行,而循环,目前不会发生,并且rFND始终等于sFirstAddress
我不确定存储地址结果并在循环时检查它们的最有效方法,但我相信有人可以帮助您完成最后一部分。我认为应该将每个结果存储在一个数组中,并对照数组检查每个新结果,直到没有找到新结果,然后转到下一页
您可能还必须将Find命令更改为从上次找到的结果开始,如果它每次都在同一个位置开始,我认为它会一次又一次地找到相同的结果。我不确定,我没有找到太多。像这样的东西应该适合你:
Public Function GetSearchArray(strSearch As String) As String
Dim ws As Worksheet
Dim rngFound As Range
Dim strFirst As String
Dim strWSname As String
For Each ws In ActiveWorkbook.Sheets
Set rngFound = ws.UsedRange.Find(strSearch, ws.UsedRange.Cells(ws.UsedRange.Cells.Count), xlValues, xlPart)
If Not rngFound Is Nothing Then
strWSname = ws.Name
If InStr(1, ws.Name, " ", vbTextCompare) > 0 Then strWSname = "'" & strWSname & "'"
strFirst = rngFound.Address
Do
GetSearchArray = GetSearchArray & "|" & strWSname & "!" & rngFound.Address
Set rngFound = ws.UsedRange.Find(strSearch, rngFound, xlValues, xlPart)
Loop While rngFound.Address <> strFirst
End If
Next ws
If Len(GetSearchArray) > 0 Then GetSearchArray = Mid(GetSearchArray, 2)
End Function
不While循环将被完全跳过。(非rFND即无)
部分将得到满足,但rFND sFirstAddress
将不会得到满足。你在它们之间使用了和
,因此因为两者都不满意,它直接转到WEnd并继续。哈,对不起,你的无限循环问题消失了,你一定找到了答案:)对不起,我意识到我的评论不正确,所以删除了它。如你所说。:)我想我会改变代码的工作方式。在上一次迭代中,我只是在一张表中查找外观的计数。我想我会合并这个,然后调用find x多次,而不是上面的while循环。看起来这样可以工作。祝你好运对不起,还没有人告诉你一个有效的方法。当你改变你的问题时,我建议保留旧代码,把你的新试用版放在下面,以防有人能让While循环比Count循环工作得更好。这正是我想要的。一个扩展-如何从单元格调用它并将输出返回到单元格中?我尝试了调用重写的第二个函数,但它不起作用。在一个单元格中:=GetSearchArray(“test”)
如果你想用“|”以外的东西来分隔结果,你可以使用替换项,比如:=SUBSTITUTE(GetSearchArray(“test”),“|”,”,”)
嗯,我试过了,但单元格只是出错并显示了#值!我试着通过按Ctr+Shift+Enter来确保它是一个数组公式,但运气不好。结果表明,在UDF中不能使用Range.FindNext
方法,这就是导致问题的原因。我使用了一个带有Range.Find
方法的替代方法,然后为我成功地测试了它。请参阅更新的答案
Sub tgr()
MsgBox Replace(GetSearchArray("test"), "|", Chr(10))
End Sub