In this article I will show how to create and use a custom class within a script. If you program in VBA, VB6 or .NET you might be familiar with building your own classes but you may not know that you can also use them in a script. In case you are wondering what a class is, I will start by briefly discussing that as well. I have to admit that I have only used classes inside scripts a handful of times, but in those situations it proved to be very useful.
What is a class?
When you write programs using the CATIA automation API, you are working with objects that represent various “things” in the software. For example, each document that is open is represented by a separate Document object. That object has various properties that hold some data or attributes associated with it. For example, the Document object provides a Path property to retrieve the file path where it is currently saved. Objects also may provide methods which can be thought of as services or actions that can be performed. As an example, the document object provides a Save method to save any changes that were made.
All of these objects are actually instances that get each their definition from a master “template”. That template is called a class and it has three basic purposes:
- It defines what properties and methods will be provided (called members)
- It defines how its data will be stored
- It provides all of the underlying code that gets executed when calls are made to its instances
Why create a class inside of a script?
Adding a class to your script allows you to define a new object type that can be very easily used (instantiated) again and again in the script. Generally, a class will represent some type of real “thing” so it might make sense to group all attributes and services that “thing” will provide into an easy to use object. When I have used them, most often they are relatively simple and will duplicate some functionality that is not available in a script language.
Declaring the class
The class definition needs to be separated from the other procedures (subroutines and functions) in the script. This is done by enclosing all of the class code inside the Class and End Class statements. So you might have something like this to start:
Sub CATMain() 'This is the main sub for your program End Sub Class 'All of the code for your class goes here End Class
The first step here is to decide what properties your class should provide and their data types. A good way to think about this is to mimic the way CATIA classes or other objects you may have used in the past are defined. Most commercial applications have very well thought out object models, so try to follow the same sorts of conventions they do. Once you have done that, you should declare a private variable inside the class to hold each piece of data. This step is called encapsulation because it protects that data from being accessed in the program unless it is accessed through the class properties. Next, you should create a separate procedure to retrieve and set each property value. This is shown below.
'Declare a private variable to hold the property value Private p_strName As String 'This procedure is executed when this property is read Property Get Name() As String 'Like a function, return the value by assigning it to the property name Name = p_strName End Property 'This procedure is executed when a value is assigned to the property Property Let Name(iName As String) 'Simply assign the passed in value to the private variable p_strName = iName End Property
- Properties can be values (number, string, boolean, etc.) or other objects. To retrieve a property, you will always define a Property Get procedure. However, to assign a property there are two different ways depending on whether the data type is a value or an object. To assign a value, you will define a Property Let procedure (as shown above) and to assign an object you will define a Property Set statement as shown below.
Private p_objPart As Part 'This procedure is executed when an object is assigned to the property Property Set Part(iPart As Part) 'Simply assign the passed in object to the private variable Set p_objPart = iPart End Property
- If you want a property to be read only or write only, simply define only one (not both) of the Get Property / Let Property / Set Property procedures. For example, if there is not a Property Get procedure, that property can be assigned but not read.
Adding methods to a class is very simple. All you have to do is include a subroutine or function for each.
A great example that I have used in some of my scripts is a collection class. If you have written code in VBA, VB6, .NET, etc. you are probably familiar with collections. They simply hold a bunch of values or objects. They generally provide the following basic capabilities:
- Query the size of the collection (Count)
- Add items to the collection
- Remove items from the collection
- Retrieve an item from the collection
The VB script language does not provide its own collection class. So, a common alternative is to use an array to store values. While an array does work, it can require a lot of code throughout your program. A collection class may contain a fair amount of code, but it can be reused in other scripts easily and it greatly simplifies the rest of the code in the script. Another option is to use a dictionary object in the Windows Scripting Runtime Library. This is a good option and I have used it many times as well.
An example collection class is provided below. I only included the most basic capabilities and it is setup to store and retrieve objects (not values). If you want to manage values, you will need to replace the Property Set procedures with Property Let Procedures.
'Start the class definition Class CustCollection 'Declare private variables. These cannot be accessed directly. 'Instead they can only be accessed through a property or method Private p_varItemArray() As Variant Private p_intCount As Integer Private Sub Class_Initialize() 'The initialize procedure will execute whenever a new object instance is created 'Here you should initialize any default values p_intCount = 0 End Sub Property Get Count() As Integer 'Used to retrieve how many items are in the collection 'Simply return the value stored in the private variable Count = p_intCount End Property Sub Add(iObject) 'Used to add an item to the collection 'Increment the size of the collection p_intCount = p_intCount + 1 'Resize the array preserving all of the existing items ReDim Preserve p_varItemArray(p_intCount) 'Add the new item to the array Set p_varItemArray(p_intCount) = iObject End Sub Function Item(ByVal iIndex As Integer) As Object 'Used to retrieve an item from the collection 'If the requested index exists, return it 'Otherwise raise an error If iIndex <> 0 And iIndex <= p_intCount Then Set Item = p_varItemArray(iIndex) Else Err.Raise vbObjectError + 1, "Collection.Item()", "Index out of range" End If End Function Sub Remove(ByVal iIndex As Integer) 'Used to remove an item from the collection Dim intIndex As Integer 'From the requested index to the upper bound of 'the array move all existing items down one index For intIndex = iIndex To p_intCount - 1 Set p_varItemArray(iIndex) = p_varItemArray(iIndex + 1) Next 'Resize the array destroying the last element p_intCount = p_intCount - 1 ReDim Preserve p_varItemArray(p_intCount) End Sub End Class
The following example shows how to use the class in your script. Each of the properties and methods provided by the new CustCollection class are demonstrated.
Sub CATMain() Dim objCol As CustCollection 'Declare a new variable Dim objItem As Object 'Instantiate a new collection object Set objCol = New CustCollection 'Display the current collection count MsgBox objCol.Count, 0, "Count (Initial)" 'Add the 3 std planes from the active part to the collection objCol.Add CATIA.ActiveDocument.Part.OriginElements.PlaneXY objCol.Add CATIA.ActiveDocument.Part.OriginElements.PlaneYZ objCol.Add CATIA.ActiveDocument.Part.OriginElements.PlaneZX 'Display the current collection count MsgBox objCol.Count, 0, "Count (After adding std planes)" 'Get the 2nd item in the collection and display its name Set objItem = objCol.Item(2) MsgBox objItem.Name, 0, "Name of 2nd Item" 'Remove the 2nd Item objCol.Remove 2 'Display the current collection count MsgBox objCol.Count, 0, "Count (After removing 2nd item)" 'Get the 2nd item in the collection and display its name 'When the original 2nd item was removed the 3rd item moved to the 2nd index Set objItem = objCol.Item(2) MsgBox objItem.Name, 0, "Name of 2nd Item" End Sub
Once you create a class such as the collection example shown above, you can reuse it in future script projects by just pasting in the class definition. Creating easy to use custom classes takes some practice. As you create more of them, you will begin to learn good and bad practices but in general, try to mimic the way other objects work in other applications. For example, I made the collection class above provide the properties and methods you would expect to see and the way they are used is familiar.
Please take a moment to rate this article…Just click the stars up near the title.