This should work
;; mttb for Move Text To Block
(defun c:mttb ( / i j ss texts blocks ent ip1 ip2 dst ind)
(setq ss (ssget (list (cons 0 "TEXT,INSERT"))))
;; lets make 2 selections. Texts and blocks
(setq texts (ssadd))
(setq blocks (ssadd))
(setq i 0)
(repeat (sslength ss)
(setq ent (entget (ssname ss i)))
(if (= "INSERT" (cdr (assoc 0 ent)))
(ssadd (ssname ss i) blocks)
(ssadd (ssname ss i) texts)
)
(setq i (+ i 1))
)
;; now we loop over the blocks, for each block we fine a text that's closest to that block.
;; (we could have chosen the the other way around)
(setq i 0)
(repeat (sslength blocks)
(setq ip1 (cdr (assoc 10 (entget (ssname blocks i)))))
(setq dst nil) ;; this holds the closest distance block-text
(setq ind nil) ;; this holds the index j for the closest distance
(setq j 0)
(repeat (sslength texts)
(setq ip2 (cdr (assoc 10 (entget (ssname texts j)))))
(if (= nil dst)
(progn ;; first try
(setq dst (distance ip1 ip2))
(setq ind j)
)
(progn ;; next we see if we find anything better
(if (< (distance ip1 ip2) dst)
(progn
(setq dst (distance ip1 ip2))
(setq ind j)
)
)
)
)
(setq j (+ j 1))
)
;; change insert point of TEXT
(setq ent (ssname texts ind))
(entmod (subst
(cons 10 ip1) ;; insert point of the block
(assoc 10 (entget ent))
(entget ent)
))
(setq i (+ i 1))
)
;; this grips the text objects. Notr really needed, but why not
(sssetfirst nil texts)
(princ)
)
EDIT
Oh yes, you can add this line of code. (ssdel ...) will remove the text from the list.
In that case the variable texts should be empty at the end, then nothing gets gripped at the end
;; change insert point of TEXT
(setq ent (ssname texts ind))
(entmod (subst
(cons 10 ip1) ;; insert point of the block
(assoc 10 (entget ent))
(entget ent)
))
;; we can remove the TEXT from the selection. No need to keep using it after we found a match
(ssdel (ssname texts ind) texts)