Lisp to explode all dynamic blocks except named blocks

Lisp to explode all dynamic blocks except named blocks

Anonymous
Not applicable
3,610 Views
11 Replies
Message 1 of 12

Lisp to explode all dynamic blocks except named blocks

Anonymous
Not applicable

Hi, 

 

I have drawings with multiple dynamic blocks in that need to be exploded except for a named blocks. I have had a look around the forums and found a lisp that will explode all static blocks except named blocks, but this wont do because there are too many static blocks to exclude. This lisp is as follows-

 

(defun c:HSSBOM()
(if (SETQ fgh (SSGET "_X" (list
'(0 . "INSERT")
(cons 410 (getvar "ctab"))
'(-4 . "<NOT")
'(2 . "A1_MECH_FRAME")
'(-4 . "NOT>")
'(-4 . "<NOT")
'(2 . "PANEL SPEC TABLE")
'(-4 . "NOT>")
'(-4 . "<NOT")
'(2 . "CHASES & DIMS")
'(-4 . "NOT>")
)))
(progn
(setq cntr 0)
(while (< cntr (sslength fgh))
(command "_.Explode" (ssname fgh cntr))
;catch the possibility of it being an xref or
;non explodable block which would leave the cmd active
(if (> (getvar "cmdactive") 0)
(command "")
);if not explodable
(setq cntr (1+ cntr))
);while
);progn have selset True
);If selset is created
);defun

 

Is there anything similar or a way to modify the lisp that will do as mentioned-

  • explode all dynamics blocks (not static blocks if possible)
  • exclude blocks called "PANEL SPEC TABLE", "A1_MECH_FRAME", "CHASES & DIMS".

 

Thanks

 

Danny

0 Likes
Accepted solutions (1)
3,611 Views
11 Replies
Replies (11)
Message 2 of 12

DannyNL
Advisor
Advisor
Accepted solution

Hi Danny Smiley Wink

 

Try the code below. It will explode all dynamic blocks excluding the names as specified.

 

(defun c:Test (/ T_Selection T_Count T_Object)
   (if
      (setq T_Selection (ssget "_X" (list '(0 . "INSERT")(cons 410 (getvar "CTAB")))))
      (progn
         (setq T_Count 0)
         (vla-StartUndoMark (vla-get-ActiveDocument (vlax-get-acad-object)))
         (foreach T_Item (ssnamex T_Selection)
            (setq T_Object (vlax-ename->vla-object (cadr T_Item)))
            (if
               (and
                  (= (vla-get-IsDynamicBlock T_Object) :vlax-true)
                  (not (member (strcase (vla-get-EffectiveName T_Object)) '("PANEL SPEC TABLE" "A1_MECH_FRAME" "CHASES & DIMS")))
               )
               (progn
                  (vla-Explode T_Object)
                  (setq T_Count (1+ T_Count))
               )
            )
         )
         (vla-EndUndoMark (vla-get-ActiveDocument (vlax-get-acad-object)))
         (princ (strcat "\n ** Total of " (itoa T_Count) " dynamic blocks exploded."))
      )
   )
   (princ)
)
Message 3 of 12

Anonymous
Not applicable

That is great, works well.

 

2 out of 2 Smiley Very Happy

 

Think i should make an effort and learn a bit myself.

 

Thanks,

 

Danny

0 Likes
Message 4 of 12

DannyNL
Advisor
Advisor

Good to hear & glad I could help Smiley Happy

0 Likes
Message 5 of 12

DannyNL
Advisor
Advisor

BTW, for your info; it's also possible to convert a dynamic block to a static block. So the block will be frozen in the current settings and all dynamic parameters are removed.

 

Upside of this compared to exploding is that it still remains a block and one object in your drawing. Downside is that the number of blocks in the drawing will increase and if you look at the INSERT command, the list of available blocks can be huge due to that each converted dynamic block will get a new name.

0 Likes
Message 6 of 12

Anonymous
Not applicable

I just stumbled on to this. I was wondering how this could be inverted.
Lets say, I want to just explode a dynamic block with the "Real Name ADA" but it has 4 different Visibility States.

 

How could you just target those to be exploded or deleted and keep all the other dynamic blocks in the drawing safe.

0 Likes
Message 7 of 12

dlanorh
Advisor
Advisor

Do you mean only explode a certain named dynamic block with a certain visibility state, or all the named dynamic blocks?

 

e.g.  real (defined) name of block = "test1"

 

explode all "test1" dynamic blocks with visibility state "normal"

or

just explode all "test1" dynamic blocks 

I am not one of the robots you're looking for

0 Likes
Message 8 of 12

Anonymous
Not applicable

All of the visibility states of the dynamic block.

 

If the dynamic block is named ADA and it has 3 different visibility states. Then explode the ADA and the 3 states possibly even if one of the states is not used. Then not to explode all the other blocks that are used in the drawing.

0 Likes
Message 9 of 12

dlanorh
Advisor
Advisor

Try this :

;; Explode Dynamic Blocks by Name (dlanorh)
(vl-load-com)

(defun c:XDBN ( / *error* c_doc c_blks d_blk ent obj b_nme blk ss b_lst)
 
  (defun *error* ( msg ) 
    (if (and c_doc (= 8 (logand 8 (getvar 'UNDOCTL)))) (vla-endundomark c_doc))
    (if (not (wcmatch (strcase msg) "*BREAK*,*CANCEL*,*EXIT*")) (princ (strcat "\nOops an Error occurred : " msg)))
    (princ)
  );end_defun *error*

  (setq c_doc (vla-get-activedocument (vlax-get-acad-object))
        c_blks (vla-get-blocks c_doc)
        d_blk nil
        b_lst nil
  );end_setq
  
  (while (not d_blk)
    (setq ent (car (entsel "\nSelect Instance of Dynamic Block to Explode : ")))
    (cond ( (and ent (= (cdr (assoc 0 (entget ent))) "INSERT"))
            (setq obj (vlax-ename->vla-object ent)
                  b_nme (vlax-get-property obj 'effectivename)
                  blk (vla-item c_blks b_nme)      
            );end_setq
            (cond ( (and  (= :vlax-true (vlax-get-property blk 'explodable))
                          (= :vlax-true (vlax-get-property blk 'isdynamicblock))
                    );end_and
                    (setq d_blk t)
                  )
                  ( (= :vlax-false (vlax-get-property blk 'explodable)) (alert "Block is not explodable"))
                  ( (= :vlax-false (vlax-get-property blk 'isdynamicblock)) (alert "Not a Dynamic Block"))
            );end_cond
          )
    );end_cond
  );end_while  

  (setq ss (ssget "_X" (list '(0 . "INSERT")(cons 410 (getvar "CTAB")))))
  (cond (ss
          (if (and c_doc (= 8 (logand 8 (getvar 'UNDOCTL)))) (vla-endundomark c_doc))
          (vla-startundomark c_doc)
          (vlax-for blk (vla-get-activeselectionset c_doc)
            (cond ( (and  (= :vlax-true (vlax-get-property blk 'isdynamicblock))
                          (= (vlax-get-property blk 'effectivename) b_nme)
                    );end_and
                    (vlax-invoke blk 'explode)
                    (setq b_lst (cons blk b_lst)) 
                  )
            );end_cond
          );end_for
        )
  );end_cond
  
  (foreach blk (reverse b_lst) (vla-delete blk))
  
  (if (and c_doc (= 8 (logand 8 (getvar 'UNDOCTL)))) (vla-endundomark c_doc))
  (princ)
);end_defun

The user is asked to select one of the blocks to be exploded (dynamic blocks are anonymous)

The lisp then finds the blocks defined effective name, checks that it is dynamic and explodable, (alerts if not) and gets all the blocks in the drawing. It then iterates the selection set and explodes only those blocks that match the original selected blocks effective name.

 

Limitations : The current reference block visibility state defines which objects are retained. Any Block attributes default to the attributes tag name, not it's value.

 

Test it first to ensure it is what you want.

 

I am not one of the robots you're looking for

0 Likes
Message 10 of 12

Anonymous
Not applicable

Awesome! Thank you so much! Works great!

0 Likes
Message 11 of 12

dlanorh
Advisor
Advisor
No problem, glad I could help.

I am not one of the robots you're looking for

0 Likes
Message 12 of 12

MSA3DY
Contributor
Contributor
This is great lisp, but the dynamic block still in the file, I found two copies of block, one is exploded and the other is not.
0 Likes