我试图在递归函数中使用.Find
函数在工作表中找到行号。
我设置了一个名为Found = .Find....
的对象,它的效果很好......一点点。我在深度递归1级时设置它,然后在我2级深度时再次设置它。然后,我的代码找到路径的结尾并开始备份,直到它回到1级深,但不是我的Found对象已被重新声明并保持其值从第二级。我的其他变量(ThisRow等...)保持它们所处的级别的值,这就是我想要对象Found所做的事情。有没有办法可以在本地声明Found,以便它的值不会扩展到下一个函数,并且不能在更深层次上覆盖?您可以在下面找到我的代码以供参考。
这是我目前的代码 - 不相关的部分:
Public Function FindChildren()
ThisRow = AnswerRow 'Also declared before function call
BeenHereCell = Cells(ThisRow, "O").Address
If Range(BeenHereCell).Value = "Yes" Then
Exit Function 'That means we've already been there
End If
Range(BeenHereCell).Value = "Yes"
With Worksheets("MasterScore").Range("j1:j50000")
Set Found = .Find(NextQuestionID, LookIn:=xlValues)
If Not Found Is Nothing Then
firstAddress = Found.Address
NextCell = Found.Address
Do
AnswerRow = Range(NextCell).Row
FindChildren 'This is where it's recursive.
Set Found = .FindNext(Found)
NextCell = Found.Address
Loop While Not Found Is Nothing And Found.Address <> firstAddress
End If
End With
End Function
现在我通过激活单元来解决它,但它使我的代码慢了很多。目前我正在使用这个:
Set Found = Worksheets("MasterScore").Range("j1:j50000").Find(NextQuestionID, LookIn:=xlValues)
If Not Found Is Nothing Then
Count = 1
Do
Columns("J:J").Select
FirstFoundRow = Selection.Find(What:=NextQuestionID, After:=ActiveCell, LookIn:= _
xlFormulas, LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:= _
xlNext, MatchCase:=False, SearchFormat:=False).Row
For i = 1 To Count
Selection.FindNext(After:=ActiveCell).Activate
Next i
AnswerRow = ActiveCell.Row
If AnswerRow = FirstFoundRow And Count <> 1 Then Exit Do
FindChildren
Count = Count + 1
Loop
End If
这样,我不必再次设置对象的值,但我必须遍历it.FindNext很多次,并且每次运行该行时它也会激活该行。我真的只想要类似的东西。
AnswerRow = .Find(nth instance of NextQuestionID).Row
(我有大约5万行,计数经常大约20,所以它真的需要一段时间)。
我很感激任何想法!目前我的代码正在运行,但是需要很长一段时间才能完成,我需要在某个时候再次运行它!
答案 0 :(得分:0)
我最终找到了一种方法来加快它的速度。我认为这可以帮助别人,所以我将分享我发现的东西。 这不是最好的解决方案(我本来希望只在本地声明对象,这样我的其他函数就不会改变它的值),但至少在这种情况下,我不会循环20次左右找到Do循环的每次迭代。
Set Found = Worksheets("MasterScore").Range("j1:j50000").Find(NextQuestionID, LookIn:=xlValues)
If Not Found Is Nothing Then
NextAnswerRange = "j" & 1 & ":" & "j50000" 'The first search will be from the beginning
Do
Set Found = Worksheets("MasterScore").Range(NextAnswerRange).Find(NextQuestionID, LookIn:=xlValues)
NextCell = Found.Address
AnswerRow = Range(NextCell).Row
NextAnswerRange = "j" & AnswerRow & ":" & "j50000"
If LastAnswerRange = NextAnswerRange Then Exit Function 'This would mean we've reached the end.
LastAnswerRange = NextAnswerRange
FindChildren
Loop
End If
结束功能
所以我们知道我们已经覆盖了以前范围的基础,因为它总能找到下一个范围。我们每次只更改搜索范围,它会找到下一个值。
这个解决方案的一个奇怪的事情是,如果你正在寻找范围70中的值 - &gt; 50,000你得到你在第70行寻找的答案,它实际上会找到下一行(它跳过第一行)。但是,如果没有任何超过70的行有答案,它实际上会从第70行获取值。这意味着我无法做到
NextAnswerRange = "j" & AnswerRow + 1 & ":" & "j50000"
因为它会错过一些值。如果没有+ 1意味着在文档的最后我会一遍又一遍地搜索相同的最后一个值(它永远不会回到Found Is Nothing)所以我必须检查以查看LastAnswerRange = NextAnswerRange。
我希望这有助于某人。我认为这不是最优雅的解决方案,但它比我的速度快得多。