Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't an Excel/VBA user defined default property that returns a Range behave like a Range?

Tags:

excel

vba

A property in an Excel/VBA class I'm writing returns a Range. I made it the default property for the class using the technique described at http://www.cpearson.com/excel/DefaultMember.aspx. I expected to use all the Range class's built-in properties and methods with objects of my class without specifying the property explicitly. It doesn't work. Here are a couple of much simpler classes to illustrate. (These listings are the exported source viewed with a text editor since VBA's editor hides the Attribute statements.)

' 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

Here's a Sub in a normal module to instantiate and test the classes. The comments indicate what happens when I single step through it:

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

Why doesn't DefRange in statement (5) behave just like DefRange.DefProp in statement (4)?

If I change statement (5) to:

Debug.Print DefRange.Cells(1, 1) 

The compiler selects ".Cells", says "Compile error: Method or data member not found" and stops so the problem is in the object model - not just something getting messed up at run-time. Am I doing something wrong? Or isn't it possible to have a default property that returns a Range? How about other built-in classes? User defined classes?

like image 561
SVanDee Avatar asked Dec 16 '12 02:12

SVanDee


People also ask

What does the range in VBA return?

Excel VBA Range Object For example, the range property in VBA is used to refer to specific rows or columns while writing the code. The code “Range(“A1:A5”). Value=2” returns the number 2 in the range A1:A5. In VBA, macros are recorded.

How do you specify a range of cells in VBA?

Range(“A1”) tells VBA the address of the cell that we want to refer to. Select is a method of the Range object and selects the cells/range specified in the Range object. The cell references need to be enclosed in double quotes.

What is range data type in VBA?

In VBA we have a data type as a range that is used to define variables as a range that can hold a value of the range. These variables are very useful in complex programming and automation. Often variable range is used with the set statements and range method.


1 Answers

Debug.Print DefRange

This seems like you're asking it to chain default properties and it won't do it. You can only pull the default property from the object you provide. In this case, you're returning a range object and that can't be printed. VBA won't go to the next level to see if the default property returns an object and if that object type has a default property. I suppose if it did, you could create an infinite loop - two objects each the result of the default property of the other.

Debug.Print DefRange.Cells(1, 1) 

No default property will insert itself into a dot-chain. I assume this is because if DefRange did have a Cells property of its own, which would it use? I can't think of any objects in Excel's model that behave this way. You can use this

Debug.Print DefRange(1,1)

This seems to be an example of chaining default properties, which I said it wouldn't do. I guess the (1,1) is enough to jump start the chain again. DefRange returns a range object, (1,1) returns a range object, and the Value (default) property is returned.

Interesting question. I wonder if the default property feature was built this way intentionally or it's just the way it worked out.

like image 180
Dick Kusleika Avatar answered Oct 20 '22 02:10

Dick Kusleika