Hot News:

Mit Unterstützung durch:

  Foren auf CAD.de (alle Foren)
  Lisp
  Werte von Attributen in Blöcken ändern

Antwort erstellen  Neues Thema erstellen
CAD.de Login | Logout | Profil | Profil bearbeiten | Registrieren | Voreinstellungen | Hilfe | Suchen

Anzeige:

Darstellung des Themas zum Ausdrucken. Bitte dann die Druckfunktion des Browsers verwenden. | Suche nach Beiträgen nächster neuer Beitrag | nächster älterer Beitrag
Autor Thema:   Werte von Attributen in Blöcken ändern (358 mal gelesen)
Maier2018
Mitglied


Sehen Sie sich das Profil von Maier2018 an!   Senden Sie eine Private Message an Maier2018  Schreiben Sie einen Gästebucheintrag für Maier2018

Beiträge: 8
Registriert: 15.01.2018

Autocad 2019

erstellt am: 18. Jan. 2021 13:53    Editieren oder löschen Sie diesen Beitrag!  <-- editieren / zitieren -->   Antwort mit Zitat in Fett Antwort mit kursivem Zitat    Unities abgeben: 1 Unity (wenig hilfreich, aber dennoch)2 Unities3 Unities4 Unities5 Unities6 Unities7 Unities8 Unities9 Unities10 Unities

Hallo Zusammen,

ich möchte nach dem Einfügen von einem Block, Attributen einen bestimmten Wert zuweisen. Das wäre mit setpropertyvalue recht einfach gelöst. Nur sind manche Attribute mehrfach im Block vorhanden - also Duplikate.
D.h. ich habe einen Block in dem "Attribut1" drei mal vorhanden ist und ich möchte allen drei den selben Wert zuweisen.

Momentan habe ich nur eine nicht so elegante Lösung herausgefunden:

Code:

(setpropertyvalue blockname "ATT1" WERT)
(setpropertyvalue blockname "ATT11" WERT)
(setpropertyvalue blockname "ATT12" WERT)

Es scheint, dass Autocad die Attributnamen einfach nur durchnummeriert.
Ich schätze, dies wäre durch eine Schleife einfach zu lösen, nur habe ich wenig Erfahrung mit Schleifen.

Hoffe jemand kann mir da helfen...

Vielen Dank vorab!

Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP

Andreas Kraus
Mitglied
Elektrotechniker


Sehen Sie sich das Profil von Andreas Kraus an!   Senden Sie eine Private Message an Andreas Kraus  Schreiben Sie einen Gästebucheintrag für Andreas Kraus

Beiträge: 1220
Registriert: 11.01.2006

WIN 10
ACAD 2017

erstellt am: 18. Jan. 2021 19:01    Editieren oder löschen Sie diesen Beitrag!  <-- editieren / zitieren -->   Antwort mit Zitat in Fett Antwort mit kursivem Zitat    Unities abgeben: 1 Unity (wenig hilfreich, aber dennoch)2 Unities3 Unities4 Unities5 Unities6 Unities7 Unities8 Unities9 Unities10 Unities Nur für Maier2018 10 Unities + Antwort hilfreich

Hallo Maier 2018,
ich hoffe Axels Seiten sind dir bekannt.
http://www.autolisp.info/index.html

Da ist sehr viel sehr gut erklärt.

Schleifen:
Es gibt Foreach, While und Repeat als Schleifen.
Außerdem noch Vlax-For für Collections und natürlich Mapcar für die Anwendung von Funktionen auf Listen.

Hier sind Repeat und While erklärt: http://www.autolisp.info/schleifen1.html
Foreach ist hier: http://www.autolisp.info/listen6.html
Und Vlax-For hier: http://activex.autolisp.info/collections.html

Mapcar würde ich mal ganz separat behandeln, ist aber hier meine Lieblinsfunktion weil sie auch eine Rückgabe liefert.

Bei deinem Problem dass du vielleicht nicht weist wieviele Attribute mit welchem Namen an einem BlocK hängen würde ich einfach mal alle auslesen und dann die bearbeiten die ich brauche.
(vlax-invoke obj_name 'GetAttributes) liefert die eine Liste der Attribute am Block. Bitte beachte dass hier nicht der Elementname sondern der Objektname gebraucht wird.
Diese Liste mit einer Schleife abarbeiten und in der Schleife nur was arbeiten wenn der Attributname passt.

Code:
(foreach att (vlax-invoke obj_name 'GetAttributes)
  (if (= (vla-get-tagstring att) "ATT1")
    (vla-put-textstring att "neuer Wert")
  )
)

Ist jetzt einfach mal "dreckig runtergetippt" also ohne jegliche Fehlerüberwachung usw. (ist z.B. der Layer entsperrt) und natürlich kannst/musst du "ATT1" und "neuer Wert" deinen Bedürfnissen anpassen.
Wie du an den Objektnamen vom Block kommst ist auch deine Sache 

Viel Spass damit 

------------------
Geht nicht, gibts nicht

Gruß
Andreas

http://kraus-cad.de

Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP

Maier2018
Mitglied


Sehen Sie sich das Profil von Maier2018 an!   Senden Sie eine Private Message an Maier2018  Schreiben Sie einen Gästebucheintrag für Maier2018

Beiträge: 8
Registriert: 15.01.2018

Autocad 2019

erstellt am: 19. Jan. 2021 14:37    Editieren oder löschen Sie diesen Beitrag!  <-- editieren / zitieren -->   Antwort mit Zitat in Fett Antwort mit kursivem Zitat    Unities abgeben: 1 Unity (wenig hilfreich, aber dennoch)2 Unities3 Unities4 Unities5 Unities6 Unities7 Unities8 Unities9 Unities10 Unities

Hallo Andreas,

danke für die Antwort.

Tatsächlich habe ich gestern schon die while und repeat Schleifen auf Axels Seite studiert.

Ich habe aber wohl eine wichtige Kleinigkeit bei meinem Problem verschwiegen: da wir eine OEM Version von Autocad erworben haben, sind bei uns alle ActiveX Befehle "gesperrt"... Die können wir also leider nicht ausführen.
Autocad stellt sich einfach dumm und sagt es kennt den Befehl nicht. 

Wenn du mir nun einen Tipp geben könntest, mit welchen Befehlen ich die Schleife aufbauen könnte, ohne ActiveX...

Meine Überlegung war, dass ich eine Schleife bastel die einen Block nach einem Attributnamen durchsucht mit einem Platzhalter am Ende - Also Suche nach "ATT1*Platzhalter*" und überschreibe den Wert mit "Wert1".

>>>> Nach dem ich den Text oben getippert habe, fällt mir auf, dass die Schleife von dir genau das macht, oder? 

Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP

CADwiesel
Moderator
CAD4FM UG




Sehen Sie sich das Profil von CADwiesel an!   Senden Sie eine Private Message an CADwiesel  Schreiben Sie einen Gästebucheintrag für CADwiesel

Beiträge: 1937
Registriert: 05.09.2000

AutoCAD, Bricscad
Wir machen das Mögliche unmöglich

erstellt am: 19. Jan. 2021 14:53    Editieren oder löschen Sie diesen Beitrag!  <-- editieren / zitieren -->   Antwort mit Zitat in Fett Antwort mit kursivem Zitat    Unities abgeben: 1 Unity (wenig hilfreich, aber dennoch)2 Unities3 Unities4 Unities5 Unities6 Unities7 Unities8 Unities9 Unities10 Unities Nur für Maier2018 10 Unities + Antwort hilfreich

Im Kern brauchst du ENTNEXT. Damit hangelst du dich durch die Attribute, wenn deine Blockref welche hat.
Hier mal ein Lisp codeschnipsel mit dem du was machen könntest...
Code:
(defun attchange (elem attname gcwert wert / aslst)
  (setq aslst (entget elem))
  (if (= (cdr (assoc 0 aslst)) "INSERT")
    (progn
      (if
        (= (cdr (assoc 66 aslst)) 1)
        (progn
          (setq aslst (entget (entnext (cdr (assoc -1 aslst)))))
          (while
            (/= (cdr (assoc 0 aslst)) "SEQEND")
              (if
                (= (cdr (assoc 2 aslst)) attname)
                (progn
                  (if (= (cdr (assoc gcwert aslst)) "")
                    (entmod
                      (subst (cons gcwert wert)
                              (assoc gcwert aslst)
                              aslst
                              ) ;_ end of subst
                      ) ;_ end of entmod
                    (entmod
                      (subst
                        (cons gcwert
                              (strcat (cdr (assoc gcwert aslst)) ";" wert)
                              ) ;_ end of cons
                        (assoc gcwert aslst)
                        aslst
                        ) ;_ end of subst
                      ) ;_ end of entmod
                    ) ;_ end of if
                  (entupd (cdr (assoc 330 aslst)))
                  ) ;_ end of progn
                ) ;_ end of if
              (setq aslst
                    (entget (entnext (cdr (assoc -1 aslst))))
                    ) ;_ end of setq
              ) ;_ end of while
          ) ;_ end of progn
        ) ;_ end of if
      ) ;_ end of progn
    ) ;_ end of if
  )

Programmaufruf könnte so aussehen:

Code:
(attchange
      elem ;insert Ename (car(entsel))
      "RNR" ;Attributname
      1
      "neuerWert" ; der zu setzende Wert
  )

------------------
Gruß
CADwiesel
Besucht uns im CHAT

Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP

Maier2018
Mitglied


Sehen Sie sich das Profil von Maier2018 an!   Senden Sie eine Private Message an Maier2018  Schreiben Sie einen Gästebucheintrag für Maier2018

Beiträge: 8
Registriert: 15.01.2018

Autocad 2019

erstellt am: 19. Jan. 2021 15:23    Editieren oder löschen Sie diesen Beitrag!  <-- editieren / zitieren -->   Antwort mit Zitat in Fett Antwort mit kursivem Zitat    Unities abgeben: 1 Unity (wenig hilfreich, aber dennoch)2 Unities3 Unities4 Unities5 Unities6 Unities7 Unities8 Unities9 Unities10 Unities

Hallo CADWiesel,

ich verstehe nicht, was "gcwert" beim Aufruf sein soll?   

Muss es immer 1 sein?

Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP

cadffm
Moderator
良い精神




Sehen Sie sich das Profil von cadffm an!   Senden Sie eine Private Message an cadffm  Schreiben Sie einen Gästebucheintrag für cadffm

Beiträge: 20266
Registriert: 03.06.2002

System: F1
und Google

erstellt am: 19. Jan. 2021 15:39    Editieren oder löschen Sie diesen Beitrag!  <-- editieren / zitieren -->   Antwort mit Zitat in Fett Antwort mit kursivem Zitat    Unities abgeben: 1 Unity (wenig hilfreich, aber dennoch)2 Unities3 Unities4 Unities5 Unities6 Unities7 Unities8 Unities9 Unities10 Unities Nur für Maier2018 10 Unities + Antwort hilfreich

Wenn du den DXF GruppenCode 1 geändert haben möchtest, dann ja.

Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP

Maier2018
Mitglied


Sehen Sie sich das Profil von Maier2018 an!   Senden Sie eine Private Message an Maier2018  Schreiben Sie einen Gästebucheintrag für Maier2018

Beiträge: 8
Registriert: 15.01.2018

Autocad 2019

erstellt am: 20. Jan. 2021 08:15    Editieren oder löschen Sie diesen Beitrag!  <-- editieren / zitieren -->   Antwort mit Zitat in Fett Antwort mit kursivem Zitat    Unities abgeben: 1 Unity (wenig hilfreich, aber dennoch)2 Unities3 Unities4 Unities5 Unities6 Unities7 Unities8 Unities9 Unities10 Unities


TEST.lsp


TESTBLOCK.dwg

 
Der Codeschnipsel von CADWiesel funktioniert wunderbar für mich!
Musste nur etwas abgeändert werden, damit der Attributwert ersetzt und nicht mittels strcat an den ursprünglichen Wert angehängt wird.

DANKE! 

Code:

(defun attchange (elem attname gcwert wert / aslst)
  (setq aslst (entget elem))
  (if (= (cdr (assoc 0 aslst)) "INSERT")
    (progn
      (if
        (= (cdr (assoc 66 aslst)) 1)
        (progn
          (setq aslst (entget (entnext (cdr (assoc -1 aslst)))))
          (while
            (/= (cdr (assoc 0 aslst)) "SEQEND")
              (if
                (= (cdr (assoc 2 aslst)) attname)
                (progn
                  (if (= (cdr (assoc gcwert aslst)) "")
                    (entmod
                      (subst (cons gcwert wert)
                              (assoc gcwert aslst)
                              aslst
                              ) ;_ end of subst
                      ) ;_ end of entmod
                    (entmod
                      (subst
                        (cons gcwert
                              wert
                              ) ;_ end of cons
                        (assoc gcwert aslst)
                        aslst
                        ) ;_ end of subst
                      ) ;_ end of entmod
                    ) ;_ end of if
                  (entupd (cdr (assoc 330 aslst)))
                  ) ;_ end of progn
                ) ;_ end of if
              (setq aslst
                    (entget (entnext (cdr (assoc -1 aslst))))
                    ) ;_ end of setq
              ) ;_ end of while
          ) ;_ end of progn
        ) ;_ end of if
      ) ;_ end of progn
    ) ;_ end of if
)

Habe auch den Testblock+Testprogramm angehängt, mit dem ich das Programm getestet habe.

Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP

Bernd P
Ehrenmitglied V.I.P. h.c.
cook-general



Sehen Sie sich das Profil von Bernd P an!   Senden Sie eine Private Message an Bernd P  Schreiben Sie einen Gästebucheintrag für Bernd P

Beiträge: 3223
Registriert: 07.06.2001

AMD A8-3870, W7-64bit, 16GB RAM, HP DJ T2300mfp, HP DJ 500, Maus:G700s, Sub:Infrastructure Design Suite, Excel 2013,

erstellt am: 20. Jan. 2021 11:35    Editieren oder löschen Sie diesen Beitrag!  <-- editieren / zitieren -->   Antwort mit Zitat in Fett Antwort mit kursivem Zitat    Unities abgeben: 1 Unity (wenig hilfreich, aber dennoch)2 Unities3 Unities4 Unities5 Unities6 Unities7 Unities8 Unities9 Unities10 Unities Nur für Maier2018 10 Unities + Antwort hilfreich

Servus,

hab mir das LISP angepasst, es wird kein Block eingefügt sondern es muss einer ausgewählt werden.

Hab 3 Fragen dazu.
1. Die Auswahl von dynamischen Blöcken funktioniert mit "(setq obj_ename (car(entsel "\nBlock wählen: ")))" nicht.
mit "(setq obj_ename (vlax-ename->vla-object (car (entsel))))" bekomme ich "Fehlerhafter Argumenttyp: lentityp #<VLA-OBJECT IAcadBlockReference 00000173bd877d88>"
2. Wenn die Attribute einen Mehrzeiligen Inhalt hatten funktioniert es auch nicht mehr.
3. Kann man den Inhalt aus einem bestimmten Attribut als Vorgabe für WERT1 machen?

------------------
<----- Bitte Systeminfo eintragen, warum siehst du hier. Schöne Grüsse aus der Steiermark  Bernd P.

Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP

cadffm
Moderator
良い精神




Sehen Sie sich das Profil von cadffm an!   Senden Sie eine Private Message an cadffm  Schreiben Sie einen Gästebucheintrag für cadffm

Beiträge: 20266
Registriert: 03.06.2002

System: F1
und Google

erstellt am: 20. Jan. 2021 12:35    Editieren oder löschen Sie diesen Beitrag!  <-- editieren / zitieren -->   Antwort mit Zitat in Fett Antwort mit kursivem Zitat    Unities abgeben: 1 Unity (wenig hilfreich, aber dennoch)2 Unities3 Unities4 Unities5 Unities6 Unities7 Unities8 Unities9 Unities10 Unities Nur für Maier2018 10 Unities + Antwort hilfreich

Ich fange mal an

>>1. Die Auswahl von dynamischen Blöcken funktioniert mit "(setq obj_ename (car(entsel "\nBlock wählen: ")))" nicht
Mit entsel wählt man höchstens Blockreferenzen, nie einen Block.
Dabei sollte dann auch völlig egal sein ob die Blockreferenz  von einem dynamischen Block stammt oder nicht.

>>"mit "(setq obj_ename (vlax-ename->vla-object (car (entsel))))" bekomme ich "Fehlerhafter Argumenttyp: lentityp #<VLA-OBJECT IAcadBlockReference 00000173bd877d88>"
  Daran ist aber nicht die Zeile an sich schuld, aber der restliche code erwartet an obj_ename wohl keine vla-objekt, sondern einen ENAME.
  Die Änderungen der Zeile war also nicht nur falsch, sondern auch noch unnötig.

Deine Zeile von 1.) sollte also die einzige Anpassung sein welche für BlockREFERENZ wählen nötig wird (neben dem entfernen der command-EINFÜGE Zeile natürlich)
(setq obj_ename (car(entsel)))


Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP

Bernd P
Ehrenmitglied V.I.P. h.c.
cook-general



Sehen Sie sich das Profil von Bernd P an!   Senden Sie eine Private Message an Bernd P  Schreiben Sie einen Gästebucheintrag für Bernd P

Beiträge: 3223
Registriert: 07.06.2001

AMD A8-3870, W7-64bit, 16GB RAM, HP DJ T2300mfp, HP DJ 500, Maus:G700s, Sub:Infrastructure Design Suite, Excel 2013,

erstellt am: 20. Jan. 2021 15:51    Editieren oder löschen Sie diesen Beitrag!  <-- editieren / zitieren -->   Antwort mit Zitat in Fett Antwort mit kursivem Zitat    Unities abgeben: 1 Unity (wenig hilfreich, aber dennoch)2 Unities3 Unities4 Unities5 Unities6 Unities7 Unities8 Unities9 Unities10 Unities Nur für Maier2018 10 Unities + Antwort hilfreich

1. *faceplam* hab es am Anfang anscheinend an einem dyn Block mit mehreren Zeilen versucht....

Aus einem anderen meiner Fragen geholt, jetzt klappt es auch mit mehrzeiligen Attribute.
https://ww3.cad.de/foren/ubb/Forum145/HTML/003960.shtml 

Code:
(defun attchange (elem attname gcwert wert / aslst)
  (setq aslst (entget elem))
  (if (= (cdr (assoc 0 aslst)) "INSERT")
    (progn
      (if
        (= (cdr (assoc 66 aslst)) 1)
        (progn
          (setq aslst (entget (entnext (cdr (assoc -1 aslst)))))
          (while
            (/= (cdr (assoc 0 aslst)) "SEQEND")
              (if
                (= (cdr (assoc 2 aslst)) attname)
                (progn
                  (if (= (cdr (assoc gcwert aslst)) "")
                    (entmod
                      (subst (cons gcwert wert)
                              (assoc gcwert aslst)
                              aslst
                              ) ;_ end of subst
                      ) ;_ end of entmod
                    (entmod
                      (subst
                        (cons gcwert wert) ;_ end of cons
                        (assoc gcwert (reverse aslst))
                        aslst
                        ) ;_ end of subst
                      ) ;_ end of entmod
                    ) ;_ end of if
                  (entupd (cdr (assoc 330 aslst)))
                  ) ;_ end of progn
                ) ;_ end of if
              (setq aslst
                    (entget (entnext (cdr (assoc -1 aslst))))
                    ) ;_ end of setq
              ) ;_ end of while
          ) ;_ end of progn
        ) ;_ end of if
      ) ;_ end of progn
    ) ;_ end of if
)

------------------
<----- Bitte Systeminfo eintragen, warum siehst du hier. Schöne Grüsse aus der Steiermark  Bernd P.

[Diese Nachricht wurde von Bernd P am 20. Jan. 2021 editiert.]

Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP

Bernhard GSD
Mitglied



Sehen Sie sich das Profil von Bernhard GSD an!   Senden Sie eine Private Message an Bernhard GSD  Schreiben Sie einen Gästebucheintrag für Bernhard GSD

Beiträge: 459
Registriert: 29.08.2002

AutoCAD 2020(Deu); Windows 10 PRO x64(Deu)

erstellt am: 01. Feb. 2021 15:41    Editieren oder löschen Sie diesen Beitrag!  <-- editieren / zitieren -->   Antwort mit Zitat in Fett Antwort mit kursivem Zitat    Unities abgeben: 1 Unity (wenig hilfreich, aber dennoch)2 Unities3 Unities4 Unities5 Unities6 Unities7 Unities8 Unities9 Unities10 Unities Nur für Maier2018 10 Unities + Antwort hilfreich

Ich verwende 2 Lisp-Befehle zum Attribut-Handling:

(:attget [blockname])

Liefert Dotted-pair Liste, die mit (CDR (ASSOC...) auszulesen ist.

Code:
(DEFUN :attget (#name / #att #elem #rückliste #ende)
  (WHILE (NOT #ende)
      (SETQ #elem (ENTGET (SETQ #name (ENTNEXT #name))))
      (IF (= (CDR (ASSOC 0 #elem)) "SEQEND")
        (SETQ #ende T)
        (SETQ #rückliste (CONS (CONS (CDR (ASSOC 2 #elem)) (CDR (ASSOC 1 #elem))) #rückliste))
      )
  )
  #rückliste
)

(:attakt [blockname] [attributbezeichnung] [neuerwert])


Code:
(DEFUN :attakt (#name #bez #wert / #brk #elem)
  (WHILE (NOT #brk)
    (SETQ #elem (ENTGET (SETQ #name (ENTNEXT #name))))
    (IF (= (CDR (ASSOC 0 #elem)) "SEQEND")(SETQ #brk T)
      (IF (= (CDR (ASSOC 2 #elem)) #bez)
        (PROGN
          (SETQ #elem (SUBST (CONS 1 #wert)(ASSOC 1 #elem) #elem))
          (ENTMOD #elem)(ENTUPD #name)
        )
      )
    )
  )
)

------------------
Gruß aus Wien
Bernhard

Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP

Anzeige.:

Anzeige: (Infos zum Werbeplatz >>)

Darstellung des Themas zum Ausdrucken. Bitte dann die Druckfunktion des Browsers verwenden. | Suche nach Beiträgen

nächster neuerer Beitrag | nächster älterer Beitrag
Antwort erstellen


Diesen Beitrag mit Lesezeichen versehen ... | Nach anderen Beiträgen suchen | CAD.de-Newsletter

Administrative Optionen: Beitrag schliessen | Archivieren/Bewegen | Beitrag melden!

Fragen und Anregungen: Kritik-Forum | Neues aus der Community: Community-Forum

(c)2021 CAD.de | Impressum | Datenschutz