CXATTCOPYBlöcke und AttributeVersion 1.0.0In AutoCAD getestet
Attributwerte von einem Block auf andere kopieren
Nimmt die Attributwerte eines Blocks und schreibt sie in die anderen gewählten Blöcke, entweder alle Attribute oder nur die, die Sie nennen.
So verwenden Sie ihn
- CXATTCOPY eingeben und den Quellblock anklicken.
- Die zu füllenden Blöcke wählen.
- Die zu kopierenden Attributnamen durch Komma getrennt eingeben, oder - für alle.
Gut zu wissen
- Kopiert werden nur Attribute, die in beiden Blöcken vorkommen.
In AutoCAD laden
- Speichern Sie die Datei an einem beliebigen Ort.
- Geben Sie APPLOAD ein, wählen Sie die Datei und klicken Sie auf Laden.
- Geben Sie den Befehl ein: CXATTCOPY.
Damit er bei jedem Start bereitsteht, fügen Sie ihn im selben Dialog zum Startup-Set hinzu, oder laden Sie mit dem optionalen Loader einen ganzen Ordner auf einmal. Der optionale Loader
In AutoCAD (Vollversion) getestet. Andere Programme, die AutoLISP ausführen, funktionieren vielleicht, wurden aber nicht getestet.
Der Code
Reiner Text, nichts ist versteckt. Kopieren Sie ihn in eine Datei namens cxattcopy.lsp oder laden Sie ihn herunter.
;;; ============================================================================
;;; CXATTCOPY - Copy attribute values from one block to others
;;; Version 1.0.0
;;; CADXChange LISP tools - https://cadxchange.net/resources/lisp/cxattcopy
;;; Tested in: AutoCAD (full version). Other programs that run AutoLISP may work but are not tested.
;;; Copyright (c) CADXChange. Free for personal and commercial use; do not resell or
;;; republish it as a collection. Terms: https://cadxchange.net/legal/lisp-terms
;;; ============================================================================
;; Copy attribute values from the block SOURCE to every block in TARGETS that has the same tags.
;; TAGS is a list of tag names, or nil for all tags of the source. Returns how many values were copied.
(defun cx:attcopy-run (source targets tags / n)
(setq n 0)
(foreach e targets
(if (/= e source)
(foreach tg (if tags tags (cx:tags (list source)))
(if (and (cx:att-find e tg) (cx:att-find source tg))
(progn
(cx:att-set e tg (cx:att-get source tg))
(setq n (1+ n)))))))
n)
(defun c:CXATTCOPY ( / *error* cx:sv r source ss tags answer n)
(setq *error* cx:err)
(setq r (entsel "\nClick the block to copy the attribute values from: "))
(cond
((null r))
((/= (cx:dxf 0 (entget (car r))) "INSERT") (princ "\nThat is not a block."))
((null (cx:attribs (car r))) (princ "\nThat block has no attributes."))
(T
(setq source (car r))
(princ (strcat "\nAttributes: " (cx:join (cx:tags (list source)) ", ")))
(if (setq ss (ssget '((0 . "INSERT") (66 . 1))))
(progn
(setq answer (cx:ask-str "Tags to copy, separated by commas (- for all)" "-"))
(setq tags (if (member answer '("-" "")) nil (mapcar 'cx:trim (cx:split answer ","))))
(cx:start '(("CMDECHO" . 0)))
(setq n (cx:attcopy-run source (cx:ss->list ss) tags))
(princ (strcat "\n" (itoa n) " value(s) copied."))
(cx:end)))))
(princ))
;;; ---- Shared helpers (used by the command above; identical in every CADXChange tool) ----
(defun cx:dxf (code ed)
(cdr (assoc code ed)))
;; The ATTRIB entities of a block reference, in order.
(defun cx:attribs (ins / e out)
(setq e (entnext ins))
(while (and e (= (cx:dxf 0 (entget e)) "ATTRIB"))
(setq out (cons e out) e (entnext e)))
(reverse out))
;; The attribute tags found in a list of block references, each once, in order of appearance.
(defun cx:tags (names / out)
(foreach e names
(foreach a (cx:attribs e)
(if (not (member (strcase (cx:dxf 2 (entget a))) (mapcar 'strcase out)))
(setq out (append out (list (cx:dxf 2 (entget a))))))))
out)
;; The ATTRIB of a block reference with the tag TAG (any case), or nil.
(defun cx:att-find (ins tag / r)
(foreach a (cx:attribs ins)
(if (and (not r) (= (strcase (cx:dxf 2 (entget a))) (strcase tag))) (setq r a)))
r)
;; Replace the text of a TEXT, ATTRIB, ATTDEF or MTEXT.
(defun cx:text-set (ename str / ed out)
(setq ed (entget ename))
(if (= (cx:dxf 0 ed) "MTEXT")
(progn
;; MTEXT stores text in 250-character pieces: 3 groups for the first pieces, 1 for the last
(foreach p ed (if (not (member (car p) '(1 3))) (setq out (cons p out))))
(setq out (reverse out))
(while (> (strlen str) 250)
(setq out (append out (list (cons 3 (substr str 1 250)))) str (substr str 251)))
(setq ed (append out (list (cons 1 str)))))
(setq ed (subst (cons 1 str) (assoc 1 ed) ed)))
(entmod ed)
(entupd ename)
T)
;; Set the attribute TAG of a block reference to VALUE; returns T when the block has that attribute.
(defun cx:att-set (ins tag value / a)
(if (setq a (cx:att-find ins tag))
(progn (cx:text-set a value) (entupd ins) T)))
(defun cx:att-get (ins tag / a)
(if (setq a (cx:att-find ins tag)) (cx:dxf 1 (entget a))))
;; Close the undo step and put the system variables back.
(defun cx:end ()
(foreach v cx:sv (setvar (car v) (cdr v)))
(command "_.UNDO" "_End")
(setq cx:sv nil)
(princ))
;; Error handler: restores everything, stays quiet on Esc.
(defun cx:err (msg)
(if (> (getvar "CMDACTIVE") 0) (command))
(cx:end)
(if (and msg (not (wcmatch (strcase msg) "*BREAK*,*CANCEL*,*EXIT*")))
(princ (strcat "\nError: " msg)))
(princ))
(defun cx:join (lst delim / out)
(setq out "")
(foreach s lst
(setq out (if (= out "") s (strcat out delim s))))
(if lst out ""))
;; Ask for a string (spaces allowed) with a default; "-" means an empty string.
(defun cx:ask-str (msg def / v)
(setq v (getstring T (strcat "\n" msg " <" def ">: ")))
(cond ((= v "") def) ((= v "-") "") (T v)))
;; Remove spaces and tabs at both ends.
(defun cx:trim (s / a b)
(setq a 1 b (strlen s))
(while (and (<= a b) (member (substr s a 1) '(" " "\t"))) (setq a (1+ a)))
(while (and (>= b a) (member (substr s b 1) '(" " "\t"))) (setq b (1- b)))
(substr s a (max 0 (1+ (- b a)))))
;; Split STR at every DELIM (a one-character string) into a list of strings.
(defun cx:split (str delim / out cur i c)
(setq out nil cur "" i 1)
(while (<= i (strlen str))
(setq c (substr str i 1))
(if (= c delim)
(setq out (cons cur out) cur "")
(setq cur (strcat cur c)))
(setq i (1+ i)))
(reverse (cons cur out)))
;; Save the system variables in VARS ((name . value) ...), set them, and open one undo step.
;; The caller declares cx:sv as a local so the saved values live exactly as long as the command.
(defun cx:start (vars)
(setq cx:sv (mapcar (function (lambda (v) (cons (car v) (getvar (car v))))) vars))
(command "_.UNDO" "_Begin")
(foreach v vars (setvar (car v) (cdr v)))
(princ))
;; Selection set to a list of entity names.
(defun cx:ss->list (ss / i out)
(setq i 0)
(if ss
(repeat (sslength ss)
(setq out (cons (ssname ss i) out)
i (1+ i))))
(reverse out))
(princ "\nCXATTCOPY loaded. Type CXATTCOPY to start.")
(princ)
Versionsverlauf
Version 1.0.0 · 27. Oktober 2026
Erste Veröffentlichung.
Für viele Zeichnungen auf einmal?
BlockSync erledigt diese Art von Aufgabe für einen ganzen Ordner voller Zeichnungen in einem Durchlauf.
BlockSyncWeitere Befehle: Blöcke und Attribute
CXATTFILLEin Attribut in vielen Blöcken ausfüllenCXATTNUMEin Blockattribut fortlaufend nummerierenCXATTVISBlockattribute ein- oder ausblendenCXBLKCOUNTBlöcke nach Namen zählenCXBLKREPLBlöcke durch einen anderen Block ersetzenCXBLKRENBlöcke gesammelt umbenennenCXBLKXPBlöcke auflösen, aber den Attributtext behaltenCXBLKSELBlöcke nach Name oder Attributwert auswählenCXBLKATEinen Block an vielen Stellen auf einmal einfügen