Jump to content

Code help


rphillips

Recommended Posts

I have a list of blocks that i need to replace when there is one in the dwg file. Below is the code that i use to do that with but i would like to add to this.

My problem

When we receive files from our surveyor the blocks are repeated; example, if we have a block named X then it creates a new block for every occurrence (like so X_1, X_2, X_3) and so on. So the code below allows me to select all the blocks that have an X_ in the name and then it will replace with the correct name X. Currently I use the quick select command >block reference > Name > wilcard match > to search and find any block with an X_ in the name.

 

My Goal

For the code to do all the replaces using a list in the code.

I would like to add the search to the lisp and if no blocks in current file the just ignore.

the list would be something like

X_

APOINT_

MH_

FH_

I will compile the list in the code while testing.

then the code will replace name with name from another list

X

APOINT

MH

FH

and so.

 

Basicly I have a dwg with about 4000 blocks in it and it should only have abut 100.

X_1

X_2

X_1000

Should all be X

 

Thanks for the help

 

(DEFUN C:replace ()

(SETQ SS (SSGET))

(SETQ L 0)

(SETQ NB (GETSTRING "\nNEW BLOCK NAME TO REPLACE OLD:"))

(SETQ N (SSLENGTH SS))

(WHILE (

(SETQ E (ENTGET (SSNAME SS L)))

(SETQ E

(SUBST (CONS 2 NB)

(ASSOC 2 E)

E

)

)

(ENTMOD E)

(SETQ L (1+ L))

)

)

Link to comment
Share on other sites

This should get you started. My lunch break is almost over so I can't do it all for you, but it'll help with the automation:

 

(mapcar '(lambda (x) (ssget "X" (list (cons 2 x)))) (list "X_*" "APOINT_*"))

That returns a list of selection sets, the first one being all blocks with a name that begins with "X_", and so on. You can make the list as long as you'd like.

 

Alls you need is to loop through and do something with each selection set, like a block replace.

 

Good luck, I'm sure you've got enough smarts to figure out the rest, if you've come so far already. ^.^

 

EDIT: And before anyone "corrects" me, yes, you could probably just extend the Lambda to include the block replace. I just don't have the time.

 

EDIT EDIT: Meh..

 

See if this works, it's untested. It'll insert the correct block at the same insertion point of the incorrect block, then delete the incorrect one. At least, that's the idea. My fingers are crossed.

 

(defun c:test( / ss entSet)
 (mapcar '(lambda (x)
        (setq ss (ssget "X" (list (cons 2 (strcat x "_*")))))
        (if ss
          (progn
        (setq entSet (vl-remove-if-not '(lambda (y) (= (type (cadr y)) 'ENAME)) (ssnamex ss)))
        (mapcar '(lambda (z) (vl-cmdf "-insert" x (cdr (assoc 10 (entget z))) "" "" "" "erase" z "")) entSet)
        )
          )
        )
     (list "X" "APOINT"))
 )

Link to comment
Share on other sites

First of all thanks for the hlep!

 

This is what i get when running the code.

 

test ; error: bad argument type: lentityp (0

0)

Link to comment
Share on other sites

First of all thanks for the hlep!

 

This is what i get when running the code.

 

test ; error: bad argument type: lentityp (0

0)

 

Yep, I know what went wrong.. forgot to mapcar a 'cadr to the vl-remove-if-not.

 

Try this:

 

(defun c:test( / ss entSet)
 (mapcar '(lambda (x)
        (setq ss (ssget "X" (list (cons 2 (strcat x "_*")))))
        (if ss
          (progn
        (setq entSet (mapcar 'cadr (vl-remove-if-not '(lambda (y) (= (type (cadr y)) 'ENAME)) (ssnamex ss))))
        (mapcar '(lambda (z) (vl-cmdf "-insert" x (cdr (assoc 10 (entget z))) "" "" "" "erase" z "")) entSet)
        )
          )
        )
     (list "X" "APOINT"))
 )

Link to comment
Share on other sites

Thanks, I think that this works but i dont understand the code. This process takes to long there is about 4000 blocks and i belive this code has to repeat for every block.

 

This is what i am going to use

 

(setq SS (ssget "x" (list (cons 2 "X_*"))))

(if ss

(progn

(SETQ L 0)

(SETQ N (SSLENGTH SS))

(WHILE (

(SETQ E (ENTGET (SSNAME SS L)))

(SETQ E

(SUBST (CONS 2 "X")

(ASSOC 2 E)

E

)

)

(ENTMOD E)

(SETQ L (1+ L))

)

)

)

 

 

then i will repeat the code for to search for other blocks this seams to be a lot faster.

 

At the begining of my code i set cmdecho to 0 and then at the end i set it to 1 but for some reason when i do a purge it still list all the blocks deleted. Is there another way to get the command line not to repeat the info?

Link to comment
Share on other sites

If you are substituting the Block Name, the alternative block definition must be in the drawing also.

 

The old block definitions will also still be in the database and will need to be purged.

Link to comment
Share on other sites

(DEFUN C:RB ( / OriginalErrorHandling)

 

(vl-load-com)

(setq OriginalErrorHandling *error*)

(setq *error* ReplaceBlock_Error)

(setvar "cmdecho" 0)

(command "undo" "begin")

(command"ucs" "")

(setq SS (ssget "x" (list (cons 2 "X_*"))))

(if ss

(progn

(SETQ L 0)

(SETQ N (SSLENGTH SS))

(WHILE (

(SETQ E (ENTGET (SSNAME SS L)))

(SETQ E

(SUBST (CONS 2 "X")

(ASSOC 2 E)

E

)

)

(ENTMOD E)

(SETQ L (1+ L))

)

)

)

(setq SS (ssget "x" (list (cons 2 "APOINT_*"))))

(if ss

(progn

(SETQ L 0)

(SETQ N (SSLENGTH SS))

(WHILE (

(SETQ E (ENTGET (SSNAME SS L)))

(SETQ E

(SUBST (CONS 2 "APOINT")

(ASSOC 2 E)

E

)

)

(ENTMOD E)

(SETQ L (1+ L))

)

)

)

(command"-purge" "blocks" "" "no")

(command "ucs" "p")

(command "undo" "end")

(setvar "cmdecho" 1)

(princ)

)

 

 

 

This is what i have so far

the lines in red are the lines that i wll have to change

the text in cyan is what will be changed in each line.

 

Does anyone see a better way to do this.

thanks

Link to comment
Share on other sites

Sure it will work if i want to go and pick all the blocks.

Please read first post for more information.

Thanks for the help

 

I know the blocks will still be there that is why there is a purge at the end of the code. I just dont what the end user to see all the blocks being deleted.

Link to comment
Share on other sites

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.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...