Excel UDF-自动运行时的结果与遍历时的结果不同

Excel UDF-自动运行时的结果与遍历时的结果不同,excel,user-defined-functions,vba,Excel,User Defined Functions,Vba,我已将以下自定义项保存到工作簿的一个模块中: Function sumAbove2(myCell As Range) Dim rng As Range, cel As Range Dim topRow As Long topRow = myCell.Offset(0, -2).End(xlUp).Row Dim sRng As Range, eRng As Range Set sRng = Cells(myCell.Row, myCell.Column) Set eRng = Cells(to

我已将以下自定义项保存到工作簿的一个模块中:

Function sumAbove2(myCell As Range)

Dim rng As Range, cel As Range
Dim topRow As Long
topRow = myCell.Offset(0, -2).End(xlUp).Row
Dim sRng As Range, eRng As Range
Set sRng = Cells(myCell.Row, myCell.Column)
Set eRng = Cells(topRow, myCell.Column)

For Each cel In Range(sRng, eRng)
    Debug.Print cel.Address
    sumAbove2 = cel.Value + sumAbove2
Next cel

End Function
其思想是自动对信息的“块”求和

当我使用
F8
遍历UDF时,它工作得很好。但是,当自动运行时,它可能会产生意外的结果。令人恼火的是,我把这段代码放在了一个全新的工作簿中,加入了示例数据,但它从未产生错误的结果……为此,我向我的朋友们道歉,我无法让它重现。我对UDF比较陌生,所以可能缺少一些运行它们的关键点(波动性是否有帮助/伤害?)

当我这样做的时候,两秒钟后,在宏中断的情况下,我可以用F8单步执行,它正确地不添加任何内容,并返回
0

会发生什么事?我没有在代码中指定工作表,但我不明白为什么会这样做。这可能与页面上的其他公式有关吗?没有工作表更改事件等

编辑:工作簿有几个工作表,这些工作表中有公式。但是我运行这个的工作表都是文本,保存我试图输入的公式。只是想提一下,以防格式化中的某些内容可能会导致奇怪的行为。

我将1)稍微简化代码(您不使用
rng
变量,也不需要在单独的变量中使用开始行和结束行范围),2)定义要返回的数据类型,3)使用完全限定的引用和4)通过以下方式添加数字检查:

Function sumAbove2(myCell As Range) As Double

    Dim actSht As Excel.Worksheet
    Dim topRow As Long
    Dim cel As Range, searchRng As Range

    topRow = myCell.Offset(0, -2).End(xlUp).Row

    Set actSht = ActiveSheet
    With actSht
        Set searchRng = .Range(.Cells(myCell.Row, myCell.Column), .Cells(topRow, myCell.Column))
    End With

    For Each cel In searchRng
        If IsNumeric(cel.Value) Then sumAbove2 = cel.Value + sumAbove2
    Next cel

End Function

对我来说,似乎工作完美无瑕。

您需要用正确的工作表完全限定您的所有范围

Function sumAbove2(myCell As Range)

    Dim sht As Worksheet '<<<
    Dim rng As Range, cel As Range
    Dim topRow As Long
    Dim sRng As Range, eRng As Range

    Set sht = myCell.Worksheet '<<<

    topRow = myCell.Offset(0, -2).End(xlUp).Row

    Set sRng = sht.Cells(myCell.Row, myCell.Column) '<<<
    Set eRng = sht.Cells(topRow, myCell.Column)     '<<<

    For Each cel In sht.Range(sRng, eRng) '<<<
        Debug.Print cel.Address
        sumAbove2 = cel.Value + sumAbove2
    Next cel

End Function

第2列中的值是否用公式过度填充?@ScottCraner-Nope,所有信息。是文本(格式为“常规”)。唯一的公式是我正在尝试使用的“上面的总和”公式。您的函数需要是可变的,当它计算时,它将根据当时的活动工作表进行计算。UDF确实应该接受它所需的所有范围作为直接参数。如果您选择两列中的单元格并按Ctrl-Up,它是否比您预期的更进一步?请想一想:尝试一下,并使用
myCell.Parent.Cells完全限定您的代码(…
。关于
应用程序.Volatile
我想指出的是,这只会确保每次在工作表上更改值时重新计算公式。否则,如果值(应求和),则公式可能会提供不正确的结果正在更改。当然,要使其正常工作,您需要将文件设置为
Application.Calculation=xlCalculationAutomatic
。谢谢-我尝试了它,它对我也有同样的作用!我自动运行它,但得到的结果不正确。当我逐步执行它时,我得到了正确的结果…嗯。这似乎有些牵强,但你没有ried重新启动?在非常罕见的情况下,我曾体验到Excel应用程序出现故障,因为Windows中出现了暂时性的错误。不再有什么牵强的事情发生了!我尝试重新启动,出现了相同的问题:/n当包含公式的工作表不是活动工作表时,这将给出错误的结果。@BruceWayne有关工作簿的行为不稳定,我的最佳猜测是您的工作簿或Excel应用程序不知何故已损坏。1)在另一台计算机上测试工作簿。如果问题仍然存在:2)作为最后手段,我会尝试在一个新的工作簿中运行代码,然后一步一步地重新创建旧工作簿,直到我能够指出问题所在。(如果问题消失,则工作簿已损坏),如果旧工作簿很大,这显然是一项艰巨的任务,但如果其他所有操作都失败,这可能是您的最佳选择。嘿,蒂姆-谢谢。我完全合格了他们,但仍然得到了意想不到的结果。我现在将重点看一下工作表/工作簿中导致这种情况的一些古怪的代码/格式。不过非常感谢,它恢复了排位赛范围的重要性(我通常非常渴望这样做,我只是忘了在这里)。当我将其作为唯一的宏运行时,它返回
#VALUE
error。当我一步一步通过它时,它正确地给出了准确的总数。所以,书中有些东西很古怪。
Sub Tester()
    Debug.Print sumAbove2(Activesheet.Range("C44"))
End sub