DesmetMartin Posted October 26, 2016 Posted October 26, 2016 Hello all, I should get the following code changed so that you can select the blocks you want to 'undynamic" first. Can somebody help me? (defun c:UnDynamic ( / _get_item _right _make_key _dynamic->static_block _get_locked _get_dynamic_inserts _main ) (defun _get_item ( collection key / item ) (vl-catch-all-apply '(lambda ( ) (setq item (vla-item collection key))) ) item ) (defun _right ( str n / len ) (if (< n (setq len (strlen str))) (substr str (1+ (- len n))) str ) ) (defun _make_key ( collection prefix len / key ) ( (lambda ( i pad ) (while (_get_item collection (setq key (strcat prefix (_right (strcat pad (itoa (setq i (1+ i)))) len ) ) ) ) ) key ) 0 ( (lambda ( pad ) (while (< (strlen pad) len) (setq pad (strcat "0" pad)) ) pad ) "" ) ) ) (defun _dynamic->static_block ( blocks insert len ) (vla-ConvertToStaticBlock insert (_make_key blocks (strcat (vla-get-EffectiveName insert) "_00") len) ) ) (defun _get_locked ( layers / locked ) (vlax-for layer layers (if (eq :vlax-true (vla-get-lock layer)) (setq locked (cons layer locked)) ) ) locked ) (defun _get_dynamic_inserts ( blocks / inserts ) (vlax-for block blocks (vlax-for object block (if (eq "AcDbBlockReference" (vla-get-objectname object)) (if (eq :vlax-true (vla-get-isdynamicblock object)) (setq inserts (cons object inserts)) ) ) ) ) inserts ) (defun _main ( document / blocks inserts locked len ) (if (setq inserts (_get_dynamic_inserts (setq blocks (vla-get-blocks document)) ) ) (progn (foreach layer (setq locked (_get_locked (vla-get-layers document))) (vla-put-lock layer :vlax-false) ) (setq len (strlen (itoa (length inserts)))) (foreach insert inserts (_dynamic->static_block blocks insert len) ) (foreach layer locked (vla-put-lock layer :vlax-true) ) ) ) (princ) ) (_main (vla-get-activedocument (vlax-get-acad-object))) ) Credits to TP from theswamp.org. Thanks, Martin. Quote
Grrr Posted October 26, 2016 Posted October 26, 2016 Not so pretty as his, but gets the job done: (defun C:test ( / ErrCatcher SS i o ) (defun ErrCatcher ( func varLst / rtn ) (if (not (vl-catch-all-error-p (setq rtn (vl-catch-all-apply func varLst)))) rtn)) (prompt "\nSelect blocks to convert them into static ones:" ) (if (setq SS (ssget "_:L" (list (cons 0 "INSERT")))) (repeat (setq i (sslength SS)) (if (eq :vlax-true (vla-get-IsDynamicBlock (setq o (vlax-ename->vla-object (ssname SS (setq i (1- i))))))) (ErrCatcher 'vla-ConvertToStaticBlock (list o (vla-get-EffectiveName o))) ) ) ) (princ) );| defun |; (or (vlax-get-acad-object) (vl-load-com)) (princ) Quote
DesmetMartin Posted October 26, 2016 Author Posted October 26, 2016 Thanks, it's this kind of thing I want to do. The only problem is that the name get's changed and you can't edit you static block anymore. Quote
DesmetMartin Posted October 28, 2016 Author Posted October 28, 2016 So what I'm trying to say is that the code in the 1st post should be used. Only thing that should be added in the code is that you select the items you want to undynamic instead of all the blocks. Thanks, Martin Quote
Roy_043 Posted October 29, 2016 Posted October 29, 2016 @Grrr: IMO this: (or (vlax-get-acad-object) (vl-load-com)) Should be: (or vlax-get-acad-object (vl-load-com)) Quote
Grrr Posted October 29, 2016 Posted October 29, 2016 @Grrr:IMO this: (or (vlax-get-acad-object) (vl-load-com)) Should be: (or vlax-get-acad-object (vl-load-com)) Hi Roy, Yes it seems that it makes more sence: _$ vlax-get-acad-object #<SUBR @000000a99c5a6d68 vlax-get-acad-object> _$ (vlax-get-acad-object) #<VLA-OBJECT IAcadApplication 00007ff604c59110> _$ Thanks! Quote
Roy_043 Posted October 29, 2016 Posted October 29, 2016 It is not about 'more sense'. I expect that (vlax-get-acad-object) will fail if the VL extensions have not been loaded. I am using the word 'expect' because I am using BricsCAD where (vl-load-com) is a dummy function and VL functions are available by default. Quote
Grrr Posted October 29, 2016 Posted October 29, 2016 Yes, I mean that I haven't noticed that instead of checking for such function, I'm instead running it with the possibility of triggering an error, such as: _$ (defun C:test () (strcat 1)) C:TEST _$ C:test #<USUBR @000000a99c508570 C:TEST> _$ (C:test) _$ (C:test) Error: bad argument type: stringp 1 _1$ You have sharp eye. Quote
Roy_043 Posted October 30, 2016 Posted October 30, 2016 Testing the (vla-ConvertToStaticBlock) function I have noticed something strange (note: as previously mentioned I use BricsCAD). My test: 1. Insert the same dynamic block twice. 2. Make identical changes to one or more dynamic properties for each insert. 3. The inserts now look the same but reference different anonymous definitions. 4. Copy one of the inserts. 5. The copy references the same anonymous definition as its original. 6. Only convert the copy to a static block. 7. Result: The original of the copy has also become a static block (probably due to what was mentioned under #5). If AutoCAD has the same behavior, converting only selected inserts to static blocks would require a more complex solution than the code posted in this thread. Quote
Lee Mac Posted October 30, 2016 Posted October 30, 2016 1. Insert the same dynamic block twice. 2. Make identical changes to one or more dynamic properties for each insert. 3. The inserts now look the same but reference different anonymous definitions. This differs in AutoCAD: inserting two references of the same dynamic block and modifying their dynamic parameters to use the same values results in the two blocks referencing the same anonymous definition. 4. Copy one of the inserts. 5. The copy references the same anonymous definition as its original. AutoCAD has the same behaviour (as to be expected, based on the above observation). 6. Only convert the copy to a static block.7. Result: The original of the copy has also become a static block (probably due to what was mentioned under #5). This is not the case in AutoCAD: converting one of the dynamic block references has no effect on the others. Quote
Roy_043 Posted October 31, 2016 Posted October 31, 2016 @Lee: Thanks for your comments. I'll send a Support Request to the Bricsys team. Quote
Grrr Posted October 31, 2016 Posted October 31, 2016 I've followed the steps Roy mentioned on my Acad 2015, and can comfirm this: This is not the case in AutoCAD: converting one of the dynamic block references has no effect on the others. Seems that it adds new block definition, under the provided name: (vla-ConvertToStaticBlock o "ABC") But, when I try to convert other block reference under the same / existing block definition name, I get: _$ (vla-ConvertToStaticBlock o "ABC") Error: Automation Error. Duplicate key _1$ But/And It creates an annonymous block definition anyway: _$ (vla-get-EffectiveName (vlax-ename->vla-object (car (entsel)))) "*U117" _$ Note that the "Name" property row in the quick properties dialog, always references to the block's "effective name / definition name". So thats why my previously posted code forces the creation of N annonymous block definitions: (ErrCatcher 'vla-ConvertToStaticBlock (list o (vla-get-EffectiveName o))) Since this always triggers an error Quote
Lee Mac Posted October 31, 2016 Posted October 31, 2016 But, when I try to convert other block reference under the same / existing block definition name, I get: _$ (vla-ConvertToStaticBlock o "ABC") Error: Automation Error. Duplicate key _1$ Of course: the block name argument for the ActiveX converttostaticblock method cannot correspond to an existing block, otherwise you will receive a duplicate key error - this is why the original code included the '_make_key' function. Quote
DesmetMartin Posted November 2, 2016 Author Posted November 2, 2016 First of all, thanks for all the help so far! I would like to think together with you guys, but since I can't program, it's though Let me know if you find a solution please! Thanks! - Martin Quote
Grrr Posted November 2, 2016 Posted November 2, 2016 First of all, thanks for all the help so far!I would like to think together with you guys, but since I can't program, it's though Let me know if you find a solution please! Thanks! - Martin Try this: (defun C:test ( / ErrCatcher BlksColl SS i o cnt flg nm ) ; (ErrCatcher 'vla-item (list (vla-get-Blocks (vla-get-ActiveDocument (vlax-get-acad-object))) "BlockThatDoesNotExist")) -> nil (defun ErrCatcher ( func varLst / rtn ) (if (not (vl-catch-all-error-p (setq rtn (vl-catch-all-apply func varLst)))) rtn)) (setq BlksColl (vla-get-Blocks (vla-get-ActiveDocument (vlax-get-acad-object)))) (prompt "\nSelect blocks to convert them into static ones:" ) (if (setq SS (ssget "_:L" (list (cons 0 "INSERT")))) (repeat (setq i (sslength SS)) (if (eq :vlax-true (vla-get-IsDynamicBlock (setq o (vlax-ename->vla-object (ssname SS (setq i (1- i))))))) (progn (setq cnt 0) (setq flg 'T) (while flg (if (not (ErrCatcher 'vla-item (list BlksColl (setq nm (strcat (vla-get-EffectiveName o) "_" (itoa (setq cnt (1+ cnt)))))))) (progn (vla-ConvertToStaticBlock o nm) (setq flg nil)) ); if ); while ); progn ); if ); repeat ); if (princ) );| defun |; (or vlax-get-acad-object (vl-load-com)) (princ) Note that the original dynamic blocks are not purged. Quote
DesmetMartin Posted November 3, 2016 Author Posted November 3, 2016 Try this: (defun C:test ( / ErrCatcher BlksColl SS i o cnt flg nm ) ; (ErrCatcher 'vla-item (list (vla-get-Blocks (vla-get-ActiveDocument (vlax-get-acad-object))) "BlockThatDoesNotExist")) -> nil (defun ErrCatcher ( func varLst / rtn ) (if (not (vl-catch-all-error-p (setq rtn (vl-catch-all-apply func varLst)))) rtn)) (setq BlksColl (vla-get-Blocks (vla-get-ActiveDocument (vlax-get-acad-object)))) (prompt "\nSelect blocks to convert them into static ones:" ) (if (setq SS (ssget "_:L" (list (cons 0 "INSERT")))) (repeat (setq i (sslength SS)) (if (eq :vlax-true (vla-get-IsDynamicBlock (setq o (vlax-ename->vla-object (ssname SS (setq i (1- i))))))) (progn (setq cnt 0) (setq flg 'T) (while flg (if (not (ErrCatcher 'vla-item (list BlksColl (setq nm (strcat (vla-get-EffectiveName o) "_" (itoa (setq cnt (1+ cnt)))))))) (progn (vla-ConvertToStaticBlock o nm) (setq flg nil)) ); if ); while ); progn ); if ); repeat ); if (princ) );| defun |; (or vlax-get-acad-object (vl-load-com)) (princ) Note that the original dynamic blocks are not purged. Super! This is what I was looking for! Thank you so much! -Martin Quote
RGS Posted April 23 Posted April 23 @Grrr, it's possible to erase the hiden objets!? When I edit the static block, it keeps all the existing objects from the dynamic block. But not visible. Its possible to remove changing your lisp!? Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.