Replace old block with new dynamic block

Replace old block with new dynamic block

bsanada
Advocate Advocate
1,537 Views
9 Replies
Message 1 of 10

Replace old block with new dynamic block

bsanada
Advocate
Advocate

I have several older blocks that I'm attempting to replace with a new dynamic block.  This new dynamic block has a visibility state for each of the old blocks I am trying to replace.  If I have 3 old blocks (block-1, block-2, block-3) and 3 visibilty states in the new block (state-1, state-2, state-3) I would like to have the visibility state set to "state-1" when replacing "block-1", "state-2" when replacing "block-2", etc.  If I set the correct visibility state as the default before replacing that particular block it works, but I haven't been able to find a way to change the default visibility state using a script or lisp.  Another option I explored was to insert a new version of the dynamic block into the drawing with a different visibility state as the default, but this changed the visibility state of the previous blocks.  For example I update block-1 with the new block set to state-1 and inserted a new version of the dynamic block with state-2 as the default visibility state, but when the block gets redefined it changes the visibility state of the blocks previously set to state-1 to state-2.

 

Any suggestions?

 

Thanks,

Brad

0 Likes
Accepted solutions (1)
1,538 Views
9 Replies
Replies (9)
Message 2 of 10

hmsilva
Mentor
Mentor

Hi Brad,

'Quick and Dirty' and not test for locked layers....

 

(vl-load-com)
(defun c:demo (/ ss blk obj)
    (if (and
            (setq ss (ssget "_X" (list '(0 . "INSERT") '(2 . "block-1,block-2,block-3") (cons 410 (getvar 'CTAB)))))
            (setq blk (findfile "C:\\folder1\\folder\\newdynamicblock.dwg")) ; change to the correct full name
        )
        (repeat (setq i (sslength ss))
            (setq obj  (vlax-ename->vla-object (ssname ss (setq i (1- i))))
                  name (vla-get-effectivename obj)
            )
            (cond ((= name "block-1")
                   (setq vis "state-1")
                  )
                  ((= name "block-2")
                   (setq vis "state-2")
                  )
                  (T
                   (setq vis "state-3")
                  )
            )
            (command "-insert" blk "_S" 1 "_R" 0 "_NONE" (vlax-get obj 'InsertionPoint))
            (setq lasthnd (entlast)
                  lastobj (vlax-ename->vla-object lasthnd)
            )
            (if (and (vlax-property-available-p lastobj 'IsDynamicBlock)
                     (eq (vla-get-IsDynamicBlock lastobj) :vlax-true)
                )
                (progn
                    (foreach p (vlax-safearray->list
                                   (vlax-variant-value (vla-getdynamicblockproperties lastobj))
                               )
                        (if (and (eq (vlax-get p 'PropertyName) "VisibilityName") ; change to the correct Name
                                 (vl-position vis (vlax-get p 'AllowedValues))
                            )
                            (vlax-put-property p "Value" vis)
                        )
                    )
                    (vla-delete obj)
                )
            )
        )
    )
    (princ)
)

 

Hope this helps,
Henrique

EESignature

0 Likes
Message 3 of 10

bsanada
Advocate
Advocate

Henrique, first of all thanks for your help.  It is much appreciated.  Unfortunately I haven't been able to get this to work.  In the section where you are linking the block to the visibility state it looks like there may be a mix up with the 3rd block since the name is mentioned.  I did try a modified version, following the syntax of the previous items (see below), but this did not work either.  I don't receive any errors loading or running the lisp.

 

Thanks,

Brad

 

(cond ((= name "block-1")
                   (setq vis "state-1")
                  )
                  ((= name "block-2")
                   (setq vis "state-2")
                  )
                  ((= name "block-3")
                   (setq vis "state-3")
                  )
            )

 

0 Likes
Message 4 of 10

hmsilva
Mentor
Mentor

@Anonymous wrote:

Henrique, first of all thanks for your help.  It is much appreciated.  Unfortunately I haven't been able to get this to work.  In the section where you are linking the block to the visibility state it looks like there may be a mix up with the 3rd block since the name is mentioned.  I did try a modified version, following the syntax of the previous items (see below), but this did not work either.  I don't receive any errors loading or running the lisp.

 

Thanks,

Brad

 

(cond ((= name "block-1")
                   (setq vis "state-1")
                  )
                  ((= name "block-2")
                   (setq vis "state-2")
                  )
                  ((= name "block-3")
                   (setq vis "state-3")
                  )
            )

 


Hi Brad,

from my code:

; selected 'blocks', only block-1. block-2 and block-3
(cond (; test if name is block-1
       (= name "block-1")
       ; if true
       ; set vis to state-1
       (setq vis "state-1")
      )
      (; if previous test fail,
       ; test if name is block-2
       (= name "block-2")
       ; if true
       ; set vis to state-1
       (setq vis "state-2")
      )
      (; if both previous tests fail
       ; the 'block' name must be block-3
       ; the conditional function is just a T
       ; will return 'true'
       T ; (it could be written without this test,
       ; but I like to write it this way...
       ; set vis to state-1
       (setq vis "state-3")
      )
)

 

If possible, post a sample dwg, with the blocks to to replace, and the DynBlock to replace the static ones...

 

Hope this helps,
Henrique

EESignature

0 Likes
Message 5 of 10

bsanada
Advocate
Advocate

Here is the file.

 

Thanks, Brad

0 Likes
Message 6 of 10

hmsilva
Mentor
Mentor

Brad,

your dynamic block, dont have the same insertion point as the blocks to be replaced...

Just a starting point, i did commented the 'vla-erase' just for visual debugging...

 

(vl-load-com)
(defun c:demo (/ ss blk obj)
   (if (and
          (setq ss (ssget "_X" (list '(0 . "INSERT") '(2 . "IIFM,SDFM,CFFM,PLFM") (cons 410 (getvar 'CTAB)))))
          (setq blk "GENERAL INSTRUMENT")
       )
      (repeat (setq i (sslength ss))
         (setq obj  (vlax-ename->vla-object (ssname ss (setq i (1- i))))
               name (vla-get-effectivename obj)
         )
         (cond ((= name "IIFM")
                (setq vis "INDEPENDENT INSTRUMENTS")
               )
               ((= name "SDFM")
                (setq vis "SHARED DISPLAY/SHARED CONTROL OF DISTRIBUTED CONTROL SYSTEM")
               )
               ((= name "CFFM")
                (setq vis "COMPUTER FUNCTION")
               )
               (T
                (setq vis "PROGRAMMABLE LOGIC CONTROL")
               )
         )
         (command "-insert" blk "_S" 1 "_R" 0 "_NONE" (vlax-get obj 'InsertionPoint))
         (setq lasthnd (entlast)
               lastobj (vlax-ename->vla-object lasthnd)
         )
         (if (and (vlax-property-available-p lastobj 'IsDynamicBlock)
                  (eq (vla-get-IsDynamicBlock lastobj) :vlax-true)
             )
            (progn
               (foreach p (vlax-safearray->list
                             (vlax-variant-value (vla-getdynamicblockproperties lastobj))
                          )
                  (if (and (eq (vlax-get p 'PropertyName) "Visibility1")
                           (vl-position vis (vlax-get p 'AllowedValues))
                      )
                     (vlax-put-property p "Value" vis)
                  )
               )
               ;(vla-delete obj)
            )
         )
      )
   )
   (princ)
)



 

Hope this helps,
Henrique

EESignature

0 Likes
Message 7 of 10

bsanada
Advocate
Advocate

Henrique,

 

I was able to get your routine to work, great job and thanks for your effort!  Unfortunately it looks like this routine places the new block at the insertion of the existing block rather than an actual block replacement.  The issue with this method is the attribute values won't carry over to the new block.  I have currently made provisions for each of the different types to be placed on a specific layer that can be isolated to aid in changing the visibility state after doing a blockreplace.  This will be a workable solution in our update process.  If your tired of my little project feel free to move on.  If you would like to continue helping me out perhaps a routine that would select all the "block-1" blocks on layer "layer-1" and change the visibility state to "state-1" would do the trick.

 

In either case, much thanks for your help!

Brad

0 Likes
Message 8 of 10

hmsilva
Mentor
Mentor
Accepted solution

@Anonymous wrote:

Henrique,

 

I was able to get your routine to work, great job and thanks for your effort!  Unfortunately it looks like this routine places the new block at the insertion of the existing block rather than an actual block replacement.  The issue with this method is the attribute values won't carry over to the new block.  I have currently made provisions for each of the different types to be placed on a specific layer that can be isolated to aid in changing the visibility state after doing a blockreplace.  This will be a workable solution in our update process.  If your tired of my little project feel free to move on.  If you would like to continue helping me out perhaps a routine that would select all the "block-1" blocks on layer "layer-1" and change the visibility state to "state-1" would do the trick.

 

In either case, much thanks for your help!

Brad


Brad,

even using blockreplace, will have to replace one block, for one other using the same insertion point.

Try the revised code, with the attached dwg, with the 'GENERAL INSTRUMENT' redefined by me...

 

(vl-load-com)
(defun c:demo (/ attlst attlst1 attlst2 b blk i lasthnd lastobj name obj ss vis)
   (or adoc (setq adoc (vla-get-activedocument (vlax-get-acad-object))))
   (vla-startundomark adoc)
   (if (and (setq ss (ssget "_X" (list '(0 . "INSERT") '(2 . "IIFM,SDFM,CFFM,PLFM") (cons 410 (getvar 'CTAB)))))
            (setq blk "GENERAL INSTRUMENT")
       )
      (repeat (setq i (sslength ss))
         (setq obj     (vlax-ename->vla-object (ssname ss (setq i (1- i))))
               name    (vla-get-effectivename obj)
               attlst  (vlax-invoke obj 'GetAttributes)
               attlst1 nil
         )
         (foreach a attlst
            (setq attlst1 (cons (cons (vla-get-tagstring a) (vla-get-textstring a)) attlst1))
         )
         (cond ((= name "IIFM")
                (setq vis "INDEPENDENT INSTRUMENTS")
               )
               ((= name "SDFM")
                (setq vis "SHARED DISPLAY/SHARED CONTROL OF DISTRIBUTED CONTROL SYSTEM")
               )
               ((= name "CFFM")
                (setq vis "COMPUTER FUNCTION")
               )
               (T
                (setq vis "PROGRAMMABLE LOGIC CONTROL")
               )
         )
         (command "-insert" blk "_S" 1 "_R" 0 "_NONE" (vlax-get obj 'InsertionPoint))
         (setq lasthnd (entlast)
               lastobj (vlax-ename->vla-object lasthnd)
               attlst2 (vlax-invoke lastobj 'GetAttributes)
         )
         (foreach a attlst2
            (if (setq b (assoc (vla-get-tagstring a) attlst1))
               (vla-put-textstring a (cdr b))
            )
         )
         (if (and (vlax-property-available-p lastobj 'IsDynamicBlock)
                  (eq (vla-get-IsDynamicBlock lastobj) :vlax-true)
             )
            (progn
               (foreach p (vlax-safearray->list
                             (vlax-variant-value (vla-getdynamicblockproperties lastobj))
                          )
                  (if (and (eq (vlax-get p 'PropertyName) "Visibility1")
                           (vl-position vis (vlax-get p 'AllowedValues))
                      )
                     (vlax-put-property p "Value" vis)
                  )
               )
               ;(vla-delete obj)
            )
         )
      )
   )
   (vla-endundomark adoc)
   (princ)
)

 

As I said in an earlier post, the vla-delete is commented, just for visual debugging, to erase the original 'INSERT', just remove the ";".

 

Hope this helps,
Henrique

EESignature

0 Likes
Message 9 of 10

bsanada
Advocate
Advocate
Works great, thanks Henrique!
0 Likes
Message 10 of 10

hmsilva
Mentor
Mentor

@Anonymous wrote:
Works great, thanks Henrique!

You're welcome, Brad!
Glad I could help

Henrique

EESignature

0 Likes