Bezieht sich auf | |||
Produkt(e): | MicroStation | ||
Version(en): | 08.11.09.578 | ||
Umgebung: | Windows 7 64 bit | ||
Produktbereich: | Programmierung | ||
Produktunterbereich: | VBA | ||
Ursprünglicher Autor: | Artur Goldsweer, Bentley Technical Support Group | ||
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 (Stand gilt für MicroStation V8i, SelectSeries 3 und kann von anderen Versionen abweichen) :
Liste der Elementtypen zum Download