Hi,
I have a routine that put the layer name, color and linetype of the select object in 3 different variables. At the end of this routine, I would like to print this variables values. I am able to do this with the layer name and lynetype but not with the color. I think because the color is an integer.
Here is what I am doing:
(princ (strcat "\n" newlay " is now the current layer. "));works good
(princ (strcat "\n" newcol " is now the current color. "));does not work
(princ (strcat "\n" newlt " is the current linetype. "));works good
Any help?
Solved! Go to Solution.
Solved by Kent1Cooper. Go to Solution.
Solved by Kent1Cooper. Go to Solution.
Solved by Kent1Cooper. Go to Solution.
You should convert the integer to string .
(itoa newcol)
Oops!
I just realise: if the color is Bylayer the (princ (strcat "\n" newcol " is now the current color. ")) will work. But if I convert the variable value to a integer it will still work?
Thanks
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;http://forums.autodesk.com/t5/Visual-LISP-AutoLISP-and-General/Lisp-routine-to-set-Layer-Lintype-col...
;;Defines current layer with chose object properties;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun C:OL (/ e newlay newcol newlwt newlt)
(setq e (car (entsel "\nSelect object whose layer, color and linetype will become current: ")))
(if e
(progn
(setq e (entget e))
(setq newlay (cdr (assoc 8 e)))
(setq newcol (cdr (assoc 62 e)))
(if (= newcol nil) (setq newcol "bylayer"))
(setq newlt (cdr (assoc 6 e)))
(if (= newlt nil) (setq newlt "bylayer"))
(setq newlwt (cdr (assoc 370 e)))
(if (= newlwt nil)
(progn
(setq newlwt "bylayer")
);close progn
(progn
(setq newlwt (/ newlwt 100.0))
);close progn
);close if
(command "layer" "s" newlay "")
(command "color" newcol)
(command "-lweight" newlwt)
(command "linetype" "s" newlt "")
);close progn
);close if
(if (eq (type newcol) 'INT)
(itoa newcol)
newcol
)
(command "lwdisplay" "off")
(princ (strcat "\n" newlay " is now the current layer. "))
(princ (strcat "\n" newcol " is now the current color. "))
(princ (strcat "\n" newlt " is the current linetype. "))
(princ)
);defun
Works with Bylayer but with other color I get this
Command: bad argument type: stringp 30
@msarqui wrote:
.... if the color is Bylayer the (princ (strcat "\n" newcol " is now the current color. ")) will work. But if I convert the variable value to a integer it will still work? ....
If you want "Bylayer" reported that way even if it's stored as color number 256, you can do something like this:
(princ
(strcat
"\n"
(cond
((= newcol 256) "ByLayer")
((= newcol 0) "ByBlock")
((eq (type newcol) 'INT) (itoa newcol)); any numerical value
(newcol); either "Bylayer" or "Byblock" or any color name in text form
); cond
" is now the current color. "
); strcat
); princ
It could also be made more sophisticated to report, for example, a stored numerical value of 3 as "Green" and so on.
[EDIT: I hadn't seen your code yet, and thought maybe settings would be arrived at by some other means than object selection, so some of the above isn't really applicable.]
@msarqui wrote:
....
(setq newlay (cdr (assoc 8 e)))
(setq newcol (cdr (assoc 62 e)))
(if (= newcol nil) (setq newcol "bylayer"))
(setq newlt (cdr (assoc 6 e)))
(if (= newlt nil) (setq newlt "bylayer"))
(setq newlwt (cdr (assoc 370 e)))
(if (= newlwt nil)
(progn
(setq newlwt "bylayer")
);close progn
(progn
(setq newlwt (/ newlwt 100.0))
);close progn
);close if
....
Another approach to that part of it, using only one (setq) function, and which also accounts for additional possibilities:
(setq
newlay (cdr (assoc 8 e))
newcol
(cond
((member '(62 . 0) e) "Byblock")
((assoc 62 e) (itoa (cdr (assoc 62 e)))); other numerical
("Bylayer")
); cond & newcol
newlt
(cond
((assoc 6 e) (cdr (assoc 6 e)))
("Bylayer")
); cond & newlt
newlwt
(cond
((member '(370 . -2) e) "Byblock")
((member '(370 . -3) e) "Default")
((assoc 370 e) (/ (cdr (assoc 370 e)) 100.0)); other numerical
("Bylayer")
); cond & newlwt
); setq
Thanks for all answers but I loved this from Kent:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;http://forums.autodesk.com/t5/Visual-LISP-AutoLISP-and-General/Lisp-routine-to-set-Layer-Lintype-col...
;;Defines current layer with chose object properties;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun C:OL (/ e newlay newcol newlwt newlt)
(setq e (car (entsel "\nSelect object whose layer, color and linetype will become current: ")))
(if e
(progn
(setq e (entget e))
(setq newlay (cdr (assoc 8 e)))
(setq newcol (cdr (assoc 62 e)))
(if (= newcol nil) (setq newcol "bylayer"))
(setq newlt (cdr (assoc 6 e)))
(if (= newlt nil) (setq newlt "bylayer"))
(setq newlwt (cdr (assoc 370 e)))
(if (= newlwt nil)
(progn
(setq newlwt "bylayer")
);close progn
(progn
(setq newlwt (/ newlwt 100.0))
);close progn
);close if
(command "layer" "s" newlay "")
(command "color" newcol)
(command "-lweight" newlwt)
(command "linetype" "s" newlt "")
);close progn
);close if
(command "lwdisplay" "off")
(princ
(strcat "\n" newlay " is now the current layer, "
(cond
((= newcol 1) "Red")
((= newcol 2) "Yellow")
((= newcol 3) "Green")
((= newcol 4) "Cyan")
((= newcol 5) "Blue")
((= newcol 6) "Magenta")
((= newcol 7) "White")
((= newcol 256) "ByLayer")
((= newcol 0) "ByBlock")
((eq (type newcol) 'INT) (itoa newcol)); any numerical value
(newcol); either "Bylayer" or "Byblock" or any color name in text form
); cond
" is now the current color & " newlt " is the current linetype. "
); strcat
); princ
(princ)
);defun
A few further suggestions:
Since the entity properties are being determined from object selection, I don't think there's any way the Color could end up being 256 [if it's Bylayer, the result will be nil rather than a number], so you can eliminate that possibility.
In all the checks whether something is nil, it's very slightly shorter/simpler to check not whether they are "equal to" nil, but just whether they exist at all, i.e.
(if (= newlwt nil)
can instead be either
(if (not newlwt)
or
(if (null newlwt)
and similarly with others.
You have a couple of (progn) functions that aren't really doing anything for you -- you can just do:
(if (= newlwt nil)
(setq newlwt "bylayer"); then
(setq newlwt (/ newlwt 100.0)); else
);close if
And if you check for the mere existence of variables, in some cases like the above, you can check whether it does exist rather than whether it doesn't, and simplify it by removing the (not) or (null) function and reversing the 'then' and 'else' parts:
(if newlwt
(setq newlwt (/ newlwt 100.0)); then
(setq newlwt "bylayer"); else
);close if
Or even simpler, with only one (setq) function:
(setq newlwt (if newlwt (/ newlwt 100.0) "bylayer"))
Multiple commands can be performed in one (command) function:
(command
"layer" "s" newlay ""
"color" newcol
"-lweight" newlwt
"linetype" "s" newlt ""
); command
Or you could do them faster [though you probably wouldn't detect the time difference in this situation] with System Variables:
(setvar 'clayer newlay)
(setvar 'cecolor newcol)
(setvar 'celweight newlwt)
(setvar 'celtype newlt)
which should all be done earlier in the routine, because some of those you would need to set before converting values for prompt wording, etc.
[A small thing, but I would use (prompt) to report the settings. Yes, (princ) works, but prompting is what you're actually doing. And the (prin...) functions are set up with the option to also write information to a file, which is irrelevant here.]
You can streamline that prompt somewhat with a list of color names:
(prompt
(strcat "\n" newlay " is now the current layer, "
(cond
((eq (type newcol) 'INT); any numerical value
(if (< newcol 8); has a word equivalent
(nth newcol '("ByBlock" "Red" "Yellow" "Green" "Cyan" "Blue" "Magenta" "White")); then
(itoa newcol); else
); if
); numerical condition
(newcol); either "Bylayer" or "Byblock" or any color name in text form
); cond
" is now the current color & " newlt " is the current linetype. "
); strcat
); prompt
Hi guys,
Old post, but I noticed that if the color is BYBLOCK, I have this error:
Command:
Select object whose layer, color and linetype will become current: layer
Current layer: "Tx-E-Chemin de câble"
Enter an option
[?/Make/Set/New/Rename/ON/OFF/Color/Ltype/LWeight/TRansparency/MATerial/Plot/Fre
eze/Thaw/LOck/Unlock/stAte/Description/rEconcile]: s
Enter layer name to make current or <select object>: Tx-E-Chemin de câble Enter
an option
[?/Make/Set/New/Rename/ON/OFF/Color/Ltype/LWeight/TRansparency/MATerial/Plot/Fre
eze/Thaw/LOck/Unlock/stAte/Description/rEconcile]:
Command: color
Enter default object color [Truecolor/COlorbook] <2 (yellow)>: 0
Invalid color number.
; error: Function cancelled
And here is the routine:
(defun C:LOL (/ e newlay newcol newlwt newlt)
(command "select" nil);to remove selection if an object is already selected
(setq e (car (entsel "\nSelect object whose layer, color and linetype will become current: ")))
(if e
(progn
(setq e (entget e))
(setq newlay (cdr (assoc 8 e)))
(setq newcol (cdr (assoc 62 e)))
(setq newlt (cdr (assoc 6 e)))
(if (not newlt) (setq newlt "Bylayer"))
(setq newlwt (cdr (assoc 370 e)))
(if newlwt
(setq newlwt (/ newlwt 100.0))
(setq newlwt "Bylayer")
);if
(command "layer" "s" newlay ""
"color" newcol
"-lweight" newlwt
"linetype" "s" newlt ""
);command
);close progn
);close if
(command "lwdisplay" "off")
(prompt
(strcat "\n" newlay " is now the current layer, "
(cond
((= newcol 1) "Red")
((= newcol 2) "Yellow")
((= newcol 3) "Green")
((= newcol 4) "Cyan")
((= newcol 5) "Blue")
((= newcol 6) "Magenta")
((= newcol 7) "White")
((= newcol 256) "ByLayer")
((= newcol 0) "ByBlock")
((eq (type newcol) 'INT) (itoa newcol)); any numerical value
(newcol); either "Bylayer" or "Byblock" or any color name in text form
); cond
" is now the current color & " newlt " is the current linetype. "
); strcat
);prompt
(princ)
);defun
Thanks
@msarqui wrote:
...if the color is BYBLOCK, I have this error:
....
Command: color
Enter default object color [Truecolor/COlorbook] <2 (yellow)>: 0
Invalid color number.
....
In a quick trial, I find that the Color command [or hyphen-prefixed -Color if done manually, not inside a (command) function] wants only text strings, even for numerical values, probably because of the possibility of using words such as "Red." But I find that the CECOLOR "command" [that is, the command-form approach to setting a System Variable] accepts integers.
Try changing:
"color" newcol
to:
"cecolor" newcol
or pull it out of the (command) function and use:
(setvar 'cecolor newcol)
But if the selected object is Bylayer in color, doesn't the newcol variable turn out to be nil? I don't see that possibility accounted for, though I think it was discussed earlier. Give it a fallback as you do with the newlt variable.
@Kent1Cooper wrote:
In a quick trial, I find that the Color command [or hyphen-prefixed -Color if done manually, not inside a (command) function] wants only text strings,
But if the selected object is Bylayer in color, doesn't the newcol variable turn out to be nil? I don't see that possibility accounted for, though I think it was discussed earlier. Give it a fallback as you do with the newlt variable.
Well, if the color of the object is Bylayer, the routine does not works and I have this error:
Command:
bad argument type: stringp nil
@msarqui wrote:
....Well, if the color of the object is Bylayer, the routine does not works and I have this error:Command:
bad argument type: stringp nil
Exactly what I was pointing out. One way to account for that [to "Give it a fallback" as I suggested] would be to replace this part:
....
(command "layer" "s" newlay ""
"color" newcol
....
with this, to use the 'newcol' value if it exists, but if not, use "BYLAYER":
....
(command "layer" "s" newlay ""
"color" (cond (newcol) ("BYLAYER"))
....
@Kent1Cooper wrote:
Exactly what I was pointing out. One way to account for that [to "Give it a fallback" as I suggested] would be to replace this part:
....
(command "layer" "s" newlay ""
"color" newcol....
with this, to use the 'newcol' value if it exists, but if not, use "BYLAYER":
....(command "layer" "s" newlay ""
"color" (cond (newcol) ("BYLAYER"))....
As one of your suggestions, I made this :
(command "layer" "s" newlay ""
"cecolor" (cond (newcol) ("BYLAYER"))
"-lweight" newlwt
"linetype" "s" newlt ""
);command
The routine is working good now, only the prompt still has the error.
So, I tryed the same thing but it did not work...
...
(prompt
(strcat "\n" newlay " is now the current layer, "
(cond
((= newcol 1) "Red")
((= newcol 2) "Yellow")
((= newcol 3) "Green")
((= newcol 4) "Cyan")
((= newcol 5) "Blue")
((= newcol 6) "Magenta")
((= newcol 7) "White")
((= newcol 256) (cond (newcol) ("BYLAYER")))
((= newcol 0) "ByBlock")
((eq (type newcol) 'INT) (itoa newcol)); any numerical value
(newcol); either "Bylayer" or "Byblock" or any color name in text form
); cond
" is now the current color & " newlt " is the current linetype. "
); strcat
);prompt
...
@msarqui wrote:
....The routine is working good now, only the prompt still has the error.
So, I tryed the same thing but it did not work...
...
(prompt
(strcat "\n" newlay " is now the current layer, "
(cond
((= newcol 1) "Red")
....((= newcol 256) (cond (newcol) ("BYLAYER")))
...
If the selected object's color is Bylayer, the (cdr (assoc 62 e)) earlier will return nil, not 256 -- there just won't be a (62 . ...) entry. Try this:
....
(prompt
(strcat "\n" newlay " is now the current layer, "
(cond
((not newcol) "ByLayer")
((= newcol 1) "Red")
....
((= newcol 7) "White")
((= newcol 0) "ByBlock")
((eq (type newcol) 'INT) (itoa newcol)); any numerical value >7
(newcol); either "Bylayer" or "Byblock" or any color name in text form ; it won't be any of these if coming from (assoc 62 e)
); cond
" is now the current color & " newlt " is the current linetype. "
); strcat
);prompt