9

我正在编写的 Excel/VBA 类中的一个属性返回一个范围。我使用http://www.cpearson.com/excel/DefaultMember.aspx中描述的技术将其设为该类的默认属性。我希望将 Range 类的所有内置属性和方法与我的类的对象一起使用,而无需明确指定属性。它不起作用。这里有几个更简单的类来说明。(这些清单是使用文本编辑器查看的导出源代码,因为 VBA 的编辑器隐藏了 Attribute 语句。)

' clsDefLong:    This class just verifies that default properties work as I expected.
Public Property Get DefProp() As Long
Attribute DefProp.VB_UserMemId = 0
    DefProp = 125
End Property

' clsDefRange:  This class is identical except the default property returns a Range.
Public Property Get DefProp() As Range
Attribute DefProp.VB_UserMemId = 0
    Set DefProp = ActiveCell
End Property

这是一个普通模块中的 Sub 用于实例化和测试类。评论表明当我单步执行时会发生什么:

Sub DefTest()
    Dim DefRange As New clsDefRange, DefLong As New clsDefLong
    Debug.Print DefLong.DefProp         '(1) Displays 125. Verifies the class behaves as intended.
    Debug.Print DefLong                 '(2) Same as (1). Verifies VBA uses the DefProp property as the default.
    Debug.Print DefRange.DefProp.Value  '(3) Displays the ActiveCell content. Verifies that this class works as intended.
    Debug.Print DefRange.DefProp        '(4) Same as (3). Verifies VBA knows DefProp returns a Range without further prompting.
    Debug.Print DefRange                '(5) Aborts with the messge "Run-time error '13': Type mismatch"
 End Sub

为什么语句 (5) 中的 DefRange 的行为不像语句 (4) 中的 DefRange.DefProp?

如果我将语句 (5) 更改为:

Debug.Print DefRange.Cells(1, 1) 

编译器选择“.Cells”,说“编译错误:未找到方法或数据成员”并停止,因此问题出在对象模型中 - 而不仅仅是在运行时搞砸了。难道我做错了什么?还是不可能有一个返回范围的默认属性?其他内置类呢?用户定义的类?

4

1 回答 1

5
Debug.Print DefRange

这似乎是您要求它链接默认属性,但它不会这样做。您只能从您提供的对象中提取默认属性。在这种情况下,您将返回一个无法打印的范围对象。VBA 不会进入下一个级别来查看默认属性是否返回一个对象以及该对象类型是否具有默认属性。我想如果是这样,您可以创建一个无限循环 - 两个对象每个都是另一个对象的默认属性的结果。

Debug.Print DefRange.Cells(1, 1) 

没有默认属性会将自身插入到点链中。我认为这是因为如果 DefRange 确实有自己的 Cells 属性,它会使用哪个?我想不出 Excel 模型中的任何对象都以这种方式运行。你可以用这个

Debug.Print DefRange(1,1)

这似乎是链接默认属性的示例,我说过它不会这样做。我想这(1,1)足以再次启动链条。DefRange 返回范围对象,(1,1) 返回范围对象,并返回 Value(默认)属性。

有趣的问题。我想知道默认属性功能是故意以这种方式构建的,还是只是它的工作方式。

于 2012-12-17T15:51:14.743 回答