Ein paar Worte vorabHome   Letzte MeldungenNews   Index der Kapitel und der besprochenen FunktionenIndex   Wer ich bin, warum ich diese Seiten mache, KontaktImpressum   Ich freue mich über jeden Eintrag im Gästebuch!Gästebuch   Einige Links zu anderen AutoLisp-SeitenLinks   Copyrights und DisclaimerRechts
Hier können die kompletten Seiten als ZIP-File heruntergeladen werden!

Berechnen von arithmetischen Ausdrücken in der Kommandozeile Sitz!Platz!Fass!
Das Verschachteln von Ausdrücken Alte Schachtel!
Das Speichern von Werten in Variablen Gebunkert
Verhindern der Evaluation mit Quote Bergbäche
Erzeugen von einfachen Listen in AutoLisp Brot,Eier,Käse
Einfache Funktionen zur Listenbearbeitung ...um die Wurst
Funktionen für den Zugriff auf Listenelemente Was ein Salat!
Über Haupt- und Nebeneffekte von Funktionen Schwer schuften
Das Definieren von eigenen Funktionen in AutoLisp Ostfriesischer...
Lokale Variablen und Funktionsargumente in AutoLisp Kondome!
Das Laden von Programmdateien in AutoLisp Banküberfall
Verzweigung in Funktionen aufgrund von Entscheidungen Wenn das Wort...
Zusammenfassen von Entscheidungen mit den Logik-Funktionen Ins Schweinderl
Mehrfach-Verzweigungen in AutoLisp mit Cond 3. Strasse links
Schleifen zum Steuern des Ablaufs in AutoLisp-Funktionen Wie im Fernsehen
Testfunktionen zum Steuern von Schleifen in AutoLisp Schwanger?
Gleichheitstests als Schleifenkriterium in AutoLisp Noch gleicher?
Zeichneketten-Bearbeitung in AutoLisp Rauchzeichen
Funktionen zur Konvertierung von Datentypen in AutoLisp Wasser zu Wein
Komplexere Funktionen für die Bearbeitung von Listen in AutoLisp Nicht arbeiten...
Das Erzeugen von anonymen Funktionen mit lambda Schwarze Kutte
Das Bearbeiten von Listenelementen mit foreach Jedem das Seine
Erzeugen und Verwenden von Assoziationslisten in AutoLisp Beim Psychiater
Zugriff auf Geometriedaten und Erzeugen von Geometrieelementen Ententanz
Der Umgang mit Auswahlsätzen in AutoLisp Jung gefreit, ...
Auswahl von AutoCAD-Zeichnungsgeometrie mit ssget Raffgierig!
Verändern von Zeichnungs-Geometrie mit entmod Flickschusterei
Das Erzeugen von Geometrie mit entmake Houdini
Über Programmierstile in AutoLisp, Teil 1 Emma
Über Programmierstile in AutoLisp, Teil 2 Sti(e)lblüten
Über Programmierstile in AutoLisp, Teil 3 Eingewickelt
Über Programmierstile in AutoLisp, Teil 4 Doofe Frisur?


Zum den Seiten für Fortgeschrittene

Zu den ActiveX-Seiten

Meine Private HP mit Fotos, Gedichten, Musik und Postkartenversand

Mein Online-Lexikon der Fotografie

Mein völlig abgedrehtes Reisebüro










Die Funktion (ssget ...) ist wohl die komplexeste Funktion überhaupt in AutoLisp. Nicht, dass sie in irgendeiner Weise schwer zu begreifen wäre - aber sie kann eine Unmenge verschiedener Argumente erhalten und durch diese bedingt sich völlig unterschiedlich verhalten. Die Rückgabe ist auf jeden Fall ein Auswahlsatz - oder nil, wenn gar nichts gewählt wurde. Dieser kleine Bug wurde schon an anderer Stelle besprochen.

Wir kennen Aufrufe von (ssget) bereits, aber ohne Argumente. In diesem Fall kann der Benutzer Elemente aus der Zeichnung auswählen, und zwar ohne jede Einschränkung, also was und wieviel er will. (ssget) kann aber auch dazu benutzt werden, die Zeichnung nach bestimmten Elementen zu durchsuchen, ohne dass der Benutzer irgendwie involviert wird. Werfen wir einen Blick auf ein Beispiel:
(ssget "X" '((0 . "LINE")))
                  
Der (ssget)-Aufruf erhält hier zwei Argumente. Das Zeichen "X" ist ein Code, der mitteilt, dass keine Anfrage an den Benutzer stattfinden soll, sondern dass die Zeichnungsdatenbank durchsucht werden soll. Dieser Code hat absolut nichts mit Lisp zu tun, er gilt nur für (ssget)! Und natürlich gibt es nicht nur diesen einen. Das zweite Argument ist eine Liste mit Unterlisten. In unserem Beispiel ist allerdings nur eine Unterliste darin enthalten, und auch hier sehen wir wieder die bereits bekannten Paarungen aus DXF-Gruppencode und Wert.

Wie Sie bereits vermuten: Dieser Aufrufvon (ssget) gibt uns einen Auswahlsatz zurück, der alle in der Zeichnung vorkommenden Linien enthält. Linien, die Bestandteile von Blöcken sind, sind aber nicht enthalten - der Zugriff auf Unterelemente von Blöcken ist noch einmal eine ganze Ecke komplizierter.

Die Liste mit den Gruppencodes kann mehr als ein Element haben. Wir fügen noch ein weiteres Paar hinzu:
(ssget "X" '((0 . "LINE")(8 . "0"))
                  
(ssget) sucht uns jetzt alle Entities aus der Zeichnung heraus, auf die beide Eigenschaften zutreffen: Wir erhalten einen Auswahlsatz mit allen Linien, die auf Layer 0 liegen. Natürlich können wir weitere Bedingungen hinzufügen:
(ssget "X" '((0 . "LINE")(8 . "0")(62 . 256))
                  
Jetzt bekommen wir alle Linien auf Layer 0, die die Farbe Vonlayer haben (dass wir auch hier wieder die Farbe 256 verwenden können, freut uns - schliesslich hat ja das Entity eigentlich gar keinen Gruppencode 62. Aber das haben wir schon im Kapitel über (entget) geklärt). Je mehr Paarungen wir allerdings als Suchkriterien verwenden, umso mehr müssen natürlich aufpassen, dass sie widerspruchsfrei bleiben. Das nächste Beispiel wird zwar von (ssget) ohne Beanstandung angenommen, aber wir werden immer nur ein nil zurückbekommen:
(ssget "X"
 '((0 . "LINE")(8 . "0")(62 . 256)(40 . 10.0)
)
                  
Eine Linie hat nun mal keinen Gruppencode 40 - (ssget) wird zwar brav vergleichen, aber nie etwas finden!

Ein paar weitere Beispiele:
(ssget "X" '((62 . 1)(67 . 1)))
; Alle roten Entities im Papierbereich

(ssget "X" '((0 . "3DFACE")(70 . 8)))
; Alle 3D-Flächen, bei denen alle 4
; Kanten als unsichtbar markiert sind

(ssget "X" '((0 . "INSERT")(2 . "Schraube")))
; sucht alle Referenzen des Blocks 'Schraube'
                  
Beim letzten der drei Beispiele drängt sich eine Frage auf: Wie ist es mit der Gross-/Kleinschreibung? Werden die Inserts auch gefunden, wenn man 'schraube' oder 'SCHRAUBE' oder sogar 'SCHRaubE' schreibt? Entwarnung! Sie werden auf jeden Fall gefunden. Auch den Entity-Typ kann man klein schreiben, wenn auch AutoCAD die Entity-Typen immer in Grossbuchstaben zurückgibt. Und selbst der Steuercode wird grosszügig interpretiert: Ein kleines "x" tut's auch und spart obendrein noch Tinte.

Jeder, der eine Suchmaschine vernünftig betätigen kann, weiss: Wo ein UND ist, da ist auch ein ODER. Dazu hat sich AutoDESK weitere Rauchzeichen einfallen lassen. Es wird jetzt aber nicht das "X" durch ein "Y" ersetzt - nein, ein bisschen komplizierter ist es schon. Für eine ODER-Verknüpfung müssen wir die Liste um bestimmte Paarungen erweitern:
(ssget "X"
 '( (-4 . "<OR")
      (0 . "LINE")
      (62 . 2)
    (-4 . "OR>")
  )
)
                  
Der (ssget)-Aufruf wird nun schon so lang, dass er nicht mehr in eine Zeile passt. Was passiert da? Der Gruppencode -4 ist eigens für die Funktion (ssget) reserviert, d.h. dass er zum Einen niemals in einer DXF-Datei vorkommen kann, und zum Anderen auch niemals in einer Datenliste, wie sie (entget) liefert. Es ist nichts weiter als ein Steuerzeichen für (ssget).

Die eigentlichen Steuerzeichen sind natürlich die Zeichenketten, die mit dem Gruppencode -4 verbunden sind. "<OR" leitet das ODER ein, "OR>" schliesst es ab. Diese Steuercodes müssen übrigens immer genau ausgeglichen sein - (ssget) gibt immer nil zurück, wenn sie es nicht sind!

Die Bedeutung von ODER sollte klar sein: Hier wird das herausgefiltert, was ein Kreis ist ODER gelb ODER beides - das ODER ist kein Entweder-Oder. Wenn wir das exklusive oder meinen, dann müssen wir die Steuerzeichen "<XOR" und "XOR>" verwenden. Ferner gibt es dann noch "<NOT" und "NOT>" sowie "<AND" und "AND>". Die beiden letzten umgeben sozusagen immer implizit die Filterliste, auch wenn sie nicht mitgeschrieben werden.

Es kann vorkommen, dass in einer Zeichnung verschiedene INSERTs eines Blocks unterschiedliche Attribute haben. Das entsteht, wenn der Block zwischendurch neu mit anderen Attributen definiert wird. Nehmen wir mal an, wir haben es mit einem Block namens 'Befestigung' zu tun, die neueren Inserts haben Attribute, die älteren haben keine. Wie können wir die älteren herausfischen?
(ssget "X"
 '( (0 . "insert")
    (2 . "Befestigung")
    (-4 . "<not")
      (70 . 1)
    (-4 . "not>")
  )
)
                  
Gruppencode 70 hat den Wert 1, wenn ein INSERT Attribute hat. Diese Bedingung muss hier aber negiert werden, da wir ja nach den INSERTs suchen, die keine haben.

Aber die Sache kann noch komplizierter werden: Es gibt nicht nur einen Block 'Befestigung', sondern 'Befestigung001' usw. (es gibt ja soooo viel zu befestigen). Es kommt uns sehr entgegen, dass (ssget) mit den Wildcards der Funktion (wcmatch) arbeitet. Diese gehen allerdings über die DOS-Wildcards ? und * weit hinaus - ein Blick in die Hilfe zu (wcmatch) lohnt sich also.

Für unser Beispiel reicht allerdings erst einmal ein Sternchen:
(ssget "X"
 '( (0 . "insert")
    (2 . "Befestigung*")
    (-4 . "<not")
      (70 . 1)
    (-4 . "not>")
  )
)
                  
Diese Variante filtert uns also alle Blöcke heraus, deren Name mit 'Befestigung' beginnt. Oft möchte man auch alle INSERTs überhaupt finden, aber nicht die anonymen, die von AutoCAD erzeugt werden (und die nur '*137' usw heissen). Auch hier hilft das eingebaute (wcmatch) weiter: Das nächste Beispiel sucht alle Blöcke, die nicht anonym sind, keine Attribute haben und auf Layer "0" liegen, jedoch nicht im Papierbereich, un deren Name vier Zeichen lang ist:
(ssget "X"
 '( (0 . "insert")
    (-4 . "<not")
      (-4 . "<AND")
        (2 . "`**")
        (70 . 1)
        (67 . 0)
      (-4 . "AND>")
    (-4 . "not>")
    (2 . "????")
  )
)
                  
Zwischen "<not" und "not>" darf übrigens immer nur ein Element stehen: Das automatische UND, was wir für die ganze Liste haben, gilt hier nicht mehr. Deshalb müssen mehrere negierte Elemente wie im Beispiel wieder mit "<and" und "and>" zusammengefasst werden. Das ` vor den beiden Sternen muss so sein: Der erste Stern soll als Stern interpretiert werden, der zweite als Wildcard (siehe Hilfe zu (wcmatch).

Dies sollte erst einmal genügen als Einstieg in (ssget), es gibt aber noch viel mehr Optionen. Das Thema wird jedoch in einem der nächsten Kapitel fortgesetzt. Und noch ein Hinweis: Bei der Arbeit mit AutoCAD (damit meine ich das Zeichnen, nicht das Programmieren) hat sich (ssget) bestens bewährt! Ein kleiner eingetippter Aufruf kann mühsame Klickerei vermeiden. Der neue Befehl QSELECT, der im Eigenschaftsfenster eingebaut ist, aber auch explizit aufgerufen werden kann, hat gegenüber (ssget) den Nachteil, dass er wesentlich langsamer ist.

Ich hatte einmal mit einer 150MB-Zeichnung zu tun, bei der QSELECT fast 20 Minuten brauchte, um bestimmte Objekte zu filtern. Ein (ssget)-Aufruf über die Kommandozeile erledigte genau die gleiche Aufgabe in weniger als 10 Sekunden! Ich habe keine Ahnung, warum das so ist, aber ich habe das schon öfters beobachtet.


Übungsaufgaben

  1. Welche der folgenden Aussagen sind richtig?
    • Bei der Arbeit mit (ssget) können nur Gruppencodes verwendet werden, die auch in DXF-Dateien vorkommen.

    • Bei der Code-Zeichenkette "X" muss man nicht darauf achten, ob man "X" oder "x" schreibt

    • Wenn die Filterung mit (ssget) nichts findet, wird ein leerer Auswahlsatz zurückgegeben.

    • Wenn keine Angaben gemacht werden, gilt in der (ssget)-Filterliste ein implizites logisches UND

    • Am Ende der Filterliste müssen die logischen Verknüpfungen nicht mehr geschlossen werden, wenn Eindeutigkeit besteht.

    • Für die logischen Verknüpfungen in der Filterliste gibt es sechs verschiedene Werte für den Gruppencode -4.

    • Wenn ich alle gelben und alle grünen Elemente wählen möchte, genügt die implizite UND-Verknüpfung

  2. Filtern Sie mit (ssget):
    • ...alle gelben Kreise und alle Bögen (egal welcher Farbe)

    • ...alle Blöcke, die auf Layer 0 liegen, deren Name aber nicht mit einem 'E' beginnt und die nicht anonym sind

    • ...alle Bemassungen, die nicht auf einem Layer liegen, dessen Name mit 'Bem' anfängt

  3. Denken Sie sich weitere solche Aufgaben aus, lösen Sie sie, prüfen Sie sie noch einmal sorgfältig, und dann mailen Sie sie mir, damit ich sie hier noch reinsetzen kann!
Lösungen