Here's a proof-of-concept example for consideration -
(defun update-attributes ( / bln idx ins map obj sel tag val )
(setq
;; List of
;; ((lower-left point) (upper-right point) "attribute value")
map
'(
(( 0.0 0.0) (10.0 10.0) "abc")
((20.0 20.0) (30.0 30.0) "def")
)
;; Block name
bln "YourBlock"
tag "YourTag"
)
(setq bln (strcase bln)
tag (strcase tag)
)
(if (setq sel (ssget "_X" (list '(0 . "INSERT") '(66 . 1) (cons 2 (strcat "`*U*," bln)))))
(repeat (setq idx (sslength sel))
(setq idx (1- idx)
obj (vlax-ename->vla-object (ssname sel idx))
)
(cond
( (/= bln (strcase (vlax-get-property obj (if (vlax-property-available-p obj 'effectivename) 'effectivename 'name)))))
( (setq ins (vlax-get obj 'insertionpoint)
val (vl-some '(lambda ( itm ) (if (vl-every '<= (car itm) ins (cadr itm)) (caddr itm))) map)
)
(vl-some
'(lambda ( att )
(if (= tag (strcase (vla-get-tagstring att)))
(progn
(if (vlax-write-enabled-p att)
(vla-put-textstring att val)
)
t
)
)
)
(vlax-invoke obj 'getattributes)
)
)
)
)
)
)
(defun block-position-callback ( rtr arg )
(if (and arg (wcmatch (strcase (car arg) t) "qsave,save,saveas,plot,publish"))
(update-attributes)
)
(princ)
)
(
(lambda ( key )
(vl-load-com)
(foreach rtr (cdar (vlr-reactors :vlr-command-reactor))
(if (= key (vlr-data rtr))
(vlr-remove rtr)
)
)
(vlr-set-notification
(vlr-command-reactor key
'(
(:vlr-commandwillstart . block-position-callback)
)
)
'active-document-only
)
(update-attributes)
(princ)
)
"block-position-reactor"
)
There is no command to run the program: simply amend the block name, tag name, and map at the top of the code to suit your setup, and then load the program - the attributes will be automatically updated when the drawing is saved or plotted.