VBA-Einstig 
fĂŒr AutoCAD Teil 2
Startseite
VBA EinfĂŒhrung fĂŒr
BricsCad und AutoCAD

In der vergangenen Ausgabe unserer VBA-EinfĂŒhrung haben Sie ein wenig von der Entwicklungsumgebung kennen gelernt, einen Kreis vom Programm in AutoCAD zeichnen lassen und sogar ein erstes kleines MenĂŒ entwickelt. Wer sich etwas ernsthafter mit der VBA-Programmierung beschĂ€ftigt, wird immer wieder vor der Aufgabe stehen, bereits vorhandene AutoCAD-Elemente zu verarbeiten. DafĂŒr gibt es verschiedene Möglichkeiten. Nachfolgend sollen zwei Wege beschrieben werden, nĂ€mlich die Klassen Utility und Selectionset.
Im letzten Teil der VBA-EinfĂŒhrung haben Sie bereits das Utility-Objekt zur interaktiven Koordinatenabfrage kennen gelernt. Neben verschiedenen anderen Methoden stellt es auch die GetEntity-Funktion zur VerfĂŒgung. Sie wird dazu benutzt, um den Anwender ein Zeichnungsobjekt auswĂ€hlen zu lassen. Allerdings wirklich nur genau ein Element. Sollen mehrere Zeichnungsobjekte selektiert werden, gibt es dafĂŒr das anschließend etwas nĂ€her besprochene Selectionset. Um GetEntity zu testen, starten Sie AutoCAD, zeichnen einige Elemente (z.B. Kreise, Linien, Polylinien etc.) und rufen anschließend VBA mittels der Tastenkombination „Alt-F11“ auf.
Jetzt können Sie folgende kleine Prozedur schreiben, die Sie auffordert, ein Zeichnungselement zu selektieren und anschließend dessen Namen ausgibt.

Public Sub zz1()
Dim Auswahl As acadObject
Dim Punkt As Variant

Utility.GetEntity Auswahl, Punkt, "WĂ€hlen Sie ein Element"
MsgBox Auswahl.ObjectName

End Sub

In vielen FÀllen ist allerdings mehr als ein Element in der Zeichnung auszuwÀhlen. In der Klasse AcadSelectionSets werden Ihnen vielfÀltig einsetzbare Methoden an die Hand gegeben, um Zeichnungselemente interaktiv oder auch im Hintergrund zu selektieren. Um einen solchen Auswahlsatz anzulegen, sollte er zunÀchst mit einer Dim- oder Public-Anweisung deklariert werden.

Dim Sset as AcadSelectionset

Angelegt wird der Auswahlsatz mit folgender Programmzeile.

Set Sset1 = ThisDrawing.SelectionSets.Add("Auswahl1")

Nun können Sie Ihrem Auswahlsatz verschiedenste Elemente hinzufĂŒgen. Hier die dafĂŒr am hĂ€ufigsten gebrauchten Methoden:

 

Select

Filtern von AutoCAD-Elementen im Hintergrund (also ohne Nutzereingabe).

SelectAtPoint

Auswahl eines Elements an einem bestimmten Punkt (Koordinate). Diese Anweisung Àhnelt (!) der GetEntity-Methode, allerdings ohne Abtasten einer Koordinate durch den Nutzer.

SelectByPolygon

Auswahl von Elementen die innerhalb eins Polygons liegen

SelectOnSrceen

Auswahl von Elementen durch den Anwender


Neben den Besonderheiten jeder einzelnen Methode, haben alle eines gemeinsam. Die Elemente können auch noch nach verschiedenen Eigenschaften gefiltert werden. So ist es beispielsweise möglich, alle Polylinien der Zeichnung zu ermitteln, die auf einem bestimmten Layer liegen, oder alle bestimmte Blöcke zu selektieren, die einen ganz bestimmten EinfĂŒgepunkt haben.

Zur Verdeutlichung ein erstes Beispiel, in dem Sie interaktiv mehrere Zeichnungselemente auswĂ€hlen und deren Objektnamen in einer Message-Box zur Anzeige bringen. Zum Einstieg verzichten wir zunĂ€chst auf die genannte Filtermöglichkeit. Bevor Sie die Prozedur starten, sollten Sie natĂŒrlich erst verschiedene Elemente zeichnen.

Public Sub Elementliste()
Dim Sset As AcadSelectionSet
Dim Auswahl As acadObject
Dim Liste As String

Set Sset = ThisDrawing.SelectionSets.Add("Elemente1")
Sset.SelectOnScreen
For Each Auswahl In Sset
    Liste = Liste & vbCrLf & Auswahl.ObjectName
Next
MsgBox Liste
Sset.Delete
End Sub

Eingangs werden die erforderlichen Variablen deklariert. Mit „Set Sset=
“ erzeugen Sie einen zunĂ€chst noch leeren Auswahlsatz. Die Zeile „Sset.SelectOnScreen” fĂŒhrt dann dazu, dass Sie in der AutoCAD-Kommandozeile aufgefordert werden, Objekte am Bildschirm auszuwĂ€hlen. Bitte beachten Sie, dass diese Anweisung noch mit Filter-Parametern ergĂ€nzt werden kann, dazu gleich mehr.

Wenn Sie Ihre Auswahl am Bildschirm mit der rechten Maustaste oder der Eingabetaste abgeschlossen haben, wird in der folgenden For-Next-Schleife der Auswahlsatz Element fĂŒr Element durchsucht. Mit jedem Schleifendurchlauf fĂŒllt sich die Liste um ein weiteres Element. Wenn die Schleife abgearbeitet ist, wird die gefĂŒllte Liste in einer Messagebox zur Anzeige gebracht. Vor dem Abschluß der Prozedur erzwingt „Sset.Delete“ das Löschen des Auswahlsatzes aus der Menge der SelectionSets. Erfolgt das nicht, wĂŒrde beim nĂ€chsten Aufruf Ihres Programms eine Fehlermeldung erscheinen, die sagt, dass der Auswahlsatz bereits existiert. Bitte die „Delete-Anweisung“ nicht mit der „Erease-Anweisung“ verwechseln. Letztere löscht den Inhalt des Auswahlsatzes (einschließlich der Zeichnungselemente), lĂ€sst ihn aber als dann leeres Selectionset in der Zeichnung. Am einfachsten, Sie probieren es selbst einfach aus.

Wie eingangs angedeutet, bietet das Selectionset die Möglichkeit, Elemente bei der Auswahl zu filtern, was Ă€hnlich wie der FILTER-Befehehl von AutoCAD zu verstehen ist. Die folgende Prozedur wird das verdeutlichen. Sie ist ein wenig komplexer und arbeitet mit zwei Selectionsets. Zeichnen Sie zunĂ€chst jeweils mehrere Polylinie auf den beiden Layern „Layer1“ und Layer2“. Die Aufgabe des Programms besteht grundsĂ€tzlich darin, die GesamtlĂ€nge der Polylinien auf einem bestimmten Layer zu berechnen. Ein grundsĂ€tzlicher Ablauf könnte nun so aussehen (viele Wege fĂŒhren zum Programm), dass alle Polylinien der Zeichnung gewĂ€hlt werden, und aus dieser Menge die von Layer2 zur Berechnung genommen werden.

Public Sub Tool_LenPoly()
'Ermittlung der LĂ€nge von Polylinien
Dim Sset As AcadSelectionSet
Dim fCode() as Integer
Dim fWert as Variant
Dim selOb as acadObject
Dim Onam as String
Dim Gesamt as Double
Dim POLin as AcadPolyline
Dim LWLin as AcadLWPolyline

Set Sset = ThisDrawing.SelectionSets.Add("sset08")
ReDim fCode(6): ReDim fWert(6)
fCode(0) = -4: fWert(0) = "<AND"
fCode(1) = -4: fWert(1) = "<OR"
fCode(2) = 0: fWert(2) = "lwpolyline"
fCode(3) = 0: fWert(3) = "polyline"
fCode(4) = -4: fWert(4) = "OR>"
fCode(5) = 8: fWert(5) = "Layer1"
fCode(6) = -4: fWert(6) = "AND>"

Sset.Select acSelectionSetAll, , , fCode, fWert
Gesamt = 0
For Each SelOb In Sset
    If SelOb.ObjectName = "AcDb2dPolyline" Then
        Set PoLin = SelOb
        Gesamt = Gesamt + POLin.Length
    End If
    If SelOb.ObjectName = "AcDbPolyline" Then
        Set LwLin = SelOb
        Gesamt = Gesamt + LWLin.Length
    End If
Next
AnzPoly = Sset.Count
MsgBox (LaePol)
Sset.Delete
End Sub

Hier nun die ErklĂ€rung einiger Besonderheiten. Nach der schon bekannten Erzeugung eines Auswahlsatzes mit „Set Sset = ThisDrawing.SelectionSets.Add("Auswahl")“ erfolgt die Definition des Filters. Er besteht immer aus zwei Komponenten. Erstens dem so genannten DXF-Gruppencode und zweitens dem eigentlichen Filterwert. Der Gruppencode ist vom Typ Integer und der Filterwert vom Typ Variant (siehe Deklarationen). In jedem Fall mĂŒssen es Arrays sein, deren Dimensionierung mit der Anzahl der Parameter identisch ist. Bitte beachten Sie, dass die ZĂ€hlung ĂŒblicherweise bei 0 beginnt. Zum hoffentlich besseren VerstĂ€ndnis sei die Filterdefinition hier erst mal in einer logischen Operation dargestellt:

Auswahl = ((Objekttyp=“Polyline“ ODER Objekttyp=“LWPolyline“) AND Layer=”Layer2”)

Dementsprechend sieht Ihr Programm aus. Mit : „fWert(0) = "<AND"“ öffnen Sie die UND-VerknĂŒpfung und in der folgenden Zeile die ODER-VerknĂŒpfung. Der DXF-Code fĂŒr logische VerknĂŒpfungen ist in beiden FĂ€llen „-4“. Die beiden nĂ€chsten Zeilen geben die Filterbedingungen fĂŒr die Linientypen an. Hier ist der Gruppencode „0“ (fĂŒr die Bezeichnung des AutoCAD-Elementtyps). Danach wird die ODER-VerknĂŒpfung geschlossen und es folgt die Layer-Bedingung. Layernamen sind vom Code „8“. Letztlich wird die UND-VerknĂŒpfung geschlossen.

Eine Übersicht ĂŒber alle Gruppencodes finden Sie in der DXF-Hilfe unter dem Abschnitt „Gruppencodes in numerischer Reihenfolge“.

Nachdem Sie die Filterbedingung definiert haben, können Sie endlich alle Objekte auswĂ€hlen. Das erfolgt mit „Sset.Select acSelectionSetAll, , , fCode, fWert”. Die allgemeine Syntax lautet „object.Select Mode[, Point1][, Point2][, FilterType][, FilterData]“. Nach der Select-Anweisung folgt als erster Parameter der Filtermodus, also der Mechanismus, nach dem Objekte ausgewĂ€hlt werden. „acSelectionSetAll“ sagt, dass alle Elemente der Zeichung einbezogen werden sollen. Alternativ könnten Sie den Bereich auch mit „acSelectionSetCrossing“ oder mit „acSelectionSetWindow“ auf einen durch die Punkte Point1 und Point2 definierten Bereich einschrĂ€nken. In unserem Beispiel allerdings werden diese (optionalen) Parameter nicht angegeben, denn es sollen ja alle Elemente in der Zeichnung untersucht werden. Die letzten beiden Parameter verweisen nun auf die vorstehend definierten Filterbedingungen.

Analog dazu hĂ€tten Sie ĂŒbrigens auch im vorstehenden Beispiel die Bildschirmauswahl („SelectOnScreen“) noch mit einem Filter einschrĂ€nken können.

Was nun folgt, ist die Auswertung des Selektionsergebnisses. In der For-Next-Schleife wird jedes im Auswahlsatz enthaltenen Objekt weiter verarbeitet. Genauer gesagt, werden in einem Selectionset nicht die AutoCAD-Elemente selbst gespeichert, sondern nur Verweise auf diese Objekte.

Dazu muss zunĂ€chst der jeweilige Objektname bestimmt werden. Entsprechend dieses Namens unterscheidet die folgende Select-Case-Anweisung, wie mit dem Objekt zu verfahren ist. Handelt es sich um eine Autocad-2D-Polylinie wird, mit „Set POLin = selOb“ zunĂ€chst ein entsprechendes Objekt erzeugt. Das ist erforderlich, um in der nĂ€chsten Zeile mit „POLin.Length“ dessen LĂ€nge abzufragen und zu saldieren.

Analog dazu wird mit LWPolylinien verfahren, oder auch mit (im Beispiel nicht betrachteten) AutoCAD-Linien oder -3D-Polylinien.

Nachdem Sie das Ergebnis in einer Messagebox zur Anzeige gebracht haben, wird zum Schluss der Auswahlsatz wieder gelöscht.

Noch zwei letzte kleine Hinweise fĂŒr heute. Erstens empfiehlt es sich, die Namen der AuswahlsĂ€tze in einer Zeichenketten-Variable zu speichern. Das spart eine lĂ€stige Fehlersuche bei geringfĂŒgigen Schreibfehlern.

Zweitens kann es bei lÀngeren Programmen schon mal passieren, dass man das Löschen eines Auswahlsatzes vergisst. Dem schafft folgende Funktion Abhilfe, die vor der Erzeugung eines Selectionset zunÀchst testet, ob es schon vorhanden ist. Wenn ja, wird es gelöscht. Am Ende der Funktion kann es dann erzeugt werden.

Public Function ssetGen(setName As String) As AcadSelectionSet
Dim sCol As AcadSelectionSets
Dim SS As AcadSelectionSet
Set sCol = ThisDrawing.SelectionSets
For Each SS In sCol
    If SS.Name = setName Then
        sCol.Item(setName).Delete
        Exit For
    End If
Next
Set SS = sCol.Add(setName)
Set ssetGen = SS
End Function

Der Funktionsaufruf wĂŒrde dann mit „Set Sset = ssetGen(„Auswahl“) erfolgen. Viel Spaß beim ausprobieren.

Wird fortgesetzt

IBB INGENIEURBÜRO BATTEFELD  Bochum Nöckerstraße 37c
44879 Bochum
Tel: 0234-94172-0

 Mit Fragen oder Hinweisen wenden Sie sich bitte an
  

IBB INGENIEURBÜRO BATTEFELD  Leipzig Brahestraße 17
04347 Leipzig
Tel: 0341-2330465

Hydraulische Berechnungen - GIS -  Vermessung - BricsCad V8 - Kartierung - AutoCAD - Autodesk  MAP3D - DVGW - Vermessung - GPS - INTERGEO - Free Download von BricsCad - IntelliCAD - BricsCad V7 - Programmierung - Energieversorgung - AutoLISP - VB -  VBA - SQL - SYBASE SQL Anywhere - Individualprogrammierung - Gas - Wasser - Strom - FernwÀrme - Abwasser - Kanal - Kataster - Indirekteinleiterkataster - relationale Datenbanken - SICAD - Netzberechnung - STANET - AutoSTA - Schnittstellen - SQD - SQS - ALK - ALB - EBDS - ISYBAU - GRADIS - AutoCAD
 ---------------------------------------------------------------------------------------------------------------------------