Eines der immer wiederkehrenden Themen in AutoLisp ist die
Behandlung von Block-Attributen. Deshalb möchte ich den Umgang
damit hier als Beispiel für die Verwendung von lambda-expressions
vorstellen. Die Werte von Attributen werden immer als Zeichenketten
abgelegt, mit einem anderen Datentyp haben wir es nicht zu tun.
Nun kommen wir zum Zusammenfügen der Teile: Die nächste Funktion
dient zur recht allgemeinen Auswahl von Inserts mit Attributen
in einer Zeichnung. Es wird eine Liste von Entitynamen zückgegeben,
die alle Blöcke enthält, bei denen die Evaluation der übergebenen
lambda-expression wahr wurde.
(defun sel-inserts
(blnamepat attnamepat lambda-expr / tmp retlist)
(ss-foreach
(ssget "X"
(list
'(0 . "insert")
(cons 2 blnamepat)
)
)
'(lambda(ins / )
(if(test-attributes ins attnamepat lambda-expr)
(setq retlist(append retlist(list ins)))
)
)
)
retlist
)
Die hohe Flexibilität der Funktion wird dadurch erreicht, dass
-
der verwendete ssget-Aufruf wcmatch verwendet
(das ist bei ssget einfach so)
-
der Attribut-Name ebenfalls durch wcmatch verglichen
wird (dafür haben wir in test-attributes gesorgt)
-
und wir das Ganze dann noch mit einem weiteren wcmatch
im zu übergebenden lambda-Ausdruck aufrufen können
Nachfolgend einige Beispiele, wie flexibel (sel-inserts ...)
verwendet werden kann:
; Alle Blöcke namens B1, bei denen das
; Attribut Laenge einen Wert von mehr
; als 1000 hat
(sel-inserts
"B1"
"Laenge"
'(lambda(laenge / )(> (atof laenge) 1000))
)
; Alle Blöcke namens B1, bei denen eines der
; drei angegebenen Attribute einen Wert von mehr als
; 1000 hat
(sel-inserts "B1" "Laenge,Breite,Hoehe"
'(lambda(mass / )(> (atof mass) 1000))
)
; Alle Blöcke in der Zeichnung, die ein Attribut
; Laenge haben
(sel-inserts "*" "Laenge" '(lambda(ist-egal / )'T))
; Alle Blöcke in der Zeichnung, die überhaupt ein
; Attribut haben
(sel-inserts "*" "*" 'and)
; Alle Blöcke in der Zeichnung, deren Name mit einer
; Ziffer endet und die ein Attribut haben, dessen
; Name mit einem Buchstaben anfängt und in dessen Wert
; ein Umlaut vorkommt
(sel-inserts
"*#"
"@*"
'(lambda(wert / )(wcmatch wert "*[äöüÄÖÜ]*"))
)
Diese Beispiele sollten genügen, um zu zeigen, wie man mit diesen
vier Funktionen auf Blöcke bzw. deren Attribute zugreifen kann.
Zu beachten sind die beiden Beispiele, bei denen der übergebene
lambda-Ausdruck immer T zurückgibt. Im ersten Falle ist es offensichtlich,
da es explizit ausgeschrieben wurde.
Der zweite Fall, bei dem (and ...) verwendet wird, mag vielleicht
auf Anhieb nicht so einsichtig sein. Machen wir uns aber klar, dass
ein Aufruf von and mit einem einzigen Argument immer T zurückgibt,
wenn das Argument nicht nil ist, dann wird klar, dass wir hier
mit weniger Schreibaufwand genau zum gleichen Ergebnis kommen wie beim
expliziten Ausschreiben der lambda-expression. Und wenn wir noch etwas
weniger Aufwand beim Schreiben haben möchten, dann tut's or
natürlich ganz genauso!