Here is the my lisp for multiple attribute changer that ChatGPT made.
1. Save it to XXX.lsp in Notepad
;; ------------------------------------------------------------
;; ATTBATCH — Batch-edit Attribute values on selected INSERTs
;; ------------------------------------------------------------
;; What it does
;; Updates Attribute VALUE (DXF code 1) for the chosen TAG on
;; every selected block reference (entity type: INSERT).
;;
;; Command
;; ATTBATCH
;;
;; Usage
;; 1) Load with APPLOAD.
;; 2) Type ATTBATCH.
;; 3) Enter the Attribute TAG to change.
;; - Type "*" (just an asterisk) to update ALL tags.
;; - Otherwise only the matching TAG (case-insensitive) is changed.
;; 4) Enter the NEW value to apply.
;; 5) Select target block references (INSERT). Press Enter to finish.
;;
;; Notes
;; - Constant Attributes (from ATTDEF set to Constant) aren’t present
;; on instances; edit the block definition and then run ATTSYNC for those.
;; - If an Attribute had a Field, it will be replaced by plain text.
;; - Works with MINSERT: each instance is processed.
;; - Pure AutoLISP only: compatible with environments lacking VLA/ActiveX.
;;
;; Change log
;; - Only treats "*" as “all tags”. A real TAG string updates that TAG only.
;; ------------------------------------------------------------
(defun c:ATTBATCH (/ _equal-ci _collect-attribs
tag new ss i ent cnt
lst a dxf atag doAll)
;; Case-insensitive compare
(defun _equal-ci (s1 s2) (= (strcase s1) (strcase s2)))
;; Collect ATTRIB entities following an INSERT until SEQEND
(defun _collect-attribs (ins / e typ acc)
(setq e (entnext ins))
(while (and e
(setq typ (cdr (assoc 0 (entget e))))
(/= typ "SEQEND"))
(if (= typ "ATTRIB") (setq acc (cons e acc)))
(setq e (entnext e))
)
(reverse acc)
)
;; Inputs
(setq tag (getstring T "\nEnter Attribute TAG to change (* = all): "))
(if (null tag) (setq tag ""))
(setq new (getstring T "\nEnter new Attribute value: "))
(if (null new) (setq new ""))
;; ONLY treat as 'all' when the user typed "*" exactly
(setq doAll (= (strcase tag) "*"))
(prompt "\nSelect block references (INSERT): ")
(setq ss (ssget '((0 . "INSERT"))))
(if ss
(progn
;; optional: group into one undo step (pure command call)
(command "_.UNDO" "_Begin")
(setq cnt 0
i 0)
(while (< i (sslength ss))
(setq ent (ssname ss i))
(setq lst (_collect-attribs ent))
;; Process each ATTRIB
(while lst
(setq a (car lst)
dxf (entget a)
;; TAG = code 2, VALUE = code 1
atag (cdr (assoc 2 dxf)))
(if (or doAll
(_equal-ci atag tag))
(progn
;; Update value (code 1); add if missing
(if (assoc 1 dxf)
(setq dxf (subst (cons 1 new) (assoc 1 dxf) dxf))
(setq dxf (append dxf (list (cons 1 new))))
)
(entmod dxf)
(setq cnt (1+ cnt))
)
)
(setq lst (cdr lst))
)
;; Refresh display for the block reference
(entupd ent)
(setq i (1+ i))
)
(command "_.UNDO" "_End")
(princ (strcat "\nDone: updated " (itoa cnt) " Attribute(s)."))
)
(prompt "\nSelection canceled.")
)
(princ)
)