从Excel VBA UDF调用时,Range.Preferences返回范围,而不是其前导。有解决办法吗?

从Excel VBA UDF调用时,Range.Preferences返回范围,而不是其前导。有解决办法吗?,excel,vba,excel-2007,user-defined-functions,Excel,Vba,Excel 2007,User Defined Functions,我有这个VBA功能: Public Function testPrec(target As Range) As String testPrec = target.Precedents.Address(External:=False) End Function 在单元格C11中,我有以下公式: =C6+C8 如果我从即时窗口调用testPrec,它工作正常: ?testPrec([c11]) $C$6,$C$8 编辑:如果从非UDF宏子对象调用,它也可以正常工作。异常情况是UDF情况

我有这个VBA功能:

Public Function testPrec(target As Range) As String
    testPrec = target.Precedents.Address(External:=False)
End Function
在单元格C11中,我有以下公式:

=C6+C8
如果我从即时窗口调用
testPrec
,它工作正常:

?testPrec([c11])
$C$6,$C$8
编辑:如果从非UDF宏子对象调用,它也可以正常工作。异常情况是UDF情况

如果我从工作表中将其称为自定义项:

=testPrec(C11)
我刚拿回来“$C$11”


有人知道发生了什么,或者更好地知道如何从UDF调用中获得实际的先例吗?(我使用的是Excel 2007。)

我能想到的唯一解决办法是获取target.formula并对其进行解析-这不是很好。

约束似乎在于,在包含UDF的调用堆栈中,对
的任何调用都会得到不同的处理。因此,找到一种在UDF触发的调用堆栈之外进行调用的方法:一种想法是使用事件。下面是一个过于简单化的例子

在模块中定义

Public strPrecedent As String
Public rngPrecedent As Range

Public Function testPrec(target As Range) As String
    Set rngPrecedent = target
    testPrec = strPrecedent
End Function
在图纸中定义

Private Sub Worksheet_Calculate()
    If Not Module1.rngPrecedent Is Nothing Then
        Module1.strPrecedent = Module1.rngPrecedent.Precedents.Address(External:=False)
    End If
End Sub

testPrec
现在返回正确的范围地址,尽管晚了一次。其思想是让UDF构建一个地址列表来获取先例,并创建一个事件来执行实际的GetPrevention工作,将地址字符串返回到列表以供UDF拾取。根据您的需要,您可能可以从中构建一个可行的解决方案。

我遇到了一个类似的问题:我必须根据单元格是否包含公式或常量值来设置单元格格式
HasFormula
可以确定单元格是否包含公式,但是,简单的计算,如
=123+45
也被检测为公式(从技术角度正确,但从金融建模角度错误)。因此,我想在UDF中使用
前导词
,以查看给定的单元格是否链接到其他单元格。如上所述,在执行UDF期间,
先例
的值无效,但我只需要知道是否存在先例,而不需要知道它们是哪些单元格

因此,我比较了
公式
公式1c1
属性,因为它们只有在
公式
包含单元格引用的情况下才不同


有一个例外:如果
公式
包含命名范围,则
公式
公式1c1
可以相等,即使单元格引用了某些内容。(这与我的情况无关,我不想重复所有名称并检查它们是否包含在
公式
的外部引号中。

我确实在Charles Williams的优秀网站()上找到了这一点():“你不能制作一个直接使用…先例的VBA UDF”。但是,我尝试获取一个
范围的先例,而不是调用UDF的范围的先例-即获取UDF参数的先例。这不会终止UDF调用;它只返回参数,而不是其先例。再仔细研究一下,我注意到这会发生在任何范围,而不仅仅是UD的参数F.I.e.一个硬编码函数,返回
[c11]。先例。地址
也只返回“$C$11”当从thw工作表中调用时。我讨厌调用类似这样的错误,因为这不是
先例的真正用途,但它太烦人了,没有记录在案…+1个很好的问题。处理先例,尤其是表外先例,是一个相当神秘的过程。@brettdj:谢谢。非常小的问题,但你的投票结果显示出来了吗在正确的地方?看:你是对的。我对查尔斯的答案投了高票,还以为我也对你的问题投了高票,但在重温这一点时,这显然并没有按预期发生。莫纠正了。是的,这也是我所想的。在这种情况下,这是不值得的。对于UDF的一个实例来说,这是一个好方法,但对于多个实例来说,这会变得混乱从相同或不同的工作表/工作簿调用UDF在这种情况下,我真正想要的是一个单元格的前例地址,但从UDF调用返回。任何更复杂的东西对我来说都是不值得的。但你是对的,这样的东西一般都会起作用。@Charles答案是一个简单的例子一个完整的解决方案必须管理一个列表(数组、集合或其他)由UDF引用的单元格。当然有点复杂,但它是一个可行的解决方案,让我们称之为excel的未记录功能。最终由用户决定是否值得为当前任务付出努力hand@chrisneilsen在Excel2007中测试这一点时,我发现即使在建议的事件中,依赖项和先例也不包括在内lude cross sheet cells,ever:-(虽然问题中没有提出,但这不处理交叉表公式这一事实是非常有价值的信息。