I am working with groups in AutoCAD and, due to copy pasting them from different drawings, they ungroup. In the possibility of me forgetting to regroup them, I want to create a code that, when I think I am finished with the drawing, can check if a list of blocks (every group has a block) is not inside a group.
As such, the idea is that it would run from a selection of blocks (ex: block1, block3, block7) and check if those particular blocks are grouped. If not, it would tell me which block is ungrouped.
As the tags suggest, either vba or autolisp is fine. I am fairly novice at this, any help would be fairly appreciated.
edit: knowing how I could get a block group name in vba would be great
A block definition may have many block references: the block definition is analogous to the blueprints for a building, with each block reference analogous to the construction of the building itself.
As such, given only a list of block names, each block name may correspond to multiple block references, with some contained within groups, and others not.
You can therefore approach this task from two angles:
ACAD_GROUP
dictionary contained within the Named Object Dictionary), and obtain the set of distinct block names corresponding to blocks contained within at least one Group.OR
GROUP
entity via an {ACAD_REACTORS}
entry in the DXF data. Compile a list of block names corresponding to blocks which are either contained within at least one group, or not contained within any group.Given such a list, you can then easily test whether any of your block names are not present in the list.
Below is a function that will iterate over all Groups defined within the ACAD_GROUP
dictionary of the Named Object Dictionary, and will return a list of the names of block references contained within one or more groups:
(defun blocknamesfromgroups ( / blk dic enx grp rtn )
(if (setq dic (cdr (assoc -1 (dictsearch (namedobjdict) "acad_group"))))
(while (setq grp (dictnext dic (not grp)))
(foreach itm grp
(if (and (= 340 (car itm)) (= "INSERT" (cdr (assoc 0 (setq enx (entget (cdr itm)))))))
(if (not (member (setq blk (cdr (assoc 2 enx))) rtn))
(setq rtn (cons blk rtn))
)
)
)
)
)
(reverse rtn)
)
Alternatively, the below function will iterate over all primary block references in the active drawing and will report the names of block references not contained within a group:
(defun blocknamesnotgrouped ( / blk enx grp idx sel rtn )
(if (setq sel (ssget "_X" '((0 . "INSERT"))))
(repeat (setq idx (sslength sel))
(setq idx (1- idx)
enx (entget (ssname sel idx))
blk (cdr (assoc 2 enx))
)
(if
(not
(or
(and
(setq enx (member '(102 . "{ACAD_REACTORS") enx))
(setq grp (cdr (assoc 330 enx)))
(= "GROUP" (cdr (assoc 0 (entget grp))))
)
(member blk rtn)
)
)
(setq rtn (cons blk rtn))
)
)
)
(reverse rtn)
)