Using some code found here on AUGI and Autodesk's forums, we have this ... thing. It will overwrite the last row of attributes items. It will move a row of attributes down to the next line. If that line is not empty, it will move the rows below until an empty row is found. It will then empty the selected row.
Code:
(defun c:bumpRow (/ oBlock oAttributes bEmptyRow
eBlock i iEmptyRow lstAttribs
lstRows oRow sRow iRow
GetBlkAttrib PutBlkAttrib
)
;-------------------------------------------------------------------------------
; GetBlkAttrib - Get Block Attribute value
; Arguments: 2
; BlkOrEntity = Block or entity name
; AttrTag$ = Tag label of attribute
; Returns: Attribute value
; If BlkOrEntity is a block name, it gets the attribute of the first block found.
;-------------------------------------------------------------------------------
(defun GetBlkAttrib (BlkOrEntity AttrTag$ / AttrVal$
EntAttr$ EntList@ EntName^ EntTag$
EntType$ Passed SS&
)
(if (= (type BlkOrEntity) 'ENAME)
(progn
(setq EntName^ BlkOrEntity
EntList@ (entget EntName^)
EntType$ (cdr (assoc 0 EntList@))
) ;setq
(if (and (= EntType$ "INSERT") (assoc 66 EntList@))
(setq Passed t)
) ;if
) ;progn
(if (setq
SS& (ssget
"x"
(list '(0 . "INSERT") '(66 . 1) (cons 2 BlkOrEntity))
)
)
(setq EntName^ (ssname SS& (1- (sslength SS&)))
EntList@ (entget EntName^)
Passed t
) ;setq
) ;if
) ;if
(if Passed
(while (/= (cdr (assoc 0 EntList@)) "SEQEND")
(setq EntList@ (entget EntName^)
EntType$ (cdr (assoc 0 EntList@))
EntAttr$ (cdr (assoc 1 EntList@))
EntTag$ (cdr (assoc 2 EntList@))
) ;setq
(if (= EntType$ "ATTRIB")
(if (= EntTag$ (strcase AttrTag$))
(setq AttrVal$ EntAttr$)
)
) ;if
(setq EntName^ (entnext EntName^))
) ;while
) ;if
AttrVal$
) ;defun GetBlkAttrib
;-------------------------------------------------------------------------------
; PutBlkAttrib - Put Block Attribute value
; Arguments: 3
; BlkOrEntity = Block or entity name
; AttrTag$ = Tag label of attribute
; AttrVal$ = New Value for attribute
; Returns: Changes attribute value
; If BlkOrEntity is a block name, it changes only the first block found.
;-------------------------------------------------------------------------------
(defun PutBlkAttrib (BlkOrEntity AttrTag$ AttrVal$ /
EntAttr$ EntList@ EntName^ EntTag$
EntType$ First Passed SS&
)
(if (= (type BlkOrEntity) 'ENAME)
(progn
(setq EntName^ BlkOrEntity
EntList@ (entget EntName^)
EntType$ (cdr (assoc 0 EntList@))
) ;setq
(if (and (= EntType$ "INSERT") (assoc 66 EntList@))
(setq Passed t
First t
)
) ;if
) ;progn
(if (setq
SS& (ssget
"x"
(list '(0 . "INSERT") '(66 . 1) (cons 2 BlkOrEntity))
)
)
(setq EntName^ (ssname SS& (1- (sslength SS&)))
EntList@ (entget EntName^)
Passed t
First t
) ;setq
) ;if
) ;if
(if Passed
(while (/= (cdr (assoc 0 EntList@)) "SEQEND")
(setq EntList@ (entget EntName^)
EntType$ (cdr (assoc 0 EntList@))
EntTag$ (cdr (assoc 2 EntList@))
) ;setq
(if (= EntType$ "ATTRIB")
(if (and (= EntTag$ (strcase AttrTag$)) First)
(progn
(entmod
(subst (cons 1 AttrVal$) (assoc 1 EntList@) EntList@)
)
(entupd EntName^)
(setq First nil)
) ;progn
) ;if
) ;if
(setq EntName^ (entnext EntName^))
) ;while
) ;if
(princ)
) ;defun PutBlkAttrib
(defun br:CheckRowStringCount (num lst / o)
(setq o 0)
(foreach n (cdr (nth num lst))
(setq o (+ o (strlen (cdr n))))
)
o
)
(defun num-char-p (num)
;; Does (chr num) represent a numeric character (0...9)?
(<= 48 num 57)
)
(defun d (str)
(vl-list->string
(vl-remove-if-not
'num-char-p
(vl-string->list str)
)
)
)
(setq lstAttribs '())
(if (and (setq eBlock (entsel "\nSelect material row to bump: "))
(= (type eBlock) 'LIST)
(= (type (car eBlock)) 'ENAME)
(setq oBlock (m:object eBlock))
(= (vla-get-hasAttributes oBlock) :vlax-true)
(setq oAttributes (m:safelist (vla-getattributes oBlock)))
(setq oRow (nentselp (last eBlock)))
(setq oRow (m:object oRow))
(= (vla-get-ObjectName oRow) "AcDbAttribute")
(setq sRow (d (vla-get-tagstring oRow)))
)
(foreach n oAttributes
(setq i (d (vla-get-tagstring n)))
(if (assoc i lstAttribs)
(setq lstAttribs
(subst
(append
(assoc i lstAttribs)
(list (cons (vla-get-tagstring n) (vla-get-textstring n)))
)
(assoc i lstAttribs)
lstAttribs
)
)
(setq lstAttribs
(append
lstAttribs
(list
(cons
i
(list (cons (vla-get-tagstring n) (vla-get-textstring n))
)
)
)
)
)
)
)
)
(setq iRow (1- (atoi sRow))
lstRows (list (nth iRow lstAttribs))
bEmptyRow nil
iEmptyRow (br:CheckRowStringCount iRow lstAttribs)
)
(while (or (= iRow (length lstAttribs))
(> iEmptyRow 0)
)
(setq iRow (1+ iRow)
lstRows (append lstRows (list (nth iRow lstAttribs)))
iEmptyRow (br:CheckRowStringCount iRow lstAttribs)
)
)
(foreach n (reverse (cdr lstRows))
(foreach j (cdr n)
(PutBlkAttrib
(car eBlock)
(car j)
(getBlkAttrib
(car eBlock)
(vl-string-subst
(itoa (1- (atoi (d (car j)))))
(d (car j))
(car j)
)
)
)
)
)
(foreach n (cdr (car lstRows))
(PutBlkAttrib (car eBlock) (car n) "")
)
(princ)
)
I do not currently have any available time and do not plan on supporting this any further at the moment.