PDA

View Full Version : one selection block routine?


voigtmark
2007-07-20, 01:37 PM
Below is some code for a routine i copied from the autodesk website. It works fine for a single block, however what i would like to do is more complicated(of course) I would like to select multiple blocks with different names, for example on block named "fpr" and another named "dr". after the selection is made i would like to replace the blocks with "fprd" and "drd" respectively. Our block naming convention is "XXX" for our standard block and "xxxd" for our demo blocks. how can this code be modified so i can search our libraries for the blocks with the same names but with the "d" at the end of the block name. I assume a wildcard of some type. or maybe an if then argument. Ihave commented one line out as it is not needed.


(defun c:REPL (/ ENT1 BL1 NWNM OLD ODNM)
(prompt "Select blocks to replace: ")
(setq ENT1 (ssget))
;(setq NEWBL ("fprd"))
(command "insert" fprd nil)
(setq N (sslength ENT1))
(setq I 0)
(repeat N
(setq BL1 (entget (ssname ENT1 I)))
(setq NWNM (cons 2 "fprd"))
(setq OLD (assoc 2 BL1))
(setq ODNM (cdr OLD))
(entmod (subst NWNM OLD BL1))
(command "change" "p" "" "p" "la" "e-demo-powr" "" "")
(setq I (1+ I))
)
(prin1)
)

jmcshane
2007-07-20, 03:01 PM
Have you checked out the "Replace block with another block " in the Express tools ?

John

voigtmark
2007-07-20, 03:56 PM
Yes I have, however it doesn't give the functionality that I want. I want to window an area or the drawing filter out the objects I do not need and replace the blocks that are in the selection set with the proper block. for example block "fpr" will be replaced with "fprd" and "dr" will be replaced with "drd" etc.

fixo
2007-07-20, 04:42 PM
Not sure that I understand your task
exactly, try this slightly edited code
on the copy of your working drawing


(defun c:REPL (/ BL1 ENT1 I N NM NWNM OLD)
(prompt "Select blocks to replace: ")
;; following wildcards means than block name consist 3 letters only: ("@@@")
(setq ENT1 (ssget (list (cons 0 "INSERT")(cons 2 "@@@"))))
(setq N (sslength ENT1))
(setq I 0)
(repeat N
(setq BL1 (entget (ssname ENT1 I))
NM (cdr (assoc 2 BL1)))
(setq NWNM (cons 2 (strcat NM "d")))
(setq OLD (assoc 2 BL1))
(entmod (subst NWNM OLD BL1))
(command "change" "p" "" "p" "la" "e-demo-powr" "" "")
(setq I (1+ I))
)
(prin1)
)

voigtmark
2007-07-20, 08:38 PM
What I am trying to do is replace blocks of one name with the demolition block that corresponds with that block. block one is named "fpr" the corresponding demolition block is "fprd". block two is named "dr" and the corresponding demolition block is "drd" and so on and so on with the block library we use. The block names are not limited to 3 characters. I would like to use a selection window to select the blocks, filter for the block names and replace them all with just a few clicks. What i am doing now is inserting them individually and then erasing the block i want replaced. this is very time consuming. Block replace will not work because it replaces blocks globally. here is some code with a block filter added. I hope this makes it more clear.

(defun c:REPL (/ ENT1 BL1 NWNM OLD ODNM)
(prompt "Select quad receptacles to replace: ")
(setq ENT1 (ssget ":n" '((2 . "fpr"))))
;(setq NEWBL ("fprd"))
(command "insert" fprd.DWG nil)
(setq N (sslength ENT1))
(setq I 0)
(repeat N
(setq BL1 (entget (ssname ENT1 I)))
(setq NWNM (cons 2 "fprd"))
(setq OLD (assoc 2 BL1))
(setq ODNM (cdr OLD))
(entmod (subst NWNM OLD BL1))
(command "change" "p" "" "p" "la" "e-demo-powr" "" "")
(setq I (1+ I))
)
(prin1)
)

fixo
2007-07-20, 10:45 PM
You can use instead another filter:

(ssget (list (cons 0 "INSERT")(cons 2 "@@@@,@@@,@@"))));<--comma separated
where first one for blocks that name consist 4 letters,
next one for 3 letters and last one for 2 letters

Hope that helps

~'J'~

voigtmark
2007-07-23, 02:38 PM
thanks This does help with building the list. What I am trying to do is Insert a seperate block to replace each of the blocks in the list. For block name "fpr" i want to replace it with "fprd", for block name "frep" I want to replace it with the block "FREPD", and for "DR" I want to replace it with the block "DRD". The code is below with your line added.


(defun c:REPL (/ ENT1 BL1 NWNM OLD ODNM)
(prompt "Select quad receptacles to replace: ")
(setq ENT1 (ssget (list (cons 0 "INSERT")(cons 2 "frep,fpr,dr"))));
;(setq NEWBL ("fprd"))
(command "insert" fprd.DWG nil)
(setq N (sslength ENT1))
(setq I 0)
(repeat N
(setq BL1 (entget (ssname ENT1 I)))
(setq NWNM (cons 2 "fprd"))
(setq OLD (assoc 2 BL1))
(setq ODNM (cdr OLD))
(entmod (subst NWNM OLD BL1))
(command "change" "p" "" "p" "la" "e-demo-powr" "" "")
(setq I (1+ I))
)
(prin1)
)

fixo
2007-07-23, 04:55 PM
In your last code you can replace
all blocks on block "fprd" only
replace "repeat" part on this one:

(repeat N
(setq BL1 (entget (ssname ENT1 I))
NM (cdr (assoc 2 BL1)))
(setq NWNM (cons 2 (strcat NM "d")))
(setq OLD (assoc 2 BL1))
(entmod (subst NWNM OLD BL1))
(command "change" "p" "" "p" "la" "e-demo-powr" "" "")
(setq I (1+ I))
)

~'J'~

voigtmark
2007-07-23, 10:53 PM
works like a charm. now all i need to do is get all the block names in.Thanks much.

fixo
2007-07-24, 09:41 AM
Glad to help
Happy computing :)

voigtmark
2007-07-27, 03:58 PM
Here is my new code. (please read below code)

(defun c:edp (/ ENT1 BL1 NWNM OLD ODNM)
(command "-insert" "edemopwr.dwg" "0,0" "" "" "")
(command "erase" "l" "")
(prompt "Select electrical power blocks to replace: ")
(setq ENT1 (ssget (list (cons 0 "INSERT")(cons 2 "BOXC,BOXWD,BOXWL,BOXWR,BOXWU,CSDC,DR,DREP,DRSC,ECI,DCS,DGP,DP,DRC,EPB,EWB,ESS,FPRC,FPR,FPREP,FPRSC,GP,HSR,JB,JBWD,JBWL,JBWR,JBWU,MTR,PFB,PPEDB,SPO,SRC,SR"))))
(setq N (sslength ENT1))
(setq I 0)
(repeat N
(setq BL1 (entget (ssname ENT1 I))
NM (cdr (assoc 2 BL1)))
(setq NWNM (cons 2 (strcat NM "d")))
(setq OLD (assoc 2 BL1))
(entmod (subst NWNM OLD BL1))
(command "change" "p" "" "p" "la" "e-demo-powr" "" "")
(setq I (1+ I))
)
(prin1)
(command "-purge" "b" "*" "n")
)

works good "EXCEPT" I run the program once and it works great, however if i run it the second time i get this message. ; error: bad argument type: lselsetp nil

What now. I know it must be because it can't find anything in the selection set, but cant figure out how to correct it.

Lions60
2007-07-27, 05:22 PM
Try this code. Basically i just made it one big if statement stating that if there is a value in the selection set then process the items, if there is not anything in the selection set then do nothing.

(defun c:edp (/ ENT1 BL1 NWNM OLD ODNM)
(command "-insert" "edemopwr.dwg" "0,0" "" "" "")
(command "erase" "l" "")
(prompt "Select electrical power blocks to replace: ")
(if(setq ENT1 (ssget (list (cons 0 "INSERT")(cons 2 "BOXC,BOXWD,BOXWL,BOXWR,BOXWU,CSDC,DR,DREP,DRSC,ECI,DCS,DGP,DP,DRC,EPB,EWB,ESS,FPRC,FPR,FPREP,FPRSC,GP,HSR,JB,JBWD,JBWL,JBWR,JBWU,MTR,PFB,PPEDB,SPO,SRC,SR")))) (setq N (sslength ENT1))
(progn
(setq I 0)
(repeat N
(setq BL1 (entget (ssname ENT1 I))
NM (cdr (assoc 2 BL1)))
(setq NWNM (cons 2 (strcat NM "d")))
(setq OLD (assoc 2 BL1))
(entmod (subst NWNM OLD BL1))
(command "change" "p" "" "p" "la" "e-demo-powr" "" "")
(setq I (1+ I))
)
);; end of progn
);; end of if
(prin1)
(command "-purge" "b" "*" "n")
)

voigtmark
2007-07-27, 06:40 PM
I am still getting the same error message.

fixo
2007-07-27, 06:59 PM
And this is right, because of when you run
routine first time all block names you used
in selection set filter was changed

From this point there are no blocks with these names

Hth

~'J'~

Lions60
2007-07-27, 07:59 PM
I had to go in and edit the code i posted. I had put th eif statement in the wrong place. The code in my previous post is now correct and should not recieve an error. If there is nothing by that block name the program should recongnize this and not perform any tasks and exit quietly. If there are blocks in the drawing with any of those names then it shoudl perform the tasks and after completing the tasks on each block it should exit quietly