Explode Dynamic Block by effective name

Explode Dynamic Block by effective name

Anonymous
Not applicable
2,761 Views
23 Replies
Message 1 of 24

Explode Dynamic Block by effective name

Anonymous
Not applicable

I have recently received  great help from this forum and am back with hopefully a more simple request. I have searched and could not find anything that I could get working for my needs. I'm working with dynamic blocks. It seems that exploding them via a lisp is slightly tricky due to their potential anonymous names. I have some of LM's code for working with dynamic blocks and would like to add to it. Code is below. When I add my code and run it, there doesn't appear to be any changes.

.....
   (repeat (setq idx (sslength sel))
      (if (setq idx (1- idx)
		obj (vlax-ename->vla-object (ssname sel idx))
		vis (cadr (assoc (strcase (LM:blockname obj)) lst))
		)
	(LM:SetVisibilityState obj vis))))
  	(RG:XDYNBLK OBJ)	;here is where i added my call		
  (princ)
  )
(defun RG:XDYNBLK (bname)
	(vla-get-effectivename bname)   ;i've read about setting filters for the name and can't find a good place to learn about it either.
  	(command "_explode" bname)
)

 

Thanks for your help.

0 Likes
2,762 Views
23 Replies
Replies (23)
Message 2 of 24

dlanorh
Advisor
Advisor

@Anonymous wrote:

I have recently received  great help from this forum and am back with hopefully a more simple request. I have searched and could not find anything that I could get working for my needs. I'm working with dynamic blocks. It seems that exploding them via a lisp is slightly tricky due to their potential anonymous names. I have some of LM's code for working with dynamic blocks and would like to add to it. Code is below. When I add my code and run it, there doesn't appear to be any changes.

 

.....
   (repeat (setq idx (sslength sel))
      (if (setq idx (1- idx)
		obj (vlax-ename->vla-object (ssname sel idx))
		vis (cadr (assoc (strcase (LM:blockname obj)) lst))
		)
	(LM:SetVisibilityState obj vis))))
  	(RG:XDYNBLK OBJ)	;here is where i added my call		
  (princ)
  )
(defun RG:XDYNBLK (bname)
	(vla-get-effectivename bname)   ;i've read about setting filters for the name and can't find a good place to learn about it either.
  	(command "_explode" bname)
)

 

 

Thanks for your help.


Your defun doesn't do anything, which is why there is no change. Dynamic blocks, due to their nature, become anonymous once a parameter has been altered. The effective name links back to the original defined block name. There is only ever a single instance of an anonymous block, as parameters can be changed. To explode any said block you need to know the entity name (not the blocks effective or anonymous name) it currently has in the database; or the block as an object.  

 

1)  you're are passing in a object

 

2) you're obtaining the blocks effective name but not storing it. You can't use the name name to explode it anyway, and bname is still an object

 

3) the explode command only works with entity names (which are different from a blocks effective name) and NOT objects.

 

If you provide a better eplanation of what you are trying to achieve, I'm sure someone can help.

 

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

0 Likes
Message 3 of 24

CodeDing
Advisor
Advisor

@Anonymous ,

 

Are you trying to explode every block you run across in your loop?

You can just use the Explode Method.

---EDIT---

Might have to rearrange some parenthesis...

.....
   (repeat (setq idx (sslength sel))
      (if (setq idx (1- idx)
		obj (vlax-ename->vla-object (ssname sel idx))
		vis (cadr (assoc (strcase (LM:blockname obj)) lst))
		)
	(LM:SetVisibilityState obj vis)
);if (vla-explode obj) (RG:XDYNBLK OBJ) ;here is where i added my call
);repeat
); <-- ? something ? (princ) ) .....

Best,

~DD

0 Likes
Message 4 of 24

Anonymous
Not applicable

I am only interested in exploding a blocks of a certain name at this point. The dynamic block name is BOM.

0 Likes
Message 5 of 24

CodeDing
Advisor
Advisor

Like this:

(defun RG:XDYNBLK (obj)
  (if (eq "BOM" (strcase (vla-get-effectivename obj)))
    (progn (vla-explode obj) (vla-delete obj))
  );if
);defun

 

...seems a bit simple to have in its own function. Perhaps you can consider adding it at an appropriate place in your original routine, wherever that may be. 

 

---EDIT---

Per @dlanorh 's comment below.. I had no idea that vla-explode did not erase original object. Good to know Lol. I have also updated my code above to reflect this new information.

0 Likes
Message 6 of 24

dlanorh
Advisor
Advisor

@Anonymous wrote:

I am only interested in exploding a blocks of a certain name at this point. The dynamic block name is BOM.


Change your function to this

 

(defun RG:XDYNBLK (bname)
  (cond ( (= (vla-get-effectivename bname) "BOM")  ;i've read about setting filters for the name and can't find a good place to learn about it either.
          (vla-explode bname)
          (vla-delete bname)
        )
  )
)

 

This checks if the effective name of the block is "BOM". If it is, it explodes it and deletes the original block (vla-explode retains the original block).

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

Message 7 of 24

Anonymous
Not applicable

I was also unaware the explode did not delete. But I added your code and it does not delete explode the block. If I type the following in the command line (command "_explode" "BOM") it asks me to select a block and then it will explode it. Does that help troubleshoot what's happening here?

.....
    (repeat (setq idx (sslength sel))			;sslength returns how many arguments in a selection set
      (if (setq idx (1- idx)
		obj (vlax-ename->vla-object (ssname sel idx))	;ssname rerutns the object (entity) name of the indexed element of a selection set ; vlax-ename->vla-object transforms an entity to a vla-object
		vis (cadr (assoc (strcase (LM:blockname obj)) lst))
		)
	(LM:SetVisibilityState obj vis))))
  	(RG:XDYNBLK OBJ)	
		
  (princ)
  )

(defun RG:XDYNBLK (obj)
  (if (eq "BOM" (strcase (vla-get-effectivename obj)))
    (progn (vla-explode obj) (vla-delete obj))
  );if
);defun

 latest piece of code added as well 

0 Likes
Message 8 of 24

CodeDing
Advisor
Advisor

@Anonymous wrote:

If I type the following in the command line (command "_explode" "BOM") it asks me to select a block and then it will explode it. Does that help troubleshoot what's happening here?


No, if you are typing, (command "_explode" "BOM"), into the command line.. then that does not help troubleshoot.

 

That process is the same as this >> Run EXPLODE command >> (pickbox will appear) >> type "BOM" and hit enter >> ?? nothing happens.

 

Nothing is happening because the string "BOM" is irrelevant to the EXPLODE command. we must pass entities to the explode command, not strings (there are exceptions, we can use a string like "p" for previous, etc... but that does not apply to your current scenario).

 

 

Have you tried running the lisp with updated code?

What does thee command history say when you load the lisp?

What does it say when you run the lisp?

 

It does not appear that the function I (or dlanorh) provided would cause an error, so there must be something wrong elsewhere in your code. It is hard without full context.

 

Best,

~DD

Message 9 of 24

CodeDing
Advisor
Advisor

@Anonymous ,

 

Actually, this is probably a big factor..

.....
    (repeat (setq idx (sslength sel)) ;sslength returns how many arguments in a selection set
      (if (setq idx (1- idx)
                obj (vlax-ename->vla-object (ssname sel idx)) ;ssname returns the object (entity) name of the indexed element of a selection set ; vlax-ename->vla-object transforms an entity to a vla-object
                vis (cadr (assoc (strcase (LM:blockname obj)) lst))
          );setq
        (LM:SetVisibilityState obj vis)
);if
);repeat
); <-- ? something ? (RG:XDYNBLK OBJ) ;<-- when is this function being called? (princ) );defun (probably)

 

When is the function being called? because based on the small section we can see, it is outside of the repeat loop, and also outside of another function after that.. If the 'OBJ' variable does not remain updated, then the last time it was used as a VLA-object is the only item that may get exploded...

 

We must be mindful of when we are calling our function and what we are passing to it.

 

Best,

~DD

 

0 Likes
Message 10 of 24

Anonymous
Not applicable

Fair enough. Here is the full section of code.

(defun c:UDB ( / sel idx obj vis lst bname)  
  (if (and (setq sel (ssget "_X" (append '((000 . "INSERT")
					   (-04 . "<OR")
					   (002 . "`*U*"))
					 (mapcar '(lambda ( x ) (cons 2 (car x))) lst)
					 '((-004 . "OR>")
					   (410 . "Model")))))
	   (setq lst (:ReadRangeFromXLS "C:\\test\\workbook.xls" "sheet1" "A2:B14"))
	   )
    (repeat (setq idx (sslength sel))			;sslength returns how many arguments in a selection set
      (if (setq idx (1- idx)
		obj (vlax-ename->vla-object (ssname sel idx))	;ssname rerutns the object (entity) name of the indexed element of a selection set ; vlax-ename->vla-object transforms an entity to a vla-object
		vis (cadr (assoc (strcase (LM:blockname obj)) lst))
		)
	(LM:SetVisibilityState obj vis))))
  	(RG:XDYNBLK OBJ)	
		
  (princ)
  )

(defun RG:XDYNBLK (obj)
  (if (eq "BOM" (strcase (vla-get-effectivename obj)))
    (progn (vla-explode obj) (vla-delete obj))
  );if
);defun

This function reads in visibility states from excel and selects dynamic blocks based on it (along with some other code). All together this code is working fine. I'm just trying to intercept any dynamic block named "BOM" after the lisp identifies the blocks and begins processing their visibility states based on the excel list.

0 Likes
Message 11 of 24

CodeDing
Advisor
Advisor

Last question, are you trying to explode ALL blocks with name "BOM"? Or only ones with "BOM" that come through your code?

0 Likes
Message 12 of 24

Anonymous
Not applicable

Only the ones that come thru the code, but technically if mutliple exist on a drawing they will all end up coming thru code. I'd prefer it exploding only if it comes thru the code.

0 Likes
Message 13 of 24

CodeDing
Advisor
Advisor

Try this please. We are already capturing the block name evidently in our original code, so it made sense to just include the explode in our current workflow.

(defun c:UDB ( / sel idx obj vis lst bname)  
  (if (and (setq lst (:ReadRangeFromXLS "C:\\test\\workbook.xls" "sheet1" "A2:B14"))
           (setq sel (ssget "_X" (append '((0 . "INSERT") (-4 . "<OR") (2 . "`*U*"))
					 (mapcar '(lambda ( x ) (cons 2 (car x))) lst)
					 '((-4 . "OR>") (410 . "Model")))))
      );and
    (repeat (setq idx (sslength sel))
      (if (setq idx (1- idx)
                obj (vlax-ename->vla-object (ssname sel idx))
                bname (strcase (LM:blockname obj))
                vis (cadr (assoc bname lst))
          );setq
        (LM:SetVisibilityState obj vis)
      );if
      (if (eq "BOM" bname)
        (progn (vla-explode obj) (vla-delete obj))
      );if
    );repeat
  );if
  (princ)
);defun

Best,

~DD

Message 14 of 24

dlanorh
Advisor
Advisor

**Removed*

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

Message 15 of 24

Anonymous
Not applicable

Sorry I did not get back to you. I tested this and it works great. It did bring to light one issue i'm having. The BOM block is a nested block and i'd like to do the exploding of it prior to performing the work on the other blocks. is it possible to make that happen first?

0 Likes
Message 16 of 24

CodeDing
Advisor
Advisor

@Anonymous ,

 

I do not understand what your new issue is. Can you elaborate more?

0 Likes
Message 17 of 24

Anonymous
Not applicable

Absolutely! Ok so the lisp runs on each drawing. Each drawing has dynamic blocks. One of those dynamic blocks could be named "BOM". If "BOM" does exist on a drawing, it MUST be processed and exploded first. What does processed me you may ask. Well, the excel file is used to build a list using the lisp. This list has 2 pieces of information. The first piece is a dynamic block name. The second piece is the visibility state that each dynamic block should have selected. Since the "BOM" block may contain nested blocks, it should be processed first then exploded so that the nested blocks will be processed afterwards. I'm using the word processed to mean, select the correspondingly visibility state from the list obtained from excel. If we do not look for, process, and explode "BOM" first, then the nested blocks are not processed.

 

Everything works right now but I need to process BOM first if it exists on the drawing and then explode it. 

Does this clear it up? 

0 Likes
Message 18 of 24

Anonymous
Not applicable

Did my last reply help?

0 Likes
Message 19 of 24

CodeDing
Advisor
Advisor

@Anonymous ,

 

Sorry, I have been away from the forum for a while.

 

Yes, your last explanation helped me further understand your process, but it also makes it clear to me that it will be a much more involved process.. Exploding items, then retrieving the items that have been exploded is another level of hefty work to include in the program.

 

While, I could probably create the code to accomplish this for you, it will be too time consuming for me to want to perform since it is a greater scope change than originally expected.

 

If you are to continue with this lisp on your own, you will probably need to look into the (vla-explode ...) function. This will be returning objects from an exploded object. You can come back to this thread and ask for help or guidance on specific items, but I will not be taking the effort to write the full code. Sorry.

 

Hope that helps. Best,

~DD

0 Likes
Message 20 of 24

Anonymous
Not applicable

I'm not trying to retrieve anything from exploded blocks. I am trying to explode a certain block first. Then perform my other tasks which already are working.

0 Likes