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 | ||
Im vorigen Teil haben wir einfache Zellen untersucht, allerdings haben wir bislang die Verschachtelung noch nicht beachtet, das wollen wir jetzt als Nächstes angehen.
Aus dem Beispiel der Zelle und Gruppe vom vorigen Teil 7 habe ich neue Zellen generiert und jeweils die bisherigen Zellen mit einbezogen, daraus habe ich dann letztlich eine Zelle mit Namen Zelle2 bis Zelle6 generiet, dessen Struktur hier mit dem „Analyze element“ Tool angedeutet wird, die Struktur ist dabei absichtlich verschachtelt und unübersichtlich:
Mit diesem Beispiel einer unübersichtlichen Zelle möchte ich demonstrieren, dass der bisherige Weg Zellen auszuwerten seine Grenzen erreicht hat. Um Zellen wie diese etwas komplexere Zelle6 wie bisher auszuwerten, müssten wir eine Menge an Programmzeilen generieren.
Stattdessen möchte ich einen Weg zeigen, wie man dies mit rekursiven Routinen angehen kann. Und zwar neben der bisherigen Subroutine Elementinfo, mit der die Auswertung weiterhin gestartet wird, lagere ich die Analyse der Zellen in eine weitere Subroutine aus, die ich einmal "zerlegen" nennen möchte.
Das Besondere an dieser Routine ist, dass sie immer wieder selbst aufgerufen wird, und das ist die angesprochene Rekursion
Folgenden Vorschlag habe ich dafür einmal zusammengestellt:
Public datei As String Sub elementinfo() Dim ele As Element Dim ee As ElementEnumerator Dim startpunkt, endpunkt As Point3d Dim kopfZeile, zeile As String Dim oL() As Element Dim Zellname 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 Set ee = ActiveModelReference.GraphicalElementCache.Scan() Do While ee.MoveNext Call zerlegen(ee.Current, 1) Loop End Sub Sub zerlegen(ele As Element, tiefe As Integer) Dim oL() As Element Dim zeile As String If ele.IsCellElement Then oL = ele.AsCellElement.GetSubElements.BuildArrayFromContents Open datei For Append As #1 zeile = "" For i = 2 To tiefe zeile = zeile & " ;" Next zeile = zeile + "Tiefe: " & tiefe & ";Zelle < " & ele.AsCellElement.Name & "> mit " zeile = zeile & UBound(oL) - LBound(oL) + 1 & " Elementen" Print #1, zeile Close #1 For i = LBound(oL) To UBound(oL) Call zerlegen(oL(i), tiefe + 1) Next Else Open datei For Append As #1 zeile = "" For i = 2 To tiefe zeile = zeile & " ;" Next zeile = zeile + TypeName(ele) Print #1, zeile Close #1 End If End Sub
In der bisherigen Sub elementinfo lese ich eigentlich nur noch den Namen der Datei aus, in die die Daten geschrieben werden sollen. Den Namen speichere ich in eine public Variable datei, die außerhalb der Sub elementinfo deklariert wird - Vorsicht, unbedingt die Deklaration der Variablen datei aus der Sub elementinfo entfernen, da sich sonst die Gültigkeitsbereiche der VAriablen überschneiden mit der Folge, dass in der Sub zerlegen kein Dateiname ankommt.
Die eigentliche Analyse der Daten liegt ketzt bei der Sub zerlegen.
Die Sub elementinfo ruft jetzt die Sub zerlegen für jedes Element der Zeichnung auf.
Die Routine zerlegen prüft nur, ob das Element, mit dem die Routine aufgerufen wird, selber eine Zelle ist oder nicht.
Wenn ja, dann wird die Sub zerlegen jeweils mit allen Unterelementen erneut aufgerufen, ansonsten werden die Details in die Datei geschrieben.
Um die Verschachtelungstiefe deutlich zu machen, gebe ich die Tiefe mit der gleichnamigen Variable jeweils mit und stelle dies in der Ausgabedatei durch ein Einrücken um eine Spalte optisch deutlicher da.
Dazu stelle ich den Daten dies voran:
zeile = "" For i = 2 To tiefe zeile = zeile & " ;" Next
Damit erreiche ich ein Einrücken der Daten nach rechts ab der 2. Verschachtelungstiefe.
Die resultierende .csv Datei sieht in Excel dann etwa so aus, wie dieser Ausschnitt es andeutet:
Dies ist natürlich nur ein Vorschlag, wie man dies Problem angehen kann und dient mehr zur optischen Präsentation der ausgelesenen Daten. Oftmals sind nicht alle Daten von Interesse, sondern man sucht ganz spezielle Daten wie z.B. Texte innerhalb von Zellen, die man auslesen oder ändern möchte. Das Ändern der Daten werden wir später noch behandeln, im nächsten Teile beschäftigen wir uns mit dem sogenannten Propertyhandler, der eine weitere Möglichkeit bietet, Daten auszulesen.