I'm looking for a way to 'chain class methods', for example the Range object can do things like "Range.Borders.Color", I guess that the Borders part is it's own class which is being accessed by the Range class but I have no idea how to implement something similar with my own classes - Nor do I even know what this is called and after hours of searching I think I might slowly be un-learning VBA.
Can anybody either a) Provide code which I could look at to replicate or b) Tell me what this is called and maybe even nudge me in a helpful direction?
As I know asking for code without providing any makes me look like a dick, consider the following pseudo-code. I know it's horrific but it might help me make any sense:
main ------------------------------------------------------------------------
Dim obj as class1
set obj = new class1
obj.Target = Range("A1:B5")
obj.Borders.Add
'A1:B5 put into modRange then given borders
class1 ------------------------------------------------------------------------
Private modRange as range
Public Property Let Target(newTarget as Range)
set modRange = newTarget
End Property
Public Property Borders()
Public Sub Add()
'Code to add borders to modRange
End Sub
Public Sub Remove()
'Code to remove borders from modRange
End Sub
End Property
I know this is not how the actual code would look. but as I don't know the syntax this is the closest thing I can imagine. I guess the real thing would have class1 linking to other class modules. Maybe.
As a side note. If I did have a class called "Borders" (I probably wont) as part of this class 1 object, would it conflict with the Borders portion of the Range object as well as it has a similar name? Or will the Private scope save the day?
(The .Borders.Add/Remove is a bit ridiculous to have as a class I know, I'm really only after the syntax - Honest)
To have complex properties of an object, you need to create a new class and then create an instance of that class in the parent class. So if you want to have something like Class1.Borders.Add()
, you'd first have to create a new CBorders
class (I used to prepend C
to my class names in VB6 / VBA to avoid name collisions). Something like:
'- in class CBorder
Private m_lColor As Long
Public Property Get Color() As Long
Color = m_lColor
End Property
Public Property Let Color(ByVal lNewColor As Long)
m_lColor = lNewColor
End Property
Public Sub Reset()
m_lColor = 0
End Sub
...
Then inside Class1, you'd have something like this:
Private m_oBorder As CBorder
Private Sub Class_Initialize()
...
Set m_oBorder = New CBorder
...
End Sub
Public Property Get Border() As CBorder
Set Border = m_oBorder
End Property
...
Then you can do this:
Dim obj As Class1
Set obj = New Class1
obj.Borders.Color = ...
...
Notice how the Borders
property of Class1
is accessed as a member of the obj
instance and then how the Color
property of the CBorder
class is used. Creating these values as properties is what lets you chain these calls together.
You'd need error checking and validation code as well - I left those out to keep the example short.
Another solution for this is to just return Me to make it chainable.
class module: CChaining
Using Functions for Target and Borders returning Me to enable chaining. Using Subs for Add and Remove to "finish" the chain.
Private modRange As Range, modRangeBorders As Object
Public Function Target(rng As Range)
Set modRange = rng
Set Target = Me
End Function
Public Function Borders()
Set modRangeBorders = modRange.Borders
Set Borders = Me
End Function
Public Sub Add()
modRangeBorders.LineStyle = xlContinuous
End Sub
Public Sub Remove()
modRangeBorders.LineStyle = xlNone
End Sub
Testing the class in a module
Sub testing()
Dim obj As New CChaining
obj.Target(Range("A1:B5")).Borders.Add
'now the target and property (Borders) is set and you could do this
'obj.Remove
End Sub
Pretty nice ... hmm, with this it would be possible to build a library like in other languages (javascript > jQuery) to make using Excel VBA much easier.