| |
| Gut zu wissen: Hilfreiche Tipps und Tricks aus der Praxis prägnant, und auf den Punkt gebracht für Autodesk Produkte |
Autor
|
Thema: Attribute ändern (3963 mal gelesen)
|
wasc Mitglied Bautechniker
Beiträge: 52 Registriert: 15.04.2005 Windows 2000, ACAD2005, P4 2,8
|
erstellt am: 11. Okt. 2005 10:48 <-- editieren / zitieren --> Unities abgeben:
hallo leute ! habe diesen lispteil in diesem forum gefunden. besten dank an fuchsi !! (defun GetAllAttributes (ename / i atts daten) (setq i (vlax-ename->vla-object ename)) (if (and (= (vla-get-hasattributes i) :vlax-true) (safearray-value (setq atts (vlax-variant-value (vla-getattributes i) ) ) ) ) (foreach tag (vlax-safearray->list atts) (setq daten (cons (cons (vla-get-tagstring tag) (vla-get-TextString tag) ) daten)) ) ) daten ) jetzt aber meine frage dazu: ich weiss zwar wie ich mit diesem lisp einzelene attributwerte eines blocks herausholen kann, aber wie kann ich dann die veränderten attributwerte wieder in die geomtriedatenbank zurückschreiben ? das ergebnis dieser funktion ist eine assoc liste mit den zugehöhrigen attributwerten. besten dank walter Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
CADmium Moderator Maschinenbaukonstrukteur
Beiträge: 13527 Registriert: 30.11.2003 .
|
erstellt am: 11. Okt. 2005 10:58 <-- editieren / zitieren --> Unities abgeben: Nur für wasc
für das setzen kannst du folgenden Konstrukt nehmen: (vla-put-TextString tag "NEUERINHALT") ------------------ - Thomas - "Bei 99% aller Probleme ist die umfassende Beschreibung des Problems bereits mehr als die Hälfte der Lösung desselben." Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
wasc Mitglied Bautechniker
Beiträge: 52 Registriert: 15.04.2005 Windows 2000, ACAD2005, P4 2,8
|
erstellt am: 11. Okt. 2005 13:26 <-- editieren / zitieren --> Unities abgeben:
hallo ! danke für die schnelle antwort !! da ich zur zeit mit lisp ein wenig herumexperimentiere und anfänger bin , habe ich das lisp soweit erweitert, dass ich ein attribut ändern kann ! aber mit meinen kenntnissen steige ich beim befehl (vla-put-TextString tag "neuer Eintrag") aus. ich wäre sehr dankbar wenn man mir zeigen könnte wie sich das in meinem fall verhält, sprich wie es nach dem befehl (vla-put-TextString tag "neuer Eintrag") weitergeht und wie man den geänderten eintrag in der geometriedatenbank aktuallisiert. Ich hoffe dies ist nicht all zu aufwendig. besten dank im voraus walter (defun c:ge ( /a b c txt f) (setq a (ssget)) (defun GetAllAttributes (ename / i atts daten) (setq i (vlax-ename->vla-object ename)) (if (and (= (vla-get-hasattributes i) :vlax-true) (safearray-value (setq atts (vlax-variant-value (vla-getattributes i) ) ) ) ) (foreach tag (vlax-safearray->list atts) (setq daten (cons (cons (vla-get-tagstring tag) (vla-get-TextString tag) ) daten)) ) ) daten ) (setq b (ssname a 0) c (GetAllAttributes b) txt (cons "MATERIAL" "GGGzzm") ; z.B. f (subst txt (assoc '"MATERIAL" (GetAllAttributes b))c)) ; z.B. (vla-put-TextString tag ????????) ) Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
benwisch Mitglied Bautechniker, CAD-Konstrukteur
Beiträge: 375 Registriert: 01.02.2001
|
erstellt am: 11. Okt. 2005 13:46 <-- editieren / zitieren --> Unities abgeben: Nur für wasc
na okay... hier wie man es mit AchtiveX lösen kann :) Hauptfunktion: :block:writetags2attrib Sie benötigt als Argumente ein a) Blockreferenz-Objekt als VLA-OBJEKT (!!) und b) eine Assoziationsliste wie die Rückgabe von Fuchsis Code oben.
Code:
(defun :block:writetags2attrib (#vla-obj #alst / tag) (foreach otag (:block:getattribute #vla-obj) (if (setq tag (:lst:grc (vla-get-tagstring otag) #alst)) (vla-put-textstring otag tag) ) ) )
Die Funktion iteriert durch eine Liste mit den Attributsreferenzen die als Vla-Objekte vorliegen sollten und ändert dabei alle gefundene Tags die mit der Assoziationsliste (#alst) übereinstimmen. Sie benötigt aber zus. noch 3 weitere Funktionen, die ich unten anhänge und kurz erkläre...
Code:
; Rückgabe einer Liste mit den Attributsreferenzen als Vla-Objekte ; sonst NIL (defun :block:getattribute (#vla-insert /) (if (vlax-property-available-p #vla-insert (quote hasattributes) ) (:lst:safearray->list (vlax-invoke-method #vla-insert (quote getattributes)) ) ) ) ;;;××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××× ; Rückgabe des cdr-Wertes einer Assoc-Liste (defun :lst:grc (#key #alst) (if ( :obj:ename? #alst) (cdr (assoc #key (entget #alst))) (cdr (assoc #key #alst)) ) ) ;;;××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××× ; wandelt ein Safearray in eine Liste um (defun :lst:safearray->list (#sarray /) (vlax-safearray->list (vlax-variant-value #sarray)) ) ;;;××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××× ; prüft ob das übergebene Argument ein Ename oder ; eine Liste mit Ename-Daten ist ; Rückgabe => 'T oder Nil (defun :obj:ename? (#ent) (vl-every (function (lambda (each) (= (type each) (quote ename)))) (if (and #ent (listp #ent)) #ent (list #ent) ) ) )
Beispiel Funktionsaufruf:
Code: (:block:writetags2attrib (vlax-ename->vla-object (car (entsel))) '(("FAKTOR" . "2") ("LÄNGE" . "1.20") ("DS" . "") ("HS" . "") ("Z" . "") ("E" . "0.000") ("D" . "0.000") ("C" . "0.520") ("B" . "0.170") ("A" . "0.510") ("DINTYP" . "A3") ("DU" . "8") ("ANZA" . "128") ("POS" . "6") ) )
...viel Spaß beim lernen greets Rolf[Diese Nachricht wurde von benwisch am 11. Okt. 2005 editiert.] Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
wasc Mitglied Bautechniker
Beiträge: 52 Registriert: 15.04.2005 Windows 2000, ACAD2005, P4 2,8
|
erstellt am: 11. Okt. 2005 14:07 <-- editieren / zitieren --> Unities abgeben:
|
joern bosse Ehrenmitglied Dipl.-Ing. Vermessung
Beiträge: 1760 Registriert: 11.10.2004 Window 11 ACAD 2021 CIVIL 2021 BricsCAD ab V14 11th Gen Intel(R) Core(TM) i7-1165G7 @ 2.80GHz 2.80 GHz 32.0GB RAM NVIDIA GeForce MX450<P>
|
erstellt am: 11. Okt. 2005 14:48 <-- editieren / zitieren --> Unities abgeben: Nur für wasc
Hallo Walter, hier nochmal der Versuch, es anhand Deines Beispielcodes zu zeigen. Wenn Du einen Block hast, der die Attributsbezeichnungen "PNR" und "BEM" enthält, dann werden deren Attributswerte mit vla-put-TextString geändert.
Code:
(defun GetAllAttributes (ename / i atts daten) (setq i (vlax-ename->vla-object ename)) (if (and (= (vla-get-hasattributes i) :vlax-true) (safearray-value (setq atts (vlax-variant-value (vla-getattributes i) ) ) ) ) (foreach tag (vlax-safearray->list atts);;;Attributswerte ändern (cond ((=(vla-get-tagstring tag) "PNR") ;;;wenn Attributsbezeichnung = PNR (vla-put-TextString tag "99999")) ;;;dann ersetze den Attributswert mit "99999" ((=(vla-get-tagstring tag) "BEM") ;;;wenn Attributsbezeichnung = BEM (vla-put-TextString tag "Bemerkung1")) ;;;dann ersetze den Attributswert mit "Bemerkung1" ) ;;;Ende Attributswerte ändern (setq daten (cons (cons (vla-get-tagstring tag) (vla-get-TextString tag) ) daten)) ) ) daten )
------------------ viele Grüße Jörn [Diese Nachricht wurde von joern bosse am 11. Okt. 2005 editiert.] Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
wasc Mitglied Bautechniker
Beiträge: 52 Registriert: 15.04.2005 Windows 2000, ACAD2005, P4 2,8
|
erstellt am: 12. Okt. 2005 05:16 <-- editieren / zitieren --> Unities abgeben:
|
stesofeu Mitglied Dipl.-Ing. Maschinenbau
Beiträge: 38 Registriert: 10.09.2004
|
erstellt am: 19. Jul. 2009 13:25 <-- editieren / zitieren --> Unities abgeben: Nur für wasc
Zitat: Original erstellt von joern bosse: Hallo Walter, hier nochmal der Versuch, es anhand Deines Beispielcodes zu zeigen. Wenn Du einen Block hast, der die Attributsbezeichnungen "PNR" und "BEM" enthält, dann werden deren Attributswerte mit vla-put-TextString geändert.
Code:
(defun GetAllAttributes (ename / i atts daten) (setq i (vlax-ename->vla-object ename)) (if (and (= (vla-get-hasattributes i) :vlax-true) (safearray-value (setq atts (vlax-variant-value (vla-getattributes i) ) ) ) ) (foreach tag (vlax-safearray->list atts);;;Attributswerte ändern (cond ((=(vla-get-tagstring tag) "PNR") ;;;wenn Attributsbezeichnung = PNR (vla-put-TextString tag "99999")) ;;;dann ersetze den Attributswert mit "99999" ((=(vla-get-tagstring tag) "BEM") ;;;wenn Attributsbezeichnung = BEM (vla-put-TextString tag "Bemerkung1")) ;;;dann ersetze den Attributswert mit "Bemerkung1" ) ;;;Ende Attributswerte ändern (setq daten (cons (cons (vla-get-tagstring tag) (vla-get-TextString tag) ) daten)) ) ) daten )
Hallo Jörn, wenn ich z.B. eine 0815-Zeichnung mit dem Standardkopf ISO_TITLEA erstelle und die Funktion (GETALLATTRIBUTES "ISO_TITLEA") aufrufe, kommt die Fehlermeldung ; Fehler: Fehlerhafter Argumenttyp: lentityp "ISO_TITLEA" Was muss ich denn der Funktion übergeben, wenn nicht den Blocknamen?
------------------ Viele Grüße aus Siegen-Wittgenstein Stephan Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied
|
erstellt am: 19. Jul. 2009 13:49 <-- editieren / zitieren -->
Hi Stephan, aus der Zeile: (setq i (vlax-ename->vla-object ename)) schliesse ich, dass Du den ObjectName (internes ID-Objekt) übergeben wirst müssen. Also selektiere Deinen Schriftkopf mit folgender Funktion:
(setq ename (car (entsel))) ...und ename übergibst Du dann an die Funktion. Der Blockname ist ja schon deshalb nicht ausreichend, denn Du könntest ja viele BlockReferenzen mit diesem Blocknamen in der Zeichnung haben. - alfred - PS: (vl-load-com) nicht vergessen ------------------ www.hollaus.at |
Dorfy Mitglied Double-Dipl.-Ing. Bleistiftanspitzer
Beiträge: 900 Registriert: 21.07.2006 AutoCad2007, ProE, HiCad
|
erstellt am: 19. Jul. 2009 13:52 <-- editieren / zitieren --> Unities abgeben: Nur für wasc
Hallo Stephan, "(defun GetAllAttributes (ename /..." ename --> entity name (Objektname) zBsp mit (car(entsel)) versuch mal: (GetAllAttributes (car(entsel))) ... Objekt wählen (dein Block) Edit: da war der Alfred schnell ------------------ Mfg Heiko
Elefantenjagd in Afrika "... LISP-Programmierer bauen einen Irrgarten aus Klammern und hoffen, dass sich der Elefant darin verirrt..." (www.uni-leipzig.de/~rotheh/elefant.htm) [Diese Nachricht wurde von Dorfy am 19. Jul. 2009 editiert.] Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Geos Mitglied Vermessungstechniker i.R.
Beiträge: 1017 Registriert: 21.09.2001 ACAD Map 2010, Win 7 Pro eigene Lisp's<P>HW: Core i7 860, 2.8 GHz 3.3 GB, NVIDIA GeForce GTS 250
|
erstellt am: 19. Jul. 2009 13:58 <-- editieren / zitieren --> Unities abgeben: Nur für wasc
|
stesofeu Mitglied Dipl.-Ing. Maschinenbau
Beiträge: 38 Registriert: 10.09.2004
|
erstellt am: 19. Jul. 2009 17:22 <-- editieren / zitieren --> Unities abgeben: Nur für wasc
Hallo Alfred, Dorfy und Ernst, vielen Dank für Eure Hilfe! Jetzt bin einen Schritt weiter gekommen: Mit (CAR (ENTSEL)) erhalte ich den Objektnamen des Schriftfeldblocks. Damit kann ich dann auch über (GetAllAttributes ...) die Attribute auslesen. So weit, so gut. Aber ich muss immer noch selektieren... Wenn ich den Blocknamen direkt mit (CDR (ASSOC -2(TBLSEARCH "BLOCK" "ISO_TITLEA"))) suche, erhalte ich eine andere Objektnummer. Wie kommt das? ------------------ Viele Grüße aus Siegen-Wittgenstein Stephan Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied
|
erstellt am: 19. Jul. 2009 17:27 <-- editieren / zitieren -->
Hi Stephan, Du mußt unterscheiden, was eine Blockdefinition und was eine Blockreferenz ist. Die Blockdefinition (nach der Du mit TBLSEARCH sucht) ist die Bestimmung, wie das Symbol aussieht, also die Linien, Polylinien, ... und Attributsdefinitionen. Wenn Du im AutoCAD den Befehl '_block' verwendest, dann wird eine Blockdefinition erzeugt. Die Blockreferenz ist dann das im Modellbereich oder im Layout plazierte Element. Darin können dann auch die Werte für die Attribute ausgefüllt werden. Wenn Du mit AutoCAD den Befehl '_insert'/'einfüge' verwendest, dann wird eben eine Blockreferenz erzeugt. D.h. wenn Du die Werte Deines Schriftkopfs auslesen willst, dann kannst Du nur auf eine Blockreferenz hingehen. Sei es durch Anklicken (manuelles Selektieren) oder durch Bilden eines SelectionSets, mit dem Du Dir die BlockReferenzen suchen läßt. - alfred - ------------------ www.hollaus.at [Diese Nachricht wurde von a.n. am 19. Jul. 2009 editiert.] |
stesofeu Mitglied Dipl.-Ing. Maschinenbau
Beiträge: 38 Registriert: 10.09.2004
|
erstellt am: 19. Jul. 2009 20:22 <-- editieren / zitieren --> Unities abgeben: Nur für wasc
Hallo Alfred, ich habe noch ein bißchen im Forum gesucht und hab jetzt fogenden Code zusammen:
Code: (VL-LOAD-COM)(DEFUN GetAllAttributes (EntityName / i Attribute Daten) (SETQ i (VLAX-ENAME->VLA-OBJECT EntityName)) (IF (AND (= (VLA-GET-HASATTRIBUTES i) :VLAX-TRUE) (SAFEARRAY-VALUE (SETQ Attribute (VLAX-VARIANT-VALUE (VLA-GETATTRIBUTES i))) ) ) (FOREACH Tag (VLAX-SAFEARRAY->LIST Attribute) (COND ((=(VLA-GET-TAGSTRING Tag) "PNR") (VLA-PUT-TEXTSTRING Tag "99999")) ((=(VLA-GET-TAGSTRING Tag) "BEM") (VLA-PUT-TEXTSTRING Tag "Bemerkung 1")) ) (SETQ Daten (CONS (CONS (VLA-GET-TAGSTRING Tag) (VLA-GET-TEXTSTRING Tag)) Daten)) ) ) Daten ) (DEFUN SS->LIST (Auswahlsatz / i Liste) (SETQ i 0) (REPEAT (SSLENGTH Auswahlsatz) (SETQ Liste (CONS (SSNAME Auswahlsatz i) Liste)) (SETQ i (1+ i)) ) Liste ) ;Diese Lösung geht nicht, obwohl der gleiche Inhalt in der Variablen Block steht: (<Objektname: 7ef07f90>) (SETQ Block (SS->LIST (SSGET "_X" '((0 . "INSERT") (2 . "ISO_TITLEA"))))) (PRINC Block) (GetAllAttributes Block) ;Diese Lösung geht: ;(SETQ BLOCK (CAR (ENTSEL))) ;(PRINC Block) ;(GetAllAttributes Block)
Was mich wundert: in beiden Fällen steht in Block die gleiche Liste, aber nur die mit (ENTSEL) erstellte Liste funktioniert. ------------------ Viele Grüße aus Siegen-Wittgenstein Stephan Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Dorfy Mitglied Double-Dipl.-Ing. Bleistiftanspitzer
Beiträge: 900 Registriert: 21.07.2006 AutoCad2007, ProE, HiCad
|
erstellt am: 19. Jul. 2009 20:44 <-- editieren / zitieren --> Unities abgeben: Nur für wasc
Hi Stephan, also ssget... liefert dir ein selction set SS->LIST packt alle Objekte des Auswahlsatzn in eine liste und gibt diese zurück IMHO übergibst du eine Liste (mit Glück enthält diese nur ein Objekt bei dir --> deshalb ist dieses fast gleich aber () "zuviel") In der Hilfe (vlide) findest du Methoden um Listen zu verarbeiten. car <Liste> --> (GetAllAttributes (car Block)) das erste Element der Liste wird übergeben oder besser eine Schleife (foreach...) um alle Listenelement zu bearbeiten... ------------------ Mfg Heiko Elefantenjagd in Afrika "... LISP-Programmierer bauen einen Irrgarten aus Klammern und hoffen, dass sich der Elefant darin verirrt..." (www.uni-leipzig.de/~rotheh/elefant.htm) Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
stesofeu Mitglied Dipl.-Ing. Maschinenbau
Beiträge: 38 Registriert: 10.09.2004
|
erstellt am: 21. Jul. 2009 15:48 <-- editieren / zitieren --> Unities abgeben: Nur für wasc
|