Daten in einer Zeichnung mit VBA suchen und auswerten, Teil 5 – weitere allgemeine Eigenschaften von


In den bisherigen Beispielen haben wir eigentlich immer nur die gleichen Daten ausgelesen, also die Endpunkte von Linien.
Dies wollen wir jetzt in verschiedenen Richtungen verallgemeinern, denn neben Linien kommen weitaus komplexere Datenstrukturen vor und auch die Eigenschaften selber sind vielfältig.
Die Ausgabe in eine .csv Datei dagegen belassen wir der Einfachheit halber, das Gerüst dazu haben uns ja bereits erstellt.

Zunächst einmal schränken wir die Auswahl der untersuchten Elemente nicht mehr ein,  d.h. die Auswahl erfolgt über alle graphischen Elemente des aktuellen Modells ohne Angabe von Scankriterien:

Set Ee = ActiveModelReference.GraphicalElementCache.Scan()

Jetzt müssen wir allerdings selber überprüfen, welchen Elementtyp wir jeweils untersuchen, wir können nicht mehr davon ausgehen, dass es nur Linien sind, die Variable ele wird jetzt  ein allgemeines Element:

Dim ele As Element

Diese Änderung hat auch Konsequenzen auf die nachfolgende Auswertung des Elements "ele".
Da wie vorher nur Linien ausgewählt haben, konnten wir direkt die Eigenschaft ..startpoint auslesen.
Da es sich jetzt um ein allgemeines Element handelt, müssen wir den Typ überprüfen und dann den Typ Line dem Auslesen der Endpunkte voransetzen, dies erfolgt über .AsLineElement.
Hier einmal zum Ausprobieren die Auswertung der Linien:

Sub elementinfo()
Dim ele As Element
Dim Ee As ElementEnumerator
Dim startpunkt, endpunkt As Point3d
Dim kopfZeile, Zeile As String
Dim datei As String
If ActiveWorkspace.IsConfigurationVariableDefined("MeineAusgabeDatei") Then
datei = ActiveWorkspace.ConfigurationVariableValue("MeineAusgabeDatei")
Else
MsgBox "Die Variable MeineAusgabeDatei ist nicht definiert, Verarbeitung abgebrochen", vbCritical
Exit Sub
End If
Open datei For Append As #1
Set Ee = ActiveModelReference.GraphicalElementCache.Scan()
Do While Ee.MoveNext
 Set ele = Ee.Current
 If ele.Type = msdElementTypeLine Then
   Zeile = ele.Type & ";Von (xy) = " & ele.AsLineElement.startPoint.X & "," & ele.AsLineElement.startPoint.Y & ";"
   Zeile = Zeile & "Nach (xy) = " & ele.AsLineElement.EndPoint.X & "," & ele.AsLineElement.EndPoint.Y
   Print #1, Zeile 
 End If
Loop
Close #1
End Sub

Das Ergebnis in Excel könnte bei 4 Linien so aussehen:


Mögliche Linestrings, Texte, Kreise oder andere komplexere Elemente werden noch nicht berücksichtigt, das holen wir jetzt schrittweise nach:

Da Kreise keinen Anfangspunkt haben, können wir hier etwa den Mittelpunkt und Radius auslesen, aber hier wartet schon gleich eine kleine Hürde, denn einen Kreis als Elementtyp finden wir hier nicht, sondern nur eine Ellipse.
Das macht aber deshalb Sinn, weil ein Kreis mathematisch gesehen nur ein Spezialfall einer Ellipse darstellt und deshalb durchaus als Ellipse behandelt werden kann. Der VBA Editor hilft auch hier wieder bei der Auswahl, die möglichen Elementtypen werden zur Auswahl angeboten:

Die Überprüfung der Kreise könnte dann so aussehen:

If ele.Type = msdElementTypeEllipse Then
Zeile = ele.Type & ";Zentrum (xy) = " & ele.AsEllipticalElement.CenterPoint.X & "," & ele.AsEllipticalElement.CenterPoint.Y & ";"
Zeile = Zeile & "; Radius = " & ele.AsEllipticalElement.PrimaryRadius
Print #1, Zeile
End If

 

In Excel wiederum könnte die Auswertung von 2 Kreisen ein solches Ergebnis bringen:

Bei Texten könnte für uns der Einfügepunkt, die Texthöhe und der Text selber interessant sein,

hier ein möglicher Ansatz dafür:

If ele.Type = msdElementTypeText Then
 Zeile = ele.Type & ";Ursprung (xy) = " & ele.AsTextElement.Origin.X & "," & ele.AsTextElement.Origin.Y & ";"
 Zeile = Zeile & "Hoehe: " & ele.AsTextElement.TextStyle.Height & ";"
 Zeile = Zeile & "Text: " & ele.AsTextElement.Text
 Print #1, Zeile
End If

in meinem Beispiel hat diese folgende Ausgabe im Excel erzeugt:

 Bevor wir uns im nächsten Teil den komplexeren Daten zuwenden, hier noch eine Zusammenfassung des bisherigen Ansatzes:

Sub elementinfo()
Dim ele As Element
Dim Ee As ElementEnumerator
Dim startpunkt, endpunkt As Point3d
Dim kopfZeile, Zeile As String Dim datei As String
If ActiveWorkspace.IsConfigurationVariableDefined("MeineAusgabeDatei") Then
datei = ActiveWorkspace.ConfigurationVariableValue("MeineAusgabeDatei")
Else
MsgBox "Die Variable MeineAusgabeDatei ist nicht definiert, Verarbeitung abgebrochen", vbCritical
Exit Sub
End If
Open datei For Append As #1
Set Ee = ActiveModelReference.GraphicalElementCache.Scan()
Do While Ee.MoveNext
Set ele = Ee.Current
If ele.Type = msdElementTypeLine Then
Zeile = ele.Type & ";Von (xy) = " & ele.AsLineElement.startPoint.X & "," & ele.AsLineElement.startPoint.Y & ";"
Zeile = Zeile & "Nach (xy) = " & ele.AsLineElement.EndPoint.X & "," & ele.AsLineElement.EndPoint.Y
Print #1, Zeile
End If
If ele.Type = msdElementTypeEllipse Then
Zeile = ele.Type & ";Zentrum (xy) = " & ele.AsEllipticalElement.CenterPoint.X & "," & ele.AsEllipticalElement.CenterPoint.Y & ";"
Zeile = Zeile & "; Radius = " & ele.AsEllipticalElement.PrimaryRadius
Print #1, Zeile
End If
If ele.Type = msdElementTypeText Then
Zeile = ele.Type & ";Ursprung (xy) = " & ele.AsTextElement.Origin.X & "," & ele.AsTextElement.Origin.Y & ";"
Zeile = Zeile & "Hoehe: " & ele.AsTextElement.TextStyle.Height & ";"
Zeile = Zeile & "Text: " & ele.AsTextElement.Text
Print #1, Zeile
End If
Loop
Close #1
End Sub

Bei der Ausgabe des Elementtyps dürfte auffallen, dass der Typ eines Elementes mit einer Nummer angegeben ist, beispielsweise steht die 3 für Linie, 15 für Kreis und 17 für Text.
Alle Elementtypen sind einer Nummer zugeordnet, den aktuellen Stand der gültigen Nummern habe ich aus dem MicroStation SDK kopiert und hier als Textdatei zum Download abgelegt:

Liste der Elementtypen zum Download