我正在尝试编写一个函数,该函数根据调用函数的位置动态生成一个范围。然后它应该从该范围的顶部进行迭代,寻找与调用函数的行开头的字符串匹配的字符串。当字符串匹配时,它会将两列的值添加到总和。一旦它迭代了范围,它就应该终止。
这里我有两个几乎可以工作的解决方案。两者都在执行求和的代码上失败,但是否则完全正常。我已经评论了每个失败的地方。
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):
https://i.stack.imgur.com/CMHEz.png
错误:“有一个或多个循环引用,其中公式直接或间接引用其自己的单元格。这可能导致它们计算错误。尝试删除或更改这些引用,或将公式移动到不同的单元格”我想解决方案可能是,如果有一种方法可以将范围向左移动一列,那么函数不会迭代过来? (这仍然包括进行计算的所有必要单元格)
答案 0 :(得分:0)
我似乎.FindNext
在UDF
的上下文中无法使用。这并不奇怪;因为.FindNext
需要依赖记忆和更新某些状态"在工作表上,不允许UDF更改状态。
但是,用另一个.Find
解决这个问题似乎可以解决这个问题。此外,我注意到你迭代匹配的方式并不准确。您的代码可以像这样重写:
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