@skchui6159 hi,
Although you already close this, here is my complete version 😀
Command: LMRB (you can change this to what ever you like)
It starts with select objects, than goes to find the pair of texts. we assume that a pair of texts are one above another and the distance between them is maximum of the cumulative text heights + a factor set to 1.5 by default
(setq FACT-CLOSE 1.5) ; const
if you'll find some not paired text, change this to more suitable value (but not less than 1.0)
at end unpaired texts will be highlight and selected.
this command also rely on the amazing (LM:UnFormat) function by Lee Mac.
enjoy
Moshe
(defun LM:UnFormat ( str mtx / _replace rx )
(defun _replace ( new old str )
(vlax-put-property rx 'pattern old)
(vlax-invoke rx 'replace str new)
)
(if (setq rx (vlax-get-or-create-object "VBScript.RegExp"))
(progn
(setq str
(vl-catch-all-apply
(function
(lambda ( )
(vlax-put-property rx 'global actrue)
(vlax-put-property rx 'multiline actrue)
(vlax-put-property rx 'ignorecase acfalse)
(foreach pair
'(
("\032" . "\\\\\\\\")
(" " . "\\\\P|\\n|\\t")
("$1" . "\\\\(\\\\[ACcFfHLlOopQTW])|\\\\[ACcFfHLlOopQTW][^\\\\;]*;|\\\\[ACcFfHLlOopQTW]")
("$1$2/$3" . "([^\\\\])\\\\S([^;]*)[/#\\^]([^;]*);")
("$1$2" . "\\\\(\\\\S)|[\\\\](})|}")
("$1" . "[\\\\]({)|{")
)
(setq str (_replace (car pair) (cdr pair) str))
)
(if mtx
(_replace "\\\\" "\032" (_replace "\\$1$2$3" "(\\\\[ACcFfHLlOoPpQSTW])|({)|(})" str))
(_replace "\\" "\032" str)
)
)
)
)
)
(vlax-release-object rx)
(if (null (vl-catch-all-error-p str))
str
)
)
)
)
(vl-load-com)
(defun c:lmrb (/ getMiddlePoint getCloseText isPairTexts getTextValue summarize
FACT-CLOSE ss0 ss1 ss2 ss3 ename0 ename1 text p p0 item2 pair pairs^ fname fullpath f)
(defun getMiddlePoint (ename / AcDbText Lower Upper)
(setq AcDbText (vlax-ename->vla-object ename))
(vla-getBoundingBox AcDbText 'Lower 'Upper)
(vlax-release-object AcDbText)
(mapcar
(function
(lambda (x0 x1)
(/ (+ x0 x1) 2)
)
)
(vlax-safearray->list Lower)
(vlax-safearray->list Upper)
)
)
(defun getCloseText (pt ss / ename)
(car
(vl-sort
(mapcar
(function
(lambda (ename)
(list (getMiddlePoint ename) ename)
)
)
(vl-remove-if 'listp (mapcar 'cadr (ssnamex ss)))
)
(function (lambda (e0 e1) (< (distance pt (car e0)) (distance pt (car e1)))))
)
)
)
(defun isPairTexts (t1 ent1 t2 ent2 / h1 h2)
(setq h1 (cdr (assoc '40 (entget ent1))))
(setq h2 (cdr (assoc '40 (entget ent2))))
(< (distance t1 t2) (* (+ h1 h2) FACT-CLOSE))
)
(defun getTextValue (ename / elist)
(setq elist (entget ename))
(if (eq (cdr (assoc '0 elist)) "TEXT")
(cdr (assoc '1 elist))
(LM:UnFormat (cdr (assoc '1 elist)) t)
)
)
(defun summarize (s2 s3 / i s0 p)
(cond
((and (> (sslength s2) 0) (not s3))
(setq s0 s2)
)
((and (> (sslength s2) 0) (> (sslength s3) 0))
(setq i -1 s0 (ssadd))
(foreach p (list s2 s3)
(repeat (sslength p)
(ssadd (ssname p (setq i (1+ i))) s0)
)
)
)
)
(vlr-beep-reaction)
(princ (strcat "\n" (itoa (sslength s0)) " text(s) no paired."))
(sssetfirst nil s0)
)
(setq FACT-CLOSE 1.5)
(if (setq ss0 (ssget '((0 . "text,mtext"))))
(progn
(if (< FACT-CLOSE 1.0) (setq FACT-CLOSE 1.0))
(setq ss1 (ssadd) ss2 (ssadd))
(foreach ename0 (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss0)))
(setq elist0 (entget ename0))
(if (eq (strcase (cdr (assoc '0 elist0))) "TEXT")
(setq text (cdr (assoc '1 (entget ename0))))
(setq text (LM:UnFormat (cdr (assoc '1 elist0)) t))
)
(cond
((eq (strcase (substr text 1 4)) "LMRB")
(ssadd ename0 ss1)
)
((and
(or
(setq p (vl-string-search "x" text))
(setq p (vl-string-search "X" text))
)
(eq (type (read (substr text 1 p))) 'INT)
(eq (type (read (substr text (+ p 2)))) 'INT)
)
(ssadd ename0 ss2)
)
)
)
(if (/= (sslength ss2) 0)
(progn
(setq ss3 (ssadd))
(foreach ename1 (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss1)))
(setq p0 (getMiddlePoint ename1))
(setq item2 (getCloseText p0 ss2))
(if (isPairTexts p0 ename1 (car item2) (cadr item2))
(progn
(setq pairs^ (cons (list (substr (getTextValue ename1) 1 7) ename1 (cadr item2)) pairs^))
(ssdel (cadr item2) ss2)
)
(ssadd ename1 ss3)
)
)
(setq fname (strcat (getvar "dwgprefix") (getvar "dwgname")))
(setq fullpath (strcat (vl-filename-directory fname) "\\" (vl-filename-base fname) ".csv"))
(if (findfile fullpath)
(vl-file-delete fullpath)
)
(if (not (setq f (open fullpath "w")))
(progn
(vlr-beep-reaction)
(princ (strcat "\ncan not open " fullpath " for write."))
)
(progn
(princ (strcat "\nCreating " fullpath " file."))
(write-line "BEAM MARK,SIZE" f)
(foreach pair (vl-sort pairs^ (function (lambda (e0 e1) (< (car e0) (car e1)))))
(write-line (strcat (getTextValue (cadr pair)) "," (getTextValue (caddr pair))) f)
)
(setq f (close f))
(summarize ss2 ss3)
)
)
)
(summarize ss1 nil)
)
)
)
(princ)
)