Thank @Sea-Haven for your support. I’ve tested the LISP you created, but unfortunately, it still doesn’t work for me. That said, it’s very helpful, and since I don’t have much knowledge of AutoLISP, I asked Grok to help improve it. Now, it works reasonably well for my current needs, though it’s still not exactly what I was hoping for.
I’d like to share it again in case you or someone else can help further improve it, so that others facing similar situations might benefit as well.
The main reason I’m not fully satisfied is that after selecting a rectangle to set the layer, the lisp automatically selects all rectangles in the drawing on that layer. It doesn’t allow the user to manually choose a specific area containing the rectangles to be processed. Additionally, the block creation direction seems random rather than following a consistent order along the X-axis and then the negative Y-axis.
; Create blocks from objects within rectangles
; Improved from AlanH's idea | July 2025
(defun c:wow (/ bname lay ss num x entname plobj co-ord minpt maxpt insertpt blkname innerSS)
(vl-load-com) ; Load ActiveX automation
(setvar "CMDECHO" 0) ; Turn off command echo
;; Prompt for block name prefix
(while (not (setq bname (getstring t "\nEnter block name prefix: ")))
(princ "\nBlock name cannot be empty."))
(if (= bname "") (setq bname "BLOCK")) ; Set default name if empty
;; Select a sample rectangle to get layer
(while (not (and (setq entname (entsel "\nPick a rectangle to get layer: "))
(setq entdata (entget (car entname)))
(= (cdr (assoc 0 entdata)) "LWPOLYLINE")))
(princ "\nPlease select a valid LWPOLYLINE (rectangle)."))
(setq lay (cdr (assoc 8 entdata)))
;; Select all LWPOLYLINEs on the specified layer
(princ "\nSelecting rectangles...")
(setq ss (ssget "_X" (list (cons 0 "LWPOLYLINE") (cons 8 lay))))
(if (not ss)
(progn
(princ "\nNo rectangles found on layer.")
(setvar "CMDECHO" 1)
(princ)
(exit)
)
)
(setq num 0)
(setq x 0)
;; Turn off the layer containing rectangles
(vl-cmdf "-layer" "off" lay "")
;; Loop through each rectangle
(while (< x (sslength ss))
(setq plobj (ssname ss x))
(setq co-ord (mapcar 'cdr (vl-remove-if-not
'(lambda (x) (= (car x) 10))
(entget plobj))))
;; Check if the polyline is a rectangle (4 vertices)
(if (= (length co-ord) 4)
(progn
;; Determine min and max points
(setq minpt (list (apply 'min (mapcar 'car co-ord))
(apply 'min (mapcar 'cadr co-ord))))
(setq maxpt (list (apply 'max (mapcar 'car co-ord))
(apply 'max (mapcar 'cadr co-ord))))
;; Calculate midpoint for block insertion
(setq insertpt (mapcar '(lambda (a b) (/ (+ a b) 2.0)) minpt maxpt))
;; Find all objects inside the rectangle
(setq innerSS (ssget "_CP" (list minpt
(list (car maxpt) (cadr minpt))
maxpt
(list (car minpt) (cadr maxpt))
minpt)))
;; Remove the rectangle polyline from the selection set
(if innerSS
(progn
(ssdel plobj innerSS)
(if (> (sslength innerSS) 0)
(progn
(setq num (1+ num))
(setq blkname (strcat bname "-" (itoa num)))
;; Check if block already exists
(if (tblobjname "BLOCK" blkname)
(princ (strcat "\nBlock " blkname " already exists. Skipping."))
(progn
;; Create block
(vl-cmdf "-block" blkname insertpt innerSS "")
;; Insert block
(vl-cmdf "insert" blkname insertpt 1 1 0)
)
)
)
)
)
)
)
(princ "\nWarning: Polyline is not a rectangle (does not have 4 vertices).")
)
(setq x (1+ x))
)
;; Turn on the layer containing rectangles
(vl-cmdf "-layer" "on" lay "")
(setvar "CMDECHO" 1)
(princ)
)