Dandy 发表于 2022-7-5 17:19:16

Replace block, but keeping old

Hello,
 
I'm looking for something like the following:
 
I have a drawing with a lot of similar or nearly equal blocks. Unfortunately each block has a unique name so it's not a block reference. But each block has the same attribute list, but with block specific values.
 
What I want to do is to change all blocks against one master block, so that each block has the same name (block reference). For this I found some scripts. Unfortunately the unique block attributes get lost or will be replaced by the master block.
 
http://www.cadtutor.net/forum/showthread.php?37765-Merge-Block
 
 
I also found some scripts for copying attributes from one to another block.
 
http://www.lee-mac.com/matchattribs.html
 
BUT what I'm locking is a script that does the following.
 
1. Selectthe master block (A)
2. Select all other blocks (B,C,D,E, ..)
3. Starting the replacement of blocks (B,C,D,E, ..)
3.1 Copy attributes values of block B to a list
3.2 Replacing the block B against master block A
3.3 Copy back attribute values to the newly replaced block
3.4 Starting with Block C again ( steps 3.1 - 3.3)
 
Anybody who can help ?? I looked into the code of the scripts, but I'm "too" Newbeeto lisp to make this work.
 
Thanks in advance
Dandy

BIGAL 发表于 2022-7-5 17:31:09

There are two ways to access info about block attributes either by their "tag name" or "creation order" in your case unless every block has the same tag names I would use the second method.
 
Please post a dwg with a few blocks in it.
 

; example of attributes by creation order; an example pick one attributed block(setq ss1 (ssget (list (cons 0 "INSERT"))))(foreach att (vlax-invoke (vlax-ename->vla-object (ssname SS1 0 )) 'getattributes)(alert (strcase (vla-get-textstring att))) ;displays attribute value;(alert (strcase (vla-get-tagstring att))) ;displays tag name)

Dandy 发表于 2022-7-5 17:40:10

Hello Bigal,
 
thanks for replaying.
I have attached a sample.dwg
 
In this dwg are 3 blue blocks (they are irrelevant) and 4 other similar block references (white).
 
3 of them (with the base point in the blue ones) have an cryptic ID as a name "{.........}". The forth block (top right) has a name "Raumstempel".
 
What I want to achive is to replace the block with the cryptic names by a block reference of the block "Raumstempel", but before replacing the attribute values of each block (attributes of all 4 relevant blocks are the same, only values are unique) has to be stored and written back after the replacement.
 
I found a script for replacing and ascript for copying attributes form Mac Lee (see my first post). But because of I'm not familar with AutoCAD programming I'm not able to combine them
 
So that was the reason to ask for some support.
 
If you are someone else can help me this would be great
 
Thanks Dandy
 
 
sample.dwg

BIGAL 发表于 2022-7-5 17:48:43

Ok you can find all the blocks via this as long as they always start with {

(setq ss (ssget "x" (list( cons 0 "Insert")(cons 2 "{*"))))
 
I would read all the attributes using above swap the existing block onto a frozen layer, then insert the correct block same spot with the attribute values, when happy its all ok you could delete the old block rather than freeze it.
 
Need to replace in code above in a repeat (ssname SS1 x) where is x is a counter id from how many blocks have been found.
 
Bit busy right now some one else may jump in with a solution.

David Bethel 发表于 2022-7-5 17:56:55

Actually it can be a fairly simple routine :
 
You can (subst) group 2 BLOCK names as long as the replacment BLOCK definition exists in the current drawing.
 

(defun c:blk-mast (/ ss i en ed) (if (not (tblsearch "BLOCK" "MASTER"))   (alert "MASTER Block Not Found")   (and (setq ss (ssget "X" (list (cons 0 "INSERT")                                    (cons 2 "A,B,C")                                    (cons 66 1))))          (setq i 0)          (while (setq en (ssname ss i))               (setq ed (entget en))               (entmod (subst (cons 2 "MASTER") (assoc 2 ed) ed))               (setq i (1+ i))))) (prin1))
 
A gotcha here could be any synchronize routine that goes back to the BLOCK table definitions.
 
-David
-BLKR.DWG

Dandy 发表于 2022-7-5 18:06:49

Hello David,
thanks for replaying. I just checked your script and your sample dwg, it looked good and the script makes mainly what I'm looking for :-). But is it possible to provide the arguments by input selection (mouse courser) instead of a fixed list ?? Unfortunately my block names are not as simple as your sample A,B,C and picking would be much more easier than taking out the name of each block in my drawing and to placing it in a list. Thanks in advance ;-) Daniel

David Bethel 发表于 2022-7-5 18:15:10

Maybe :
 

(defun c:blk-mmst (/ master rl ss i en ed bn) (while (not master)      (and (princ "\nSelect MASTER Replacement BLOCK:   ")             (setq ss (ssget (list (cons 0 "INSERT"))))             (= (sslength ss) 1)             (setq master (strcase (cdr (assoc 2 (entget (ssname ss 0)))))))) (princ (strcat "\n" master)) (while   (and (princ "\nSelect BLOCKs To Replace:   ")      (setq ss (ssget (list (cons 0 "INSERT")))))   (setq i 0)   (while (setq en (ssname ss i))          (setq ed (entget en)                bn (strcase (cdr (assoc 2 ed))))          (cond ((= bn master))                ((member bn rl))                ((setq rl (cons bn rl))))          (setq i (1+ i)))) (foreach e rl   (and (setq ss (ssget "X" (list (cons 0 "INSERT")                                  (cons 2 e))))      (princ (strcat "\n" e))      (setq i 0)      (while (setq en (ssname ss i))               (setq ed (entget en))               (entmod (subst (cons 2 master) (assoc 2 ed) ed))               (setq i (1+ i))))) (command "_.REGEN") (prin1))
 
 
This would not deal nested BLOCKs
 
HTH-David

Dandy 发表于 2022-7-5 18:25:13

Hello David, thanks for supporting .. I will try it out ;-). Best Dandy
页: [1]
查看完整版本: Replace block, but keeping old