(progn (cond --- I have a question.

(progn (cond --- I have a question.

nychoe1
Advocate Advocate
915 Views
8 Replies
Message 1 of 9

(progn (cond --- I have a question.

nychoe1
Advocate
Advocate

hello..

 

this is change linetype lsp. I am making draft of it but, it doesn't working

what is that reason???

 

let me know please..

 

(defun c:ty ( / i ss )
  (setvar "cmdecho" 0)
 (if (setq i (getstring "\n\t->  Hidden(H) Hidden2(H2) HiddenX2(HX2) CONtinuous(CON) CenTer(C) Center2(C2) CenterX2(CX2) Dot2(D2)  : "))
  (progn
   (setq ss (ssget '((0 . "LINE")))
   (sssetfirst nil ss)
    (cond
     ( (= i h)     (princ "\n\t = HIDDEN Linetype")         (command "_.change" ss "" "p" "lt" "hidden" "") )
     ( (= i h2)   (princ "\n\t = HIDDEN2 Linetype")        (command "_.change" ss "" "p" "lt" "hidden2" "") )
     ( (= i hx2)  (princ "\n\t = HIDDENX2 Linetype")     (command "_.change" ss "" "p" "lt" "hiddenx2" "") )
     ( (= i con) (princ "\n\t = CONTINUOUS Linetype") (command "_.change" ss "" "p" "lt" "CONTINUOUS" "") )
     ( (= i c)     (princ "\n\t = CENTER Linetype")        (command "_.change" ss "" "p" "lt" "CENTER" "") )
     ( (= i c2)    (princ "\n\t = CENTER2 Linetype")      (command "_.change" ss "" "p" "lt" "CENTER2" "") )
     ( (= i cx2)  (princ "\n\t = CENTERX2 Linetype")    (command "_.change" ss "" "p" "lt" "CENTERX2" "") )
     ( (= i d2)    (princ "\n\t = DOT2 Linetype")           (command "_.change" ss "" "p" "lt" "DOTX2" "") )

    ) ;cond
   )
  ) ;progn
 ) ; if
 (princ)
) ; defun

0 Likes
916 Views
8 Replies
Replies (8)
Message 2 of 9

Kent1Cooper
Consultant
Consultant

The i variable will be a text string, which means you must check for its value with surrounding double-quotes:
....

   (cond
     ( (= i "h") ....

 

However, in case a User types in a capital letter, the above test would miss it.  It would be better to capitalize whatever they type, and compare that to the capital letter:

....

   (cond
     ( (= (strcase i) "H") ....

 

But there are even better ways to do it, with (initget) and (getkword).  Maybe I'll be back with a suggestion for that, later, if someone else doesn't beat me to it.

Kent Cooper, AIA
Message 3 of 9

Shneuph
Collaborator
Collaborator

I think you may need a progn within the conds... like this:

Because each cond accepts 2 arguements; the test and the result.  You are giving it 3. The Princ and command count as 2 so you need to wrap them in a progn so cond sees them as a single arguement.

 

(cond
  (;cond1
    (= i h)
    (progn
      (princ "\n\t = HIDDEN Linetype")
      (command "_.change" ss "" "p" "lt" "hidden" "")
      );progn
    );cond1
---sig---------------------------------------
'(83 104 110 101 117 112 104 64 71 109 97 105 108 46 99 111 109)
0 Likes
Message 4 of 9

Kent1Cooper
Consultant
Consultant

@Shneuph wrote:

I think you may need a progn within the conds... like this:

Because each cond accepts 2 arguements; the test and the result.  You are giving it 3. The Princ and command count as 2 so you need to wrap them in a progn so cond sees them as a single arguement. ....

 


That's true for the 'thenexpr' and 'elseexpr' arguments in an (if) function, but not in a (cond) function, which accepts any number of arguments.  You can follow the test with as many things as you want it to do if the test result is not nil, without wrapping them in a (progn) function to make them one.

Kent Cooper, AIA
0 Likes
Message 5 of 9

Kent1Cooper
Consultant
Consultant

@Kent1Cooper wrote:

.... 

But there are even better ways to do it, with (initget) and (getkword).  Maybe I'll be back with a suggestion for that, later, if someone else doesn't beat me to it.


In the meantime, here is the collection of commands that I use for this kind of thing, which uses the (initget)/(getkword) approach.  Differences from your 'ty' command:

 

1)  It works with more linetypes [but see comments at the top].

 

2)  It will assign them to any relevant kinds of objects [not just Lines].

 

3)  It requires selecting items to assign the linetype to one at a time, so that it can notify the User if they miss, or something is on a locked Layer, or it is a kind of object for which linetype is irrelevant, but stay in the command for selection of other objects.

 

4)  It has a generic command [CL] which asks the User for a linetype [similar to 'ty'], and also specific command names to get the various linetypes directly [e.g. CLH2 to give things Hidden2 linetype].

 

5)  After the first use, it remembers the linetype you last used and offers it as the default on subsequent use.

 

6)  Within the running of it, you can change to a different linetype at any time and keep going.

 

It could certainly serve as the basis for editing into a more limited-purpose command that would operate like 'ty'.

Kent Cooper, AIA
0 Likes
Message 6 of 9

dbroad
Mentor
Mentor

Kent has given you some good suggestions.  What follows is a different approach.  I believe 99% of your objects should be set to a linetype of bylayer.  You should use layers in your lineweight approach.  Leaving room for at least bylayer and byblock linetypes should be a priority.  In addition, the lineweight names themselves, properly formatted can simplify the code.

 

(defun c:test (/ ss keys which)
  (setq ss (ssget))
  (setq	keys
	 "Hidden hIdden2 hiddeNx2 COntinuous Center cEnter2 centeRx2 Dot2"
  )
  (initget keys)
  (setq
    which (getkword (strcat "\nWhich linetype?(" keys ")" "<Bylayer>")
	  )
  )
  (command "_.chprop" ss "" "lt" (if which which "Bylayer") "")
  (princ)
)

 

Architect, Registered NC, VA, SC, & GA.
0 Likes
Message 7 of 9

dbroad
Mentor
Mentor

I didn't format the prompt string correctly.  The following would be better.

(defun keywords	 (keys)
  (vl-list->string (charsub2 (vl-string->list keys))))
(defun charsub2	 (strl)
  (if (null strl)
    nil
    (cons (if (= 32 (car strl))
	    47
	    (car strl))
	  (charsub2 (cdr strl)))))
(defun c:test  (/ ss keys which)
  (setq ss (ssget))
  (setq	keys
	 "Hidden hIdden2 hiddeNx2 COntinuous Center cEnter2 centeRx2 Dot2")
  (initget keys)
  (setq	which (getkword	(strcat	"\nWhich linetype?["
				(keywords keys)
				"]"
				"<Bylayer>")))
  (command "_.chprop"
	   ss
	   ""
	   "lt"
	   (if which
	     which
	     "Bylayer")
	   "")
  (princ))

 

Architect, Registered NC, VA, SC, & GA.
0 Likes
Message 8 of 9

Kent1Cooper
Consultant
Consultant

@Kent1Cooper wrote:
....

....  Differences from your 'ty' command:

....


Another:

 

7)  It has an internal one-at-a-time Undo option, so you can reverse the assignment on individual objects as you go, within the running of the command [another reason for having you select things one at a time].

 

And Doug makes an excellent point -- I draw almost everything in BYLAYER linetype, so I typically only use these commands when I have some good reason to override that, and hadn't thought about wanting to change it back with them.  I also noticed in looking it over that I didn't have Continuous in there -- I probably went through acad.lin for linetypes, and Continuous isn't in there.

 

So I adjusted the code [attached] to include COntinuous and BYlayer and BYBlock linetypes, and while I was in there, to "fix" the *error* handler and the Undo Begin/End approach to work right in 2015 and beyond.

Kent Cooper, AIA
Message 9 of 9

nychoe1
Advocate
Advocate

thank you. I surely knew that.

0 Likes