0

I am working on a script to help me create geometry in 3D software based on user input and I wanted to approach the problem with classes. I have 3 levels of structures, points, curves and surfaces so I want to create a class for each, where the next level structure inherits the lower one. So for example class cPoint have 4 properties: x,y,z,id. Further, the class cCurve has only 2 properties: id and points, and the same for surfaces. Now my question is: I implemented class cPoint as follows:

Private x_ As Double
Private y_ As Double
Private z_ As Double
Private id_ As Long

Public Property Let X(ByVal value As Double)
    x_ = value
End Property
Public Property Let Y(ByVal value As Double)
    y_ = value
End Property
Public Property Let Z(ByVal value As Double)
    z_ = value
End Property
Public Property Let ID(ByVal value As Long)
    id_ = value
End Property
Public Property Get X() As Double
    X = x_
End Property
Public Property Get Y() As Double
    Y = y_
End Property
Public Property Get Z() As Double
    Z = z_
End Property
Public Property Get ID() As Long
    ID = id_
End Property

and everything is fine here. And here I have class cCurve implemented:

Implements cPoint

Private id_ As Long
Private point_ As Collection

Public Property Let ID(ByVal value As Long)
    id_ = value
End Property
Public Property Set point(ByVal value As Collection)
    Set point_ = value
End Property
Public Property Get ID() As Long
    ID = id_
End Property
Public Property Get point() As Collection
    Set point = point_
End Property

But here, when I try to run the code I get prompted with the following error: Object module needs to implement 'X' for interface 'cPoint' I think I know what it means, but I have no clue how to implement it. Is my approach even correct? I'd highly appreciate any guidance in this manner.

4
  • Why do you think so? It is VBA though. Commented Feb 13, 2022 at 13:40
  • What methods/properties of a point do you want a curve to inherit ? Maybe this will help stackoverflow.com/questions/19373081 Commented Feb 13, 2022 at 14:48
  • my general idea is that class cCurve inherits x, y, z, id properties from cPoint (as curve is built from points) and then accordingly same thing with surface, which is built from curves. So in short, 1 Curve has a collection of points, 1 Surface has a collection of Curves. Commented Feb 13, 2022 at 15:02
  • This might help. Commented Feb 13, 2022 at 18:01

1 Answer 1

2

VBA does not support inheritance. The only way to mimic inheritance is to implement your Point class and at the same time have a private instance of the Point class in your curve class. This is what your "Point" class would look like (I used "GeometryPoint" as the name of the class because Excel already has a "Point" class created):

Option Explicit

Private Type TState
    ID  As Long
    X   As Double
    Y   As Double
    Z   As Double
End Type

Private This As TState

Public Property Let ID(ByVal Value As Long)
    This.ID = Value
End Property
Public Property Get ID() As Long
    ID = This.ID
End Property

Public Property Let X(ByVal Value As Double)
    This.X = Value
End Property
Public Property Get X() As Double
    X = This.X
End Property

Public Property Let Y(ByVal Value As Double)
    This.Y = Value
End Property
Public Property Get Y() As Double
    Y = This.Y
End Property

Public Property Let Z(ByVal Value As Double)
    This.Z = Value
End Property
Public Property Get Z() As Double
    Z = This.Z
End Property

And this is what your "Curve" class would look like:

Option Explicit
Implements GeometryPoint

Private Type TState
    Base        As GeometryPoint
    ID          As Long
    Points      As Collection
    X           As Double
    Y           As Double
    Z           As Double
End Type

Private This As TState

Public Property Let GeometryPoint_ID(ByVal Value As Long)
    This.Base.ID = Value
End Property
Public Property Get GeometryPoint_ID() As Long
    GeometryPoint_ID = This.Base.ID
End Property

Public Property Let GeometryPoint_X(ByVal Value As Double)
    This.Base.X = Value
End Property
Public Property Get GeometryPoint_X() As Double
    GeometryPoint_X = This.Base.X
End Property

Public Property Let GeometryPoint_Y(ByVal Value As Double)
    This.Base.Y = Value
End Property
Public Property Get GeometryPoint_Y() As Double
    GeometryPoint_Y = This.Base.Y
End Property

Public Property Let GeometryPoint_Z(ByVal Value As Double)
    This.Base.Z = Value
End Property
Public Property Get GeometryPoint_Z() As Double
    GeometryPoint_Z = This.Base.Z
End Property

Public Property Set Points(ByVal Value As Collection)
    Set This.Points = Value
End Property
Public Property Get Points() As Collection
    Set Points = This.Points
End Property

Private Sub Class_Initialize()
    Set This.Base = New GeometryPoint
End Sub

Private Sub Class_Terminate()
    Set This.Base = Nothing
End Sub

In VBA, when you "Implement" a class you need to list all of the members (properties, methods) of that class. In your case you received an error because you didn't list the X,Y,Z properties of the cPoint class that you were implementing. Is the "Curve" class supposed to have X,Y,Z properties as well? If not then you shouldn't implement the Point class. If the Curve class is just a class that stores a collection of Points then your Curve class should look like this:

**Note: This code was edited to include the "Class_Initialize" method which sets the "Points" member as a new collection once the Curve class is instantiated.

Option Explicit

Private Type TState
    ID          As Long
    Points      As Collection
End Type

Private This As TState

Public Property Let ID(ByVal Value As Long)
    This.ID = Value
End Property
Public Property Get ID() As Long
    ID = This.ID
End Property

Public Property Set Points(ByVal Value As Collection)
    Set This.Points = Value
End Property
Public Property Get Points() As Collection
    Set Points = This.Points
End Property

Private Sub Class_Initialize()
    Set This.Points = New Collection
End Sub

Private Sub Class_Terminate()
    Set This.Points = Nothing
End Sub

Finally, adding a new Point object to the "Points" member in the Curve class would look something like this:

Dim NewPoint As GeometryPoint
Dim NewCurve As Curve

Set NewPoint = New GeometryPoint
With NewPoint
    .X = 1
    .Y = 2
    .Z = 3
End With

Set NewCurve = New Curve
With NewCurve.Points
    .Add NewPoint
End With
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks! That makes a lot of sense the way you explained it. Indeed, the curve itself does not have X, Y, Z properties. Curves is built out of points, and the points only have those properties. How do I add points to the Curve though? I defined new point and assigned values, created new curve but when I try curve.Points.Add(point) I get an error that object doesn't support this property or method.
Alright, I just figured how to do it, Ill post it anyway in case someone may have different problem. I simply tried to assign object of cPoint to a collection of points, thus error. What needs to be done is collection of points has to be created and then assigned to curve.points collection Set Curve.Points = points_col
@rolkarz I've edited my original post to include the correct approach for adding points to your Curve class. Hopefully this answers your question.
@jtm82, thanks for the solution and for the update as well. I finally managed to solve my problem (so I marked your reply as a correct solution). Thanks a ton, your reply opened my eyes widely on this topic.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.