Brian
Brian

Reputation: 2108

Is it possible to reach the property of a collection object that is not part of an interface

I have two classes of shapes and an interface. After I instantiate objects from each class and set their properties I add them to a collection. That's pretty straightforward. Then I declare a variable of type MyInterface and loop through the collection to add each shape. But there is an additional property for each type of shape that I want to set but which are not part of the interface. Is there a way to do this? I think other languages call this type casting but I am not sure. Does VBA support this? Any help is appreciated. My code is below:

Interface (iShape)

Option Explicit

Public Property Let Top(value As Long)
End Property
Public Property Get Top() As Long
End Property

Public Property Let Left(value As Long)
End Property
Public Property Get Left() As Long
End Property

Public Property Let Width(value As Long)
End Property
Public Property Get Width() As Long
End Property

Public Property Let Height(value As Long)
End Property
Public Property Get Height() As Long
End Property

Public Function Draw(obj As Worksheet) As Excel.Shape
End Function

Class (cDiamond)

Option Explicit

Private pTop As Long
Private pLeft As Long
Private pWidth As Long
Private pHeight As Long
Private pColor As Long

Implements iShape

'====================Properties====================
Public Property Let Top(value As Long)
    pTop = value
End Property
Public Property Get Top() As Long
    Top = pTop
End Property

Public Property Let Left(value As Long)
    pLeft = value
End Property
Public Property Get Left() As Long
    Left = pLeft
End Property

Public Property Let Width(value As Long)
    pWidth = value
End Property
Public Property Get Width() As Long
    Width = pWidth
End Property

Public Property Let Height(value As Long)
    pHeight = value
End Property
Public Property Get Height() As Long
    Height = pHeight
End Property

Public Property Let Color(value As Long)
    pColor = value
End Property
Public Property Get Color() As Long
    Color = pColor
End Property

'====================Methods====================
Public Function Draw(obj As Worksheet) As Excel.Shape
    Set Draw = obj.Shapes.AddShape(msoShapeFlowchartOffpageConnector, Me.Left, Me.Top, Me.Width, Me.Height)
End Function

'====================Interface====================
Private Property Get iShape_Height() As Long
    iShape_Height = Height
End Property
Private Property Let iShape_Height(RHS As Long)
    Height = RHS
End Property

Private Property Get iShape_Left() As Long
    iShape_Left = Left
End Property
Private Property Let iShape_Left(RHS As Long)
    Left = RHS
End Property

Private Property Get iShape_Top() As Long
    iShape_Top = Top
End Property
Private Property Let iShape_Top(RHS As Long)
    Top = RHS
End Property

Private Property Get iShape_Width() As Long
    iShape_Width = Width
End Property
Private Property Let iShape_Width(RHS As Long)
    Width = RHS
End Property

Private Function iShape_Draw(obj As Worksheet) As Shape
    Set iShape_Draw = Draw(obj)
End Function

Class (cTextbox)

For the sake of brevity, this class is identical to cDiamond except it has a Caption property instead of a Color property.

Module (mTest)

Option Explicit

Private Sub Test()
    Dim wks As Excel.Worksheet
    Set wks = ActiveSheet
    Dim c As Collection
    Set c = New Collection

    Dim d1 As cDiamond
    Set d1 = New cDiamond
    d1.Top = 10
    d1.Left = 10
    d1.Height = 25
    d1.Width = 25
    d1.Color = RGB(255, 0, 0)
    c.Add d1

    Dim d2 As cDiamond
    Set d2 = New cDiamond
    d2.Top = 50
    d2.Left = 10
    d2.Height = 25
    d2.Width = 25
    d2.Color = RGB(0, 255, 0)
    c.Add d2

    Dim t1 As cTextbox
    Set t1 = New cTextbox
    t1.Top = 90
    t1.Left = 10
    t1.Height = 25
    t1.Width = 25
    t1.Caption = "Textbox"
    c.Add t1

    Dim shp As iShape
    For Each shp In c
        shp.Draw wks
        ' I would like to set the color or caption properties depending on the type of shape in the collection.
    Next shp
    Set c = Nothing
End Sub

Upvotes: 1

Views: 72

Answers (2)

user6432984
user6432984

Reputation:

Declaring shp as object you will lose intellisense. Another technique would be to have Interface return a reference to the instance of object. Similarly to how OLEObject.Object returns the instance of the object that it is wrapping. In my example I use This to return the instance of the class.

enter image description here

In this way you will have intellisense for all the common properties and methods. We can also access the properties and methods that are unique to the classes that implement your interface using a With statement.

You'll need to first test check the type of the object. Then use a With statement to temporarily instantiate a new Object of that type and write your code inside the With statement .

If TypeOf shp Is cTextbox Then
    With New cTextbox
        Msgbox .Caption
    End With
End If

Finally, you simply replace the New instance with the actual instance of the Object.

If TypeOf shp Is cTextbox Then
    With shp.This
        Msgbox .Caption
    End With
End If

enter image description here

Interface (iShape)

Public Function This() As Object
End Function

Classes cTextbox & cDiamond

Public Function This() As Object
    Set This = Me
End Function

Public Function iShape_This() As Object
    Set iShape_This = This
End Function

mTest.Test

Dim shp As iShape
For Each shp In c
    shp.Draw wks

    If TypeOf shp Is cTextbox Then
        With shp.This
            MsgBox .Caption
        End With
    End If

    ' I would like to set the color or caption properties depending on the type of shape in the collection.
Next shp

Upvotes: 1

Ron Rosenfeld
Ron Rosenfeld

Reputation: 60344

If I understand you correctly, (and I don't fully understand interfaces either), you should be able to do what you want by declaring shp as of type variant.

Dim shp
For Each shp in C ... 

shp will then take on the type of either cDiamond or cTextbox depending on which is retrieved from the Collection. Then you will be able to retrieve or modify shp.color or shp.caption. You may also want to change Caption to datatype String in cTextBox

Upvotes: 1

Related Questions