Author Topic: Replace block, also when to be replaced block is nested  (Read 10207 times)

0 Members and 1 Guest are viewing this topic.

Woabow

  • Newt
  • Posts: 56
Replace block, also when to be replaced block is nested
« on: October 09, 2013, 11:35:55 AM »
There are several methods of replacing a block:

BLOCKREPLACE: does not replace blocks when they are inside another block
-INSERT old=new: works on nested blocks, but does end up with the old blockname. Renaming globally is not possible because there could have been old blocks in the drawing that should not be renamed.
LISP PROGRAMS: As far as I know all lisp programs work with a selection and will not replace nested blocks.

Any suggestions?




kruuger

  • Swamp Rat
  • Posts: 625
Re: Replace block, also when to be replaced block is nested
« Reply #1 on: October 09, 2013, 01:38:22 PM »
There are several methods of replacing a block:

BLOCKREPLACE: does not replace blocks when they are inside another block
-INSERT old=new: works on nested blocks, but does end up with the old blockname. Renaming globally is not possible because there could have been old blocks in the drawing that should not be renamed.
LISP PROGRAMS: As far as I know all lisp programs work with a selection and will not replace nested blocks.

Any suggestions?
maybe you can use design center CTRL+2
kruuger

Woabow

  • Newt
  • Posts: 56
Re: Replace block, also when to be replaced block is nested
« Reply #2 on: October 10, 2013, 02:14:19 AM »
Ok, thanks. But Bricscad does not have Designcenter. Maybe it explains why I can't find a lisp.


roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: Replace block, also when to be replaced block is nested
« Reply #3 on: October 10, 2013, 04:16:45 AM »
-INSERT old=new: works on nested blocks, but does end up with the old blockname. Renaming globally is not possible because there could have been old blocks in the drawing that should not be renamed.
Woabow, globally changing all block references from 'old' to 'new' would be equivalent to this. Can you clarify what you want to do?

Woabow

  • Newt
  • Posts: 56
Re: Replace block, also when to be replaced block is nested
« Reply #4 on: October 10, 2013, 07:06:51 AM »
The goal is to replace a block with another block, say "new"replaces "old". But it should also replace all blocks with the name "old" inside other blocks. And in the end all replaced blocks should have the name "new".

With -INSERT old=new all replaced blocks are named "old", not "new".

I cannot rename "old" to "new" because I might rename blocks with the name "new" which existed before the insert. I tried to use a temporarily name before the insert ("old" > "temp"), but this doesn't work also because afterwards I want to rename "temp" to "new" which is not allowed when "new"already existed in the drawing.


Bhull1985

  • Guest
Re: Replace block, also when to be replaced block is nested
« Reply #5 on: October 10, 2013, 08:11:27 AM »
Please post a sample drawing with examples of the blocks you are dealing with.
I deal with blocks daily but am having a hard time understanding exactly what you are requiring.

Woabow

  • Newt
  • Posts: 56
Re: Replace block, also when to be replaced block is nested
« Reply #6 on: October 10, 2013, 09:11:09 AM »
In attached drawing replace1.dwg are OLD blocks and NEW blocks. There is also a block BLOCKWITHBLOCKS which contains OLD (and NEW).

I just want to replace all OLD blocks with NEW, like in replace2.dwg.

Not by hand, because in real life the OLD blocks are nested in many other blocks, on different levels.


ronjonp

  • Needs a day job
  • Posts: 7526
Re: Replace block, also when to be replaced block is nested
« Reply #7 on: October 10, 2013, 09:50:25 AM »
I think this should do what you want. The new block definition has to exist in the drawing though.
Code: [Select]
(defun _updateblocks (old new)
  (if (tblobjname "block" new)
    (vlax-for b (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object)))
      (vlax-for bb b
(if (and (= (vla-get-objectname bb) "AcDbBlockReference")
(wcmatch (strcase (vla-get-name bb)) (strcase old))
(print (vla-get-name bb))
    )
  (vl-catch-all-apply 'vla-put-name (list bb new))
)
      )
    )
  )
)
(_updateblocks "old" "new")

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: Replace block, also when to be replaced block is nested
« Reply #8 on: October 10, 2013, 09:52:05 AM »
Try this:
Code - Auto/Visual Lisp: [Select]
  1. (defun KGA_Conv_Collection_To_List (coll / ret)
  2.     (vlax-for a coll
  3.       (setq ret (cons a ret))
  4.     )
  5.   )
  6. )
  7.  
  8. (defun BKG_ReplaceBlock_InputName (message / input)
  9.   (setq input (getstring T message))
  10.   (if (= input "")
  11.     (if (setq input (car (entsel)))
  12.       (cdr (assoc 2 (entget input)))
  13.     )
  14.     input
  15.   )
  16. )
  17.  
  18. (defun c:BKG_ReplaceBlock ( / actDocObject blockFile blockNameNew blockNameOld count)
  19.   (if (= (logand (getvar 'undoctl) 8) 8)
  20.     (vla-endundomark actDocObject)
  21.   )
  22.   (vla-startundomark actDocObject)
  23.   (if
  24.     (and
  25.       (setq blockNameOld
  26.         (BKG_ReplaceBlock_InputName "\nBlock to replace (Enter to select): ")
  27.       )
  28.       (tblobjname "block" blockNameOld)
  29.       (setq blockNameNew
  30.         (BKG_ReplaceBlock_InputName
  31.           (strcat "\nReplace '" blockNameOld "' block with (Enter to select): ")
  32.         )
  33.       )
  34.       (or
  35.         (tblobjname "block" blockNameNew)
  36.         (and
  37.           (snvalid blockNameNew)
  38.           (setq blockFile (getfiled "Select a drawing" " " "dwg;dxf" 0))
  39.           (setvar 'cmdecho 0)
  40.           (not (command "_.insert" (strcat blockNameNew "=" blockFile) nil))
  41.           (setvar 'cmdecho 1)
  42.           (tblobjname "block" blockNameNew)
  43.         )
  44.       )
  45.     )
  46.     (progn
  47.       (setq blockNameOld (strcase blockNameOld))
  48.       (setq count
  49.         (length
  50.           (vl-remove
  51.             nil
  52.             (apply
  53.               'append
  54.               (mapcar
  55.                 '(lambda (blockDefObject)
  56.                   (mapcar
  57.                     '(lambda (object)
  58.                       (if
  59.                         (and
  60.                           (= (vla-get-objectname object) "AcDbBlockReference")
  61.                           (= (strcase (vla-get-name object)) blockNameOld)
  62.                         )
  63.                         (progn
  64.                           (vla-put-name object blockNameNew)
  65.                           T
  66.                         )
  67.                       )
  68.                     )
  69.                     (KGA_Conv_Collection_To_List blockDefObject)
  70.                   )
  71.                 )
  72.                 (KGA_Conv_Collection_To_List (vla-get-blocks actDocObject))
  73.               )
  74.             )
  75.           )
  76.         )
  77.       )
  78.       (princ (strcat "\n" (itoa count) " block reference(s) updated "))
  79.     )
  80.   )
  81.   (vla-endundomark actDocObject)
  82.   (princ)
  83. )
  84.  
  85. (defun c:BRBL ()
  86.   (c:BKG_ReplaceBlock)
  87. )
  88.  
  89. (princ "\nUse: BKG_ReplaceBlock or BRBL ")
« Last Edit: October 10, 2013, 02:21:12 PM by roy_043 »

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Replace block, also when to be replaced block is nested
« Reply #9 on: October 10, 2013, 09:55:13 AM »
An old lisp: (I did not look at your example)
http://www.theswamp.org/index.php?topic=2272.0
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

Woabow

  • Newt
  • Posts: 56
Re: Replace block, also when to be replaced block is nested
« Reply #10 on: October 10, 2013, 10:29:00 AM »
Thanks! Both programs work great.

The vla-put-name does the trick? I can't find documentation about this function...



CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Replace block, also when to be replaced block is nested
« Reply #11 on: October 10, 2013, 11:21:16 AM »
Try highlighting  vla-put-name in VLIDE & press Ctrl+Shift+A
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

Lee Mac

  • Seagull
  • Posts: 12905
  • London, England
Re: Replace block, also when to be replaced block is nested
« Reply #12 on: October 10, 2013, 11:31:07 AM »
Here is an online reference for the Name property:
http://entercad.ru/acadauto.en/idh_name.htm

Here is the full ActiveX & VBA reference:
http://entercad.ru/acadauto.en/

Here is a short explanation of how to use the reference:
http://bit.ly/1ahKh6g

Woabow

  • Newt
  • Posts: 56
Re: Replace block, also when to be replaced block is nested
« Reply #13 on: October 10, 2013, 11:39:33 AM »
Thanks a lot. I have underestimated ActiveX I guess.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Replace block, also when to be replaced block is nested
« Reply #14 on: October 10, 2013, 12:54:23 PM »
Nice explanation Lee, very helpful.
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.