You are currently reviewing an older revision of this page.
The VBA object "ElementEnumerator" can make quick work of writing custom applications for MicroStation V8 to scan DGN files for specific objects.
Scanning a design file and processing specified elements is a common task assigned to MicroStation VBA programmers. The scanning process may be as general as cycling through all the elements in a model or perhaps scanning for specific saved view elements. The ElementEnumerator object is used for this purpose.
The "MicroStation V8 Visual Basic for Applications Help" window contains a number of examples that show how to scan; here is an example of using the ElementEnumerator object in its simplest form:
Sub ScanDGN() Dim counter As Integer Dim oEnumerator As ElementEnumerator
Set oEnumerator = ActiveModelReference.Scan
Do While oEnumerator.MoveNext counter = counter + 1 Loop MsgBox "The total number of elements scanned were: " & CStr(counter) End Sub
The above scanner will find every graphical and non-graphical element in the active model. After the code runs, it displays the total number of elements that were found in a message box (using the Visual Basic MsgBox function).
First, we set the ElementEnumerator object to scan the active model:
Ø Tip: To scan for elements that are only within a Selection Set, you could replace the Scan method with the AnyElementsSelected method.
Using a Do While...Loop and calling the MoveNext method, the application moves incrementally through the enumerator, identifying each element found. Next, the counter will increment:
Do While oEnumerator.MoveNext
counter = counter + 1
Loop
Next the MsgBox object displays the number of elements that are found:
MsgBox "The total number of elements scanned were: " & CStr(counter)
For most purposes, the above example would not be efficient or recommended unless you wanted to get all the graphical and non-graphical elements.
Ø Tip: Whenever an object is declared, it needs to be Set before it can be used.
The ElementScanCriteria object is used as an argument with the ElementEnumerator object to limit the set of elements generated by the scanner. The scanner can filter out elements much faster than the Visual Basic program can, so its use is recommended to make the ElementScanCritieria as precise as possible. The example below will scan the active model for only lines and text that of Color 5:
Sub ScanForElems()
Dim counter As Integer
Dim oEnumerator As ElementEnumerator
Dim oScanCriteria As New ElementScanCriteria
oScanCriteria.ExcludeAllTypes
oScanCriteria.IncludeType msdElementTypeLine
oScanCriteria.IncludeType msdElementTypeText
oScanCriteria.ExcludeAllColors
oScanCriteria.IncludeColor 5
Set oEnumerator = ActiveModelReference.Scan(oScanCriteria)
End Sub
First, the application defines a new ElementScanCriteria object. It is possible to define and set an object with one statement using the keyword New.
By default, all elements are included in an ElementScanCriteria object. At this point, the application should first exclude all element types, then include just the types being sought:
In a similar manner, next exclude all the colors and include the only the colors you are interested in:
· oScanCriteria.ExcludeAllColors
At this point, the application needs to set the ElementEnumerator object to locate only the elements that meet the specified criteria:
The above example could also be modified to scan for saved View elements by replacing all the oScanCriteria statements with:
oScanCriteria.IncludeType msdElementTypeView
These will change the criteria to scan for reference file attachments:
oScanCriteria.IncludeType msdElementTypeReferenceAttachment
Now the application will modify the code so that it scans for elements that are in an active fence. Currently, the ElementEnumerator object does not allow the combining of ElementScanCriteria objects with a fence operation. The code below is modified so that it scans the active fence for all line and text elements of Color 5:
Sub ScanFence()
Dim oElement As Element
Dim oFence As Fence
Set oFence = ActiveDesignFile.Fence
If oFence.IsDefined = True Then
Set oEnumerator = oFence.GetContents
Set oElement = oEnumerator.Current
If oElement.Color = 5 Then
If oElement.Type = msdElementTypeLine Or oElement.Type = msdElementTypeText Then
End If
MsgBox "The total number of elements scanned for are: " & CStr(counter)
Else
ShowError "A Fence Has Not Been Defined!"
First, the application defines an Elementobject and a Fenceobject:
Next, the Fence object is set:
Before any processing begins, the application needs to determine if an active fence exists. If it does, it sets the ElementEnumerator object using the Fence object. If no fence exists, the application will display a message and end the processing:
The application again uses a similar Do While...Loop and a MoveNext method to loop through all elements found. Because the application can't use the ElementScanCriteria object, the application needs to determine if the elements contained in the Enumerator are Color 5 and if they are either a Line or a Text element. In the looping process, the application sets the Element object to "get" the current element from the Enumerator using the Currentmethod:
Next, the application uses a couple of If...End If statements to determine if the current element meets the specified criteria. If it does, the same logic is applied as in the previous examples, and one item is added to the counter. The totals are displayed:
If oElement.Type = msdElementTypeLine Or oElement.Type = msdElementTypeText Then ...
In this example, it was not necessary to use an Element object, but it is simpler to follow. This section could also have been written as:
If oEnumerator.Current.Color = 5 Then
If oEnumerator.Current.Type = msdElementTypeLine Or oEnumerator.Current.Type = _
msdElementTypeText Then ...