Visual LISP, AutoLISP and General Customization
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Entmod only works sometimes

10 REPLIES 10
Reply
Message 1 of 11
rbevansii
438 Views, 10 Replies

Entmod only works sometimes

I'm having to go into several drawings to rotate a lot of equipment casters. I've put together a LISP to do an entmod and it only works sometimes. If I have just a piece of equipment it works, but when I try it with a bunch in a drawing it does not work. It tells me "; error: bad argument type: numberp: nil" after I select the caster. Once I get this working is it possible to do multiple entmods at one time? Right now when I try to do multiple it does nothing.

(defun c:test ()
(setq cstr (ssget))
(setq edata (entget (ssname cstr i)) newdata (subst (cons 50 0.0)(assoc 50 edata) edata)
)
(entmod newdata)
) Edited by: rbevansii on May 14, 2010 3:11 PM
10 REPLIES 10
Message 2 of 11
Moshe-A
in reply to: rbevansii

hi,

take a look at this

{code}
(defun c:test (/ i cstr edata)
(if (setq cstr (ssget))
(progn
(setq i -1)
(repeat (sslength cstr)
(setq i (1+ i))
(setq edata (entget (ssname cstr i)))
(setq newdata (subst (cons 50 0.0) (assoc 50 edata) edata))
(entmod newdata)
); repeat
); progn
); if
{code}

Moshe
Message 3 of 11
rbevansii
in reply to: rbevansii

This is setup to run through the whole drawing and I need to be able to do manually. I don't need every caster rotated.
Message 4 of 11
Anonymous
in reply to: rbevansii

In my experiance using entmod, it works on one record at a time. I have used it a loop to be able to modify more that one just record. I don't see a loop in your code. You may want to look at the WHILE or IF and see if that works with what you want to do.
Message 5 of 11
Kent1Cooper
in reply to: rbevansii

It wouldn't work if that's the *entire* code -- you're missing the surrounding code that would set and increment the i variable. You would certainly get that kind of error message if there was no number value set to i. It's obviously set up for processing multiple Blocks, because if it were for one at a time, you would use 0 instead of i, or better yet, use (entsel) instead of (ssget). [The only advantage I can think of to using (ssget) for a *single* object is if you were going to filter for a Block insertion only, or a certain Layer, or something, but you don't have any filtering.]

But since it looks like you're changing it [or them all] to 0 rotation, I would try using the Properties box. Grab the ones you want, as many as you want, as you would in (ssget), or use Qselect to grab all the Blocks of a particular name, and just give them the 0 rotation in that slot in the Properties box, all at one shot. No code required.

--
Kent Cooper


rbevansii wrote...
I'm having to ... rotate a lot of equipment casters. I've put together a LISP to do an entmod and it only works sometimes. If I have just a piece of equipment it works, but when I try it with a bunch in a drawing it does not work. It tells me "; error: bad argument type: numberp: nil" after I select the caster. Once I get this working is it possible to do multiple entmods at one time? Right now when I try to do multiple it does nothing.

(defun c:test ()
(setq cstr (ssget))
(setq edata (entget (ssname cstr i)) newdata (subst (cons 50 0.0)(assoc 50 edata) edata)
)
(entmod newdata)
)
Kent Cooper, AIA
Message 6 of 11
rbevansii
in reply to: rbevansii

I had a hunch I could only do one entmod at a time, but wanted to be sure.

I was going to do a loop with while and if statement, but there are just to many variable to take into account. By the time I get the code working and figured out it would be easier for me to do manually.
Message 7 of 11
rbevansii
in reply to: rbevansii

Kent,

I don't want to do all of them at a 0 rotation because the caster rotation is going to be determined based on the equipment rotation. I just threw 0.0 in for testing purposes. If I can get the code working so I can pick and chose which caster I want to rotate I can take it from there.
Message 8 of 11
Kent1Cooper
in reply to: rbevansii

Actually, it's not [it would need to use (ssget "X" ...) -- without that or certain other arguments, it will prompt the User to select], but it *is* missing a closing

); end defun

--
Kent Cooper


rbevansii wrote...
This is setup to run through the whole drawing and I need to be able to do manually. I don't need every caster rotated.
Kent Cooper, AIA
Message 9 of 11
rbevansii
in reply to: rbevansii

Well let me go ahead and take my foot out of mouth. My apologizes Moshe and thank you. Thanks Kent as well.
Message 10 of 11
rbevansii
in reply to: rbevansii

In case anyone is interested. This is what I was needing to accomplish. Thanks everyone for the help.

;;---------------------------------------------------------------------------
;Rotates casters on user input of rotation
(defun c:rotcstr (/ i cstr edata)
(setq ang1 (getstring "Insert Rotation Value: "))
(setq rad1 (angtof ang1))
(if (setq cstr (ssget))
(progn
(setq i -1)
(repeat (sslength cstr)
(setq i (1+ i))
(setq edata (entget (ssname cstr i)))
(setq newdata (subst (cons 50 rad1) (assoc 50 edata) edata))
(entmod newdata)
); repeat
); progn
); if
)
Message 11 of 11
Kent1Cooper
in reply to: rbevansii

You're welcome, and I have a few little suggestions....

If you use (getangle), the User can input an angle in whatever the current angle format is, and it will return radians directly for use in (entmod) later, eliminating the need to convert anything. So you can replace

(setq ang1 (getstring "Insert Rotation Value: "))
(setq rad1 (angtof ang1))

with just

(setq rad1 (getangle "Insert Rotation Value: "))

and skip the ang1 variable altogether. AND, (getangle) *also* gives the User the option of specifying the angle by *picking two points on-screen*, such as locations in an equipment Block insertion you want to align with, so they don't need to know the numerical value at all, which would be very helpful in the case of oddly-rotated equipment.

You ought to also include ang1 [if you keep it around], rad1, and newdata in the localized variables list.

You can combine multiple (setq)'s into one function:

(setq
i (1+ i)
edata (entget (ssname cstr i))
newdata (subst (cons 50 rad1) (assoc 50 edata) edata)
); end setq

And you might want to filter at least for Block insertions:

(setq cstr (ssget '((0 . "INSERT"))))

because as you have it, any other kind of object the User happens to catch in their selection that has a rotation angle [Text or Dimensions, for example] will also be rotated, and if they grab something without a code-50 value at all, it will have a problem trying to change that. You could also filter for particular block names. For instance, if all your Caster blocks have names starting with "Caster", you could do a wildcard filter like this:

(setq cstr (ssget '((0 . "INSERT") (2 . "Caster*"))))

and then the User could save time by just grabbing a *whole area* with a Window or Crossing selection, and it will "find" only those Caster Blocks -- even if there are other kinds of Blocks [or Text, or whatever] in there, it won't change their rotations.

--
Kent Cooper
Kent Cooper, AIA

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report

”Boost