| |
| Gut zu wissen: Hilfreiche Tipps und Tricks aus der Praxis prägnant, und auf den Punkt gebracht für Autodesk Produkte |
| |
| Request a special discount on NVIDIA RTX 5000 Ada Generation GPU !, eine Pressemitteilung
|
Autor
|
Thema: Attributfunktionen von advanced.autolisp.info - wie XREFs filtern? (1193 mal gelesen)
|
JohannW. Mitglied
Beiträge: 14 Registriert: 29.10.2013 Windows 7 Enterprise SP2 Core i5-2520M 8 GB RAM<P>AutoCAD 2013
|
erstellt am: 18. Feb. 2014 10:00 <-- editieren / zitieren --> Unities abgeben:
Hallo zusammen! Seit einiger Zeit setze ich diese Attributfunktionen ein - bisher funktionierten sie auch wunderbar, jetzt bin ich aber auf ein Problem gestoßen: In einigen Dateien streikt die Routine bei diesem Aufruf: Code: (sel-inserts "*" "*" '(lambda (wert / ) (wcmatch wert "*blabla*")))
Ich will also alle Blöcke mit beliebigen Namen auswählen, die in einem beliebigen Attribut den Wert *blabla* enthält. ; Fehler: Fehlerhafter Argumenttyp: lentityp nil VLIDE nennt als Quelle für die letzte Unterbrechung manchmal test-attributes (1) oder die erste Zeile von insert-getattdata (2) - Sobald ich beim ersten Argument die Auswahl einschränke (z.B. "*blockname" statt "*") funktioniert es. - Sobald ich alle XREFs aus der Zeichnung entferne, funktioniert auch die originale Variante. Das Programm holt sich am Anfang mittels SSGET alle INSERTs aus der Zeichnung, damit natürlich auch alle verwendeten XREFs, und verschluckt sich anscheinend in weiterer Folge daran. Mein Lösungsansatz wäre, den Auswahlsatz zu durchlaufen und alle XREFs über den GC 70 . 4 herauszufiltern - ist das ein gangbarer Weg und an welcher Stelle filtere ich am besten? Hier nochmal die komplette Routine mit meinen Markierungen: Code: (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) ;(1) (setq retlist(append retlist(list ins))) ) ) ) retlist )(defun ss-foreach(ss expr / i) (if ss (repeat(setq i(sslength ss)) ((eval expr)(ssname ss(setq i(1- i)))) ) ) ) (defun insert-getattdata(ent / retl) (setq ent(entget(entnext(cdr(assoc -1(entget ent)))))) ;(2) (while(= "ATTRIB"(cdr(assoc 0 ent))) (setq retl(cons ent retl)) (setq ent(entget(entnext(cdr(assoc -1 ent))))) ) (reverse retl) ) (defun test-attributes(insert namepat l-expr / atts result) (setq atts(insert-getattdata insert)) (while atts (if (and (wcmatch (strcase(cdr(assoc 2(car atts)))) (strcase namepat) ) (apply l-expr(list(cdr(assoc 1(car atts))))) ) (progn (setq result(car atts)) (setq atts nil) ) (setq atts(cdr atts)) ) ) result )
Vielen Dank schonmal für jeden Hinweis! lg Johann Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Brischke Moderator CAD on demand GmbH
Beiträge: 4187 Registriert: 17.05.2001 AutoCAD 20XX, defun-tools (d-tools.eu)
|
erstellt am: 18. Feb. 2014 10:08 <-- editieren / zitieren --> Unities abgeben: Nur für JohannW.
|
JohannW. Mitglied
Beiträge: 14 Registriert: 29.10.2013 Windows 7 Enterprise SP2 Core i5-2520M 8 GB RAM<P>AutoCAD 2013
|
erstellt am: 18. Feb. 2014 10:47 <-- editieren / zitieren --> Unities abgeben:
Hallo Holger! hier mal zum Vergleich die GC-Liste von einem "normalen" INSERT: Code: ( (-1 . <Objektname: 7fffb4dac10>) (0 . "INSERT") (330 . <Objektname: 7fffb41a9e0>) (5 . "2B8A31") (100 . "AcDbEntity") (67 . 0) (410 . "Model") (8 . "-Layer-") (100 . "AcDbBlockReference") (66 . 1) (2 . "-Blockname-") (10 192481.0 248035.0 0.0) (41 . 1.0) (42 . 1.0) (43 . 1.0) (50 . 0.0) (70 . 0) (71 . 0) (44 . 0.0) (45 . 0.0) (210 0.0 0.0 1.0) )
... und einem XREF: Code: ( (-1 . <Objektname: 7fffb224dd0>) (0 . "INSERT") (330 . <Objektname: 7fffb41a9e0>) (5 . "2D9ED5") (100 . "AcDbEntity") (67 . 0) (410 . "Model") (8 . "-Layer-") (100 . "AcDbBlockReference") (2 . "-XrefName-") (10 0.0 0.0 0.0) (41 . 1000.0) (42 . 1000.0) (43 . 1000.0) (50 . 0.0) (70 . 0) (71 . 0) (44 . 0.0) (45 . 0.0) (210 0.0 0.0 1.0) )
Wenn ich das richtig sehe, kann ich beim initialen SSGET ja gar nicht unterscheiden, ob es ein normales INSERT oder XREF ist, oder? D.h. die Unterscheidung muss/kann erst später passieren?! Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
cadffm Moderator 良い精神
Beiträge: 22275 Registriert: 03.06.2002 Alles
|
erstellt am: 18. Feb. 2014 10:53 <-- editieren / zitieren --> Unities abgeben: Nur für JohannW.
Oder man erstellt einen Namenfilter (gc2) in dem man vorher ermittelt welche Blöcke nicht Xrefabhängig sein. Der Aufwand ist aber nur sinnig wenn der User die Auswahl vornimmt (man könnte dann keine Xrefabhängigen Inserts wählen), wenn die Routine so wie so nur programmintern läuft, würde ich es in jedem Fall hinterher machen. ------------------ CAD on demand GmbH - Beratung und Programmierung rund um AutoCAD Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Andreas Kraus Mitglied Elektrotechniker
Beiträge: 1455 Registriert: 11.01.2006 WIN 10 ACAD 2022 BricsCAD V23
|
erstellt am: 19. Feb. 2014 11:03 <-- editieren / zitieren --> Unities abgeben: Nur für JohannW.
Hallo Johann, der Fehler kommt wenn Blöcke ohne Attribute bearbeitet werden. Damit geht's: Code: (defun insert-getattdata (ent / retl) (if (= (cdr (assoc 66 (entget ent))) 1) (progn (setq ent (entget (entnext (cdr (assoc -1 (entget ent)))))) ;(2) (while (= "ATTRIB" (cdr (assoc 0 ent))) (setq retl (cons ent retl)) (setq ent (entget (entnext (cdr (assoc -1 ent))))) ) (reverse retl) ) ) )
------------------ Geht nicht, gibts nicht Gruß Andreas http://kraus-cad.de Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
cadffm Moderator 良い精神
Beiträge: 22275 Registriert: 03.06.2002 Alles
|
erstellt am: 19. Feb. 2014 11:22 <-- editieren / zitieren --> Unities abgeben: Nur für JohannW.
Zitat: Original erstellt von Andreas Kraus: der Fehler kommt wenn Blöcke ohne Attribute bearbeitet werden.
Die Rückgaben beider Codes sollten identisch sein, zudem ist deine Prüfung auf 66=1 überflüssig. (denn wenn dem Insert kein Attribut anhängt, dann wird auch die Whilebedingung nicht erfüllt) Und wenn ich jetzt daneben liegen sollte, erkläre mir noch mal den Unterschied zwischen beiden Codes. ------------------ CAD on demand GmbH - Beratung und Programmierung rund um AutoCAD Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
CADmium Moderator Maschinenbaukonstrukteur
Beiträge: 13527 Registriert: 30.11.2003 .
|
erstellt am: 19. Feb. 2014 11:31 <-- editieren / zitieren --> Unities abgeben: Nur für JohannW.
|
Andreas Kraus Mitglied Elektrotechniker
Beiträge: 1455 Registriert: 11.01.2006 WIN 10 ACAD 2022 BricsCAD V23
|
erstellt am: 19. Feb. 2014 15:04 <-- editieren / zitieren --> Unities abgeben: Nur für JohannW.
Thomas hat ja schon geantwortet wegen dem entget und dem nil. Find ich sogar schöner als die Prüfung von GC66. Merk ich mir :-). ------------------ Geht nicht, gibts nicht Gruß Andreas http://kraus-cad.de Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
JohannW. Mitglied
Beiträge: 14 Registriert: 29.10.2013 Windows 7 Enterprise SP2 Core i5-2520M 8 GB RAM<P>AutoCAD 2013
|
erstellt am: 24. Feb. 2014 13:49 <-- editieren / zitieren --> Unities abgeben:
Zitat: (entget (entnext ... nix gegen kompakten Code .. aber wenn entnext ins Leere läuft und Nil liefert .. gibt der entget Aufruf einen Fehler ...ich finde da (if (setq Ent(entnext ...)) (setq ent(entget ent)) ... sicherer
Wiedermal vielen, vielen Dank! Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |