| |
| Gut zu wissen: Hilfreiche Tipps und Tricks aus der Praxis prägnant, und auf den Punkt gebracht für Autodesk Produkte |
| |
| PNY präsentiert die neue NVIDIA RTX A400 und die A1000 Grafikkarte, eine Pressemitteilung
|
Autor
|
Thema: Dynamische Blöcke nach effektiven Namen UND bestimmten Layer auswählen (1469 mal gelesen)
|
kurt.trattner Mitglied Mechanical Plant Engineer
Beiträge: 46 Registriert: 28.05.2014 AutoCAD Mechanical 2012
|
erstellt am: 04. Jun. 2014 12:50 <-- editieren / zitieren --> Unities abgeben:
Hallo liebe Leute Ich habe wieder mal eine Frage. In meinem Programm kann ich bis jetzt mit folgendem Code von bestimmten dynamischen Blöcken Attribute auslesen: Code:
(initget 1 "Valve Tank Pump Motor") ;;Gibt die Blocknamen vor, die ausgewählt werden können (setq blk (getkword "\Specify Blockname: [Valve/Tank/Pump/Motor]")) ;;Eingabemaske mit Blocknamen (if (tblsearch "block" blk) (sssetfirst nil (getblockselection blk)) (princ (strcat "\n" blk " doesn't exist.")) ) (princ) (setq axss (vla-get-activeselectionset adoc)) (vlax-for a axss (setq tmp_get (get-all-atts a)) (setq tmp_data (append (list (vla-get-name a)(vla-get-handle a)) tmp_get)) (setq com_data (cons tmp_data com_data)) (setq tmp_data nil)
(Codeausschnitt für Namensauswahl) Nun möchte ich aber zusätzlich nach dem Namen noch nach dem Layer fragen. Hat bei uns den Zweck, dass wir je nach Lieferumfang einen anderen Layer haben. Somit könnte ich Listen nach Equipment und Lieferumfang erstellen. Ich hoffe ihr könnt mir helfen. Im Anhang befindet sich das aktuelle Tool und ein Beispielbock. Lg. Kurt [Diese Nachricht wurde von kurt.trattner am 04. Jun. 2014 editiert.] [Diese Nachricht wurde von kurt.trattner am 05. Jun. 2014 editiert.] Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
cadffm Moderator 良い精神
Beiträge: 22275 Registriert: 03.06.2002 Alles
|
erstellt am: 04. Jun. 2014 13:12 <-- editieren / zitieren --> Unities abgeben: Nur für kurt.trattner
Also wenn diese Zeilen von dir stammen (so hört es sich an), dann hast du auch kein Problem die Auswahl der Blockreferenzen entweder auf einen Einfügelayer zu begrenzen und nachträglich zu filtern. Daher die Bitte: Konkretisiere mal dein Problem, zeige deinen Versuch und somit wo du hängst.. ------------------ CAD on demand GmbH - Beratung und Programmierung rund um AutoCAD Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
kurt.trattner Mitglied Mechanical Plant Engineer
Beiträge: 46 Registriert: 28.05.2014 AutoCAD Mechanical 2012
|
erstellt am: 04. Jun. 2014 13:35 <-- editieren / zitieren --> Unities abgeben:
Nein der Code ist nicht von mir. Ich habe mein Tool aus verschiedenen Tools bzw. Codestücken die ich im Netz gefunden habe zusammengebaut. Ich habe leider keinen Plan wie ich mit Lisp auf den Layer zugreifen kann. Ein nachträgliches Filtern wäre mir persönlich am liebsten. Also bevor er die Einträge in die Liste schreibt.
[Diese Nachricht wurde von kurt.trattner am 04. Jun. 2014 editiert.] [Diese Nachricht wurde von kurt.trattner am 04. Jun. 2014 editiert.] Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
wronzky Ehrenmitglied V.I.P. h.c. CAD-Dienstleistungen für Architekten
Beiträge: 2154 Registriert: 02.05.2005 CAD: AutoCAD 2.6 bis 2014 ADT 2005 - 2014 Arcibem System: Windows 2000, XP, NO VISTA Internet-Startseite: http://www.archi.de
|
erstellt am: 04. Jun. 2014 13:49 <-- editieren / zitieren --> Unities abgeben: Nur für kurt.trattner
also ohne jetzt getestet zu haben: in der Blockwahlfunktion steht: Code: (list '(0 . "INSERT")
hier einfach den entsprechenden Layer in den ssget-Filter mit reinschreiben: Code: (list '(0 . "INSERT") '(8 . "LAYERNAME")
Sollte funktionieren. Grüsse, Henning ------------------ Henning Jesse VoxelManufaktur Computer-Dienstleistungen für Architekten und Ingenieure http://www.voxelman.de Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
kurt.trattner Mitglied Mechanical Plant Engineer
Beiträge: 46 Registriert: 28.05.2014 AutoCAD Mechanical 2012
|
erstellt am: 04. Jun. 2014 14:24 <-- editieren / zitieren --> Unities abgeben:
|
kurt.trattner Mitglied Mechanical Plant Engineer
Beiträge: 46 Registriert: 28.05.2014 AutoCAD Mechanical 2012
|
erstellt am: 04. Jun. 2014 16:05 <-- editieren / zitieren --> Unities abgeben:
OK ein kleines Problem habe ich doch noch. Wenn ich zuerst eine Liste exportiere und dann eine Eingabe (Block, Layer)tätige die in der Zeichnung nicht vorkommt gibt er mir statt einer leeren Liste immer die vorherige Liste aus. Wie kann man den Listeninhalt aus dem Zwischenspeicher löschen? Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
CADwiesel Moderator CAD4FM UG
Beiträge: 1989 Registriert: 05.09.2000 AutoCAD, Bricscad Wir machen das Mögliche unmöglich
|
erstellt am: 05. Jun. 2014 08:10 <-- editieren / zitieren --> Unities abgeben: Nur für kurt.trattner
|
kurt.trattner Mitglied Mechanical Plant Engineer
Beiträge: 46 Registriert: 28.05.2014 AutoCAD Mechanical 2012
|
erstellt am: 05. Jun. 2014 08:23 <-- editieren / zitieren --> Unities abgeben:
Code: (if (= LayerVar "ANDRITZ-SUPPLY") (ssget "_X" (list '(0 . "INSERT") '(8 . "ANDRITZ-SUPPLY") (cons 2 (apply 'strcat (cons blk (mapcar '(lambda ( x ) (strcat ",`" x)) (LM:getanonymousreferences blk) ) ) ) ) ) ) )
Ich habe bereits (setq x nil) (setq blk nil) und alle möglichen anderen Variablen ausprobiert. Hat es vielleicht irgendwas mit der mapcar oder der lambda funktion zu tun? Egal was ich auch nil setze. Es funktioniert nicht. Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
kurt.trattner Mitglied Mechanical Plant Engineer
Beiträge: 46 Registriert: 28.05.2014 AutoCAD Mechanical 2012
|
erstellt am: 05. Jun. 2014 08:53 <-- editieren / zitieren --> Unities abgeben:
Code: (defun getblockselection ( blk ) (if (= LayerVar "ANDRITZ-SUPPLY") (ssget "_X" (list '(0 . "INSERT") '(8 . "ANDRITZ-SUPPLY") (cons 2 (apply 'strcat (cons blk (mapcar '(lambda ( x ) (strcat ",`" x)) (LM:getanonymousreferences blk) ) ) ) ) ) ) ) (if (= LayerVar "CUSTOMER-SUPPLY") (ssget "_X" (list '(0 . "INSERT") '(8 . "CUSTOMER-SUPPLY") (cons 2 (apply 'strcat (cons blk (mapcar '(lambda ( x ) (strcat ",`" x)) (LM:getanonymousreferences blk) ) ) ) ) ) ) ) (if (= LayerVar "RELOCATED") (ssget "_X" (list '(0 . "INSERT") '(8 . "RELOCATED") (cons 2 (apply 'strcat (cons blk (mapcar '(lambda ( x ) (strcat ",`" x)) (LM:getanonymousreferences blk) ) ) ) ) ) ) ) (if (= LayerVar "ALL") (ssget "_X" (list '(0 . "INSERT") (cons 2 (apply 'strcat (cons blk (mapcar '(lambda ( x ) (strcat ",`" x)) (LM:getanonymousreferences blk) ) ) ) ) ) ) ) )
Das ist die ganze Auswahlfunktion. Ich will die Liste aber erst am Ende der Hauptfunktion zurücksetzen. Wenn ich (setq getblockselection nil) versuche läuft er beim ersten mal zwar normal durch. Bei weiteren versuchen meldet er dann aber: ; error: no function definition: GETBLOCKSELECTION Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
cadffm Moderator 良い精神
Beiträge: 22275 Registriert: 03.06.2002 Alles
|
erstellt am: 05. Jun. 2014 09:10 <-- editieren / zitieren --> Unities abgeben: Nur für kurt.trattner
Deine Auswertung läuft immer, egal ob es einen (erneuten) Treffer gab oder nicht, wenn es keinen neuen Auswahlsatz gibt, so ist ja nach wie vor der alte"aktuell" und wird ausgelesen.. Diesen Part mußt du in Abhängigkeit mit der Auswahl bringen (nur Auswerten, wenn aktuell etwas gefunden wurde..)
Code: (setq axss (vla-get-activeselectionset adoc)) (vlax-for a axss (setq tmp_get (get-all-atts a))
Also zB mit der Copy&Paste umgesetzt: Code: (if (tblsearch "block" blk) (if (setq aws (getblockselection blk)) (progn (setq axss ... ) (vlax-for a axss (setq tmp_get (get-all-atts a)) (setq tmp_data (append (list (vla-get-name a)(vla-get-handle a)) tmp_get)) .... ... . ) );_progn (princ (strcat "\nZERO")) ) (princ (strcat "\n" blk " doesn't exist.")) )
------------------ CAD on demand GmbH - Beratung und Programmierung rund um AutoCAD Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
kurt.trattner Mitglied Mechanical Plant Engineer
Beiträge: 46 Registriert: 28.05.2014 AutoCAD Mechanical 2012
|
erstellt am: 05. Jun. 2014 09:25 <-- editieren / zitieren --> Unities abgeben:
Das funktioniert super gut Da wäre ich niemals draufgekommen. Eure Hilfe ist der Wahnsinn. Danke dafür. Kann man vielleicht die Funktion nach diesem princ enden lassen? Weil er gibt mir immer einen VBA Fehler aus, da ich mit einem Wert nil weitergehe. Wenn du Funktion hier einfach enden würde wenn es keine Übereinstimmungen gibt wäre es am besten. Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
kurt.trattner Mitglied Mechanical Plant Engineer
Beiträge: 46 Registriert: 28.05.2014 AutoCAD Mechanical 2012
|
erstellt am: 05. Jun. 2014 09:37 <-- editieren / zitieren --> Unities abgeben:
So wird die Funktion beendet. Aber leider kommt dann das Popup nichtmehr: Code: );;progn ((alert "No matches found! Function cancelled!")(quit)) ) (princ (strcat "\n" blk " doesn't exist.")) ) (princ)
[Diese Nachricht wurde von kurt.trattner am 05. Jun. 2014 editiert.] Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
kurt.trattner Mitglied Mechanical Plant Engineer
Beiträge: 46 Registriert: 28.05.2014 AutoCAD Mechanical 2012
|
erstellt am: 05. Jun. 2014 10:57 <-- editieren / zitieren --> Unities abgeben:
PROBLEM SELBST GELÖST. NUR MEHR DAS PROBLEM MIT DEM BEENDEN IST AKTUELLDie Verschachtelung der If Funktionen war falsch
Code: (initget 1 "ALL ANDRITZ-SUPPLY CUSTOMER-SUPPLY RELOCATED") ;;Gibt die Layernamen vor, die ausgewählt werden können (setq LayerVar (getkword "\Specify Layer: [ALL/ANDRITZ-SUPPLY/CUSTOMER-SUPPLY/RELOCATED]")) (initget 1 "Valve Tank Pump Motor") ;;Gibt die Blocknamen vor, die ausgewählt werden können (setq blk (getkword "\Specify Blockname: [Valve/Tank/Pump/Motor]")) ;;Eingabemaske mit Blocknamen (if (tblsearch "block" blk) (if(setq aws (getblockselection blk)) (progn (setq axss (vla-get-activeselectionset adoc)) (vlax-for a axss (setq tmp_get (get-all-atts a)) (setq tmp_data (append (list (vla-get-name a)(vla-get-handle a)) tmp_get)) (setq com_data (cons tmp_data com_data)) (setq tmp_data nil) ) );;progn (alert "No matches found! Function cancelled!") ) )
OK so ganz funktioniert der Code doch nicht. Wenn ich als Leyer "All" auswähle, er also alle Blöcke mit dem selben Namen auswählt funktioniert alles wie es soll. Wähle ich jedoch einen Anderen Layer aus funktioniert es nicht mehr und er gibt mir die Fehlermeldung aus die er eigentlich ausgeben sollte wenn keine Übereinstimmungen gefunden werden. Seltsam ist dass es funktioniert wenn ich bei der Definition von "All" einen Layer hinzufüge. Hier die Definition: Code: (defun getblockselection ( blk ) (if (= LayerVar "ANDRITZ-SUPPLY") (ssget "_X" (list '(0 . "INSERT") '(8 . "ANDRITZ-SUPPLY") (cons 2 (apply 'strcat (cons blk (mapcar '(lambda ( x ) (strcat ",`" x)) (LM:getanonymousreferences blk) ) ) ) ) ) ) ) (if (= LayerVar "CUSTOMER-SUPPLY") (ssget "_X" (list '(0 . "INSERT") '(8 . "CUSTOMER-SUPPLY") (cons 2 (apply 'strcat (cons blk (mapcar '(lambda ( x ) (strcat ",`" x)) (LM:getanonymousreferences blk) ) ) ) ) ) ) ) (if (= LayerVar "RELOCATED") (ssget "_X" (list '(0 . "INSERT") '(8 . "RELOCATED") (cons 2 (apply 'strcat (cons blk (mapcar '(lambda ( x ) (strcat ",`" x)) (LM:getanonymousreferences blk) ) ) ) ) ) ) ) (if (= LayerVar "ALL") (ssget "_X" (list '(0 . "INSERT") (cons 2 (apply 'strcat (cons blk (mapcar '(lambda ( x ) (strcat ",`" x)) (LM:getanonymousreferences blk) ) ) ) ) ) ) ) )
[Diese Nachricht wurde von kurt.trattner am 05. Jun. 2014 editiert.] [Diese Nachricht wurde von kurt.trattner am 05. Jun. 2014 editiert.] Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
kurt.trattner Mitglied Mechanical Plant Engineer
Beiträge: 46 Registriert: 28.05.2014 AutoCAD Mechanical 2012
|
erstellt am: 04. Sep. 2014 08:52 <-- editieren / zitieren --> Unities abgeben:
Hallo Leute. Es ist erforderlich, dass ich eine zusätzliche Funktion ins Lisp einbaue. Es soll möglich sein eine Liste der Attribute von allen definierten Blöcken gleichzeitig ins Excel zu exportieren. Zur Erklärung. Jeder Block hat als erste 5 Attribute die selben. Also wird es kein Problem diese in die selbe Liste zu schreiben. Auch das Importieren sollte kein Problem sein. Nun mein Problem: Mein ganzes Programm ist abhängig von der Variable "blk". Ich gebe nun dem Programm den Wert "WORK" als "blk". Jedoch ist meine Auswahl in einige Unterfunktionen unterteilt und mir fällt leider überhaupt nicht ein wie ich das bewerkstelligen soll. Zuerst geht die Variable hier rein.
Code: (if (tblsearch "block" blk) (if(setq aws (getblockselection blk)) (progn (setq axss (vla-get-activeselectionset adoc)) (vlax-for a axss (setq tmp_get (get-all-atts a)) (setq tmp_data (append (list (vla-get-name a)(vla-get-handle a)) tmp_get)) (setq com_data (cons tmp_data com_data)) (setq tmp_data nil) ) );;progn (progn (alert "No matches found! Function cancelled!") (exit)) ))
Dann geht das ganze weiter in folgenden Code. Hier habe ich schon an einer Lösung gebastelt:
Code: (defun getblockselection ( blk ) (if (= blk "WORK") (ssget "_X" (list '(0 . "INSERT") (cons 2 (apply 'strcat (cons blk (mapcar '(lambda ( x ) (strcat ",`" x)) (LM:getanonymousreferences blk) ) ) ) ) ) ) ) (progn (if (= LayerVar "ANDRITZ-SUPPLY") (ssget "_X" (list '(0 . "INSERT") '(8 . "ANDRITZ-SUPPLY") (cons 2 (apply 'strcat (cons blk (mapcar '(lambda ( x ) (strcat ",`" x)) (LM:getanonymousreferences blk) ) ) ) ) ) ) (if (= LayerVar "CUSTOMER-SUPPLY") (ssget "_X" (list '(0 . "INSERT") '(8 . "CUSTOMER-SUPPLY") (cons 2 (apply 'strcat (cons blk (mapcar '(lambda ( x ) (strcat ",`" x)) (LM:getanonymousreferences blk) ) ) ) ) ) ) (if (= LayerVar "RELOCATED") (ssget "_X" (list '(0 . "INSERT") '(8 . "RELOCATED") (cons 2 (apply 'strcat (cons blk (mapcar '(lambda ( x ) (strcat ",`" x)) (LM:getanonymousreferences blk) ) ) ) ) ) ) (if (= LayerVar "ALL") (ssget "_X" (list '(0 . "INSERT") (cons 2 (apply 'strcat (cons blk (mapcar '(lambda ( x ) (strcat ",`" x)) (LM:getanonymousreferences blk) ) ) ) ) ) ) (if (= LayerVar "EXISTING") (ssget "_X" (list '(0 . "INSERT") '(8 . "EXISTING") (cons 2 (apply 'strcat (cons blk (mapcar '(lambda ( x ) (strcat ",`" x)) (LM:getanonymousreferences blk) ) ) ) ) ) ) ) ))))) )
Die obere Funktion verweist wiederum auf diese Funktion:
Code: (defun LM:getanonymousreferences ( blk / ano def lst rec ref ) (setq blk (strcase blk)) (while (setq def (tblnext "block" (null def))) (if (and (= 1 (logand 1 (cdr (assoc 70 def)))) (setq rec (entget (cdr (assoc 330 (entget (tblobjname "block" (setq ano (cdr (assoc 2 def))) ) ) ) ) ) ) ) (while (and (not (member ano lst)) (setq ref (assoc 331 rec)) ) (if (and (entget (cdr ref)) (= blk (strcase (LM:al-effectivename (cdr ref)))) ) (setq lst (cons ano lst)) ) (setq rec (cdr (member (assoc 331 rec) rec))) ) ) ) (reverse lst) )
Welche wiederum auf diese Funktion verweist:
Code: (defun LM:al-effectivename ( ent / blk rep ) (if (wcmatch (setq blk (cdr (assoc 2 (entget ent)))) "`**") (if (and (setq rep (cdadr (assoc -3 (entget (cdr (assoc 330 (entget (tblobjname "block" blk) ) ) ) '("AcDbBlockRepBTag") ) ) ) ) (setq rep (handent (cdr (assoc 1005 rep)))) ) (setq blk (cdr (assoc 2 (entget rep)))) ) ) blk )
Das Problem ist nun, dass ich für jede Funktion irgendwie eine if Funktion einbauen müsste für den Fall das die WORKliste ausgefahren werden soll. Jedoch weiß ich nicht wirklich wie ich das bei allen Funktionen machen soll. In der zweiten Funktion würde es ja gehen wenn darin nicht weiter auf anderen verwiesen werden würde. Ich hoffe ihr könnt mir wieder helfen. Ich habe gerade total ein Brett vor dem Kopf Lg. Kurt [Diese Nachricht wurde von kurt.trattner am 04. Sep. 2014 editiert.] 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: 04. Sep. 2014 09:18 <-- editieren / zitieren --> Unities abgeben: Nur für kurt.trattner
Hallo Kurt, du scheinst wirklich total auf dem Schlauch zu stehen. Wozu du die If's eingebaut hast, zumal sich doch nur immer der Layername ändert ist mir nicht klar. Ich vermute, dass dir das Erzeugen der Assoc-Listen und/oder Filterlisten für Auswahlsätze und/oder das Quoten nicht geläufig ist. So könnte es aussehen .. ob ich deine Logik jetzt wirklich abgebildet habe, bin ich mir aber nicht ganz sicher.
Code:
(defun getblockselection ( blk Layervar) (if (wcmatch (strcase Layervar) "WORK,ALL") (setq Layervar "*") ) (ssget "_X" (list '(0 . "INSERT") (cons 8 Layervar) (cons 2 (apply 'strcat (cons blk (mapcar '(lambda ( x )(strcat ",`" x))(LM:getanonymousreferences blk))))) ) ) )
Grüße! Holger ------------------ Holger Brischke CAD on demand GmbH Individuelle Lösungen von Heute auf Morgen.
defun-tools Das Download-Portal für AutoCAD-Zusatzprogramme!
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |