How To Write A Recursive Routine In MicroStation VBA [CS]


 

This Client Server article is republished in its entirety from 2003 for reference purposes.

By Yuedong Bi, Developer Support Analyst, Bentley Corporate Office
05 May 2003

 

This article describes how to write a recursive routine to solve a complex problem by solving progressively simpler problems, until a final base case can be reached. There are many practical applications to apply the theory of recursion for any nested object in MicroStation objects such as cells, attachments, etc.

What is recursive method?

Recursive definitions are common in mathematics. Any series in which a term is defined using the values of earlier terms in the series is a recursive definition. For example, the sum of the first n integers can be defined as the value of n plus the sum of the first n-1 integers.

Here is a recursive function to compute this sum:

Function sumNumber (n As Integer) As Integer

If n <= 1 Then ‘Base case

sumNumber = 1

Else ‘ the recursive call

sumNumber = sumNumber(n - 1) + n

End If

End Function

 

As illustrated above, you can see that a recursive function has two cases:

 

1. The base case - If the problem is simple enough, it is solved without recursive calls. In the above example, the sum of the 1st integer is 1.

2. The recursive call - The function calling itself to solve a simpler problem, as in the above example, would call itself by calculating the sum of the current n-1 integers.

Recursive method usage in Microstation VBA

As mentioned previously, a recursive function has many practical applications in MicroStation. For example, in the managing of nested cells, the base case is always a primitive element (such as line, shape, text, ellipse, etc.), which cannot be broken down to a simpler case to manage.

For example:

To change the color of a shape element, we can:

Dim oShapeElement As ShapeElement
‘ ....... Get oShapeElement from scan,
‘ user pick from model, or create one
oShapeElement.Color = 4 'Change element color
‘rewrite changes to its model.
oShapeElement.Rewrite
‘Redraws this object on the view
ShapeElement.Redraw msdDrawingModeNormal
To change the font of a text element:

Dim oFont As Font
Set oFont = ActiveDesignFile.Fonts(3)
With oTextElement
.TextStyle.Font = oFont
.Rewrite
End With
To process a cell element, the solution to apply would use an ElementEnumerator similar to:

Dim oElEnum As ElementEnumerator
Set oElEnum = oCellElement.GetSubElements
Do While oElEnum.MoveNext
‘ ..... Process each element inside a cell
Loop

In a recursive call, the function will keep calling itself to solve a simpler problem until the base case has been satisfied.

This code illustrates how a recursive function call is used to list all elements within a nested cell:

Function processNestedCell (oCellElement As _

CellElement) As Variant

Dim oElEnum As ElementEnumerator

Dim oSubElement As Element

Set oElEnum = oCellElement.GetSubElements
Do While oElEnum.MoveNext

Set oSubElement = oElEnum.Current

If oSubElement.Type = msdElementTypeCellHeader _

Then

Debug.Print "Nested Cell Name: " & _ oSubElement.AsCellElement.Name

' Recursive call

processNestedCell oSubElement.AsCellElement

Else

' Base case, not a cell element,

‘ If needed, you can check more type,

' Such as if type is text or text node

‘ do something, ....

Debug.Print oSubElement.Type

'More control on each type element.

‘Such as change Ellipse color

If oSubElement.Type = _

msdElementTypeEllipse Then

 

oSubElement.AsEllipseElement.Color = 4

'Change element color

oSubElement.Rewrite

oSubElement.Redraw msdDrawingModeNormal

End If

End If

Loop

End Function

 

Upon receiving a list of elements within a complex nested cell you can now easily manage and process each individual base case elements, performing any required operation such as changing the symbology or properties.

Note: If you are performing an operation that would attempt to change the size of a complex object it is recommended that you do not simply delete individual elements in cell. Instead, create a new cell with of the correct size and delete the old one.

Where should I use recursion?

Try taking these concepts further and see if you can use recursion to manage other complex element types in MicroStation such as reference files, etc.

See Also

Client Server Archive

MicroStation Desktop TechNotes and FAQs

Comments or Corrections?

Bentley's Technical Support Group requests that you please confine any comments you have on this Wiki entry to this "Comments or Corrections?" section. THANK YOU!