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

Lisp needed for alphabetizing text

6 REPLIES 6
SOLVED
Reply
Message 1 of 7
Anonymous
1305 Views, 6 Replies

Lisp needed for alphabetizing text

I'm working on a lisp and making a mess of it.  I want a lisp where i can simply select text labels on a known layer using a window and convert them into a string in alhabetical order for use as part of a layout name.  The text i'm selecting can be A-Z, AA-ZZ, OR A1-A? to Z1-Z?

 

Here's what i have so far

(defun LM:str->lst ( str del / len lst pos )
    (setq len (1+ (strlen del)))
    (while (setq pos (vl-string-search del str))
        (setq lst (cons (substr str 1 pos) lst)
              str (substr str (+ pos len))
        )
    )
    (reverse (cons str lst))
)


(defun c:big()
(vl-load-com)
  (setq num1 0) 
(while (= num1 0) 
(prompt "\nSelect Objects to be put in layout by Window")
	(setq p1 (getpoint "\nFirst Corner: "))
	(setq p2 (getcorner p1 "\nSecond Corner: "))
	(setq sel1 (ssget "w" p1 p2))
;(initget "P A B F V W M")
;(setq tabb (getkword "\nType of Layout ( Pbyp/Assembly/Backsplash/reFerence/Verification/reWork/reMake ): "))
(setq eset(ssget "W" p1 p2 '((8 . "07-Piece Identity")(0 . "TEXT"))))                                  
(setq cntr 0)

(setq profile "")               ;sets label start
(while (< cntr (sslength eset))  ;set counter to length of selection set
	(cond
	  ((/= cntr (sslength eset)) (setq en(ssname eset cntr))     ;get entity name of nth item
	(setq enlist(entget en))        ; get dxf codes for entity
	(setq profadd (cdr(assoc 1 enlist))) ;sets profadd to value of text in entity
	(setq babb (strcat profile profadd " "))
	(setq profile babb)
	(setq cntr(+ cntr 1))
	   )
	  )
)
(setq crap (list (LM:str->lst profile " ")));convert string to list - crap will have one problem with it
(princ "check 1")
  (setq pist1 (list(vl-remove "" crap)))     ;remove last "item" from string, crap is no longer used
(princ "check 2")
(princ pist1)
(princ "check 3")
  (acad_strlsort (pist1))                      ; sort list alphabetically
(setq llen pist1)                           ; work to be done--  list back to string
  (setq ccou 0)
   (while (< llen ccou)
      (strcat (babb (nth ccou pist1)))
      (setq profile babb)
      (setq ccou(+ ccou 1))
   )						; list back to string ends
(setq labb (strcase babb nil))
(setq dabb (strcase tabb nil))
(cond ((= dabb "P") (setq layy (strcat "PbyP " labb)))
((= dabb "A") (setq layy (strcat "Assembly " labb)))
((= dabb "B") (setq layy (strcat "BS " labb)))
((= dabb "F") (setq layy (strcat "Reference " labb)))
((= dabb "V") (setq layy (strcat "Verification " labb)))
((= dabb "W") (setq layy (strcat "Rework " labb)))
((= dabb "M") (setq layy (strcat "Remake " labb)))
) 
(command "-layout" "c" "Master" layy)
(command "-layout" "S" layy)
(command "mspace")
(command "zoom" "o" sel1 "")
(command "zoom" "s" "0.97x")
(command "pspace")
(command "zoom" "a")
(command "model")

)
)

 Yes I am borrowing a piece of code from Lee Mac's Lisp Site.  It seemed to fit what i was looking for at the time (converting a string to a list) since i couldn't seem to figure out how to build a list of text values from the selection set.  

 

Parts of this code are commented out since they only waste time in testing.  I already use a lot of this code in a "less lazy" version of the code (i type out the labels, instead of jsut having the computer do it from a selection set (which would be ideal since i already select a window for the items to show on the layout.)

 

Tell me I'm missing something obvious.  My guess is that it's a Mapcar/Lambda situation and I am sure thats jsut a bit too far over my head for right now. 

 

 

 

 

6 REPLIES 6
Message 2 of 7
Kent1Cooper
in reply to: Anonymous


@Anonymous wrote:

....  I want a lisp where i can simply select text labels on a known layer using a window and convert them into a string in alhabetical order for use as part of a layout name.  The text i'm selecting can be A-Z, AA-ZZ, OR A1-A? to Z1-Z?

.... 



A little clarification:  Do you want to combine a bunch of text strings, sorted alphabetically, into one text string?  Or am I misunderstanding?  An example of a small number of strings as selected and the nature of the desired output would be helpful.

 

It's easy enough to put the text content of a selection of Text objects into a list, by getting the (cdr (assoc 1 EntityDataList)) or the 'TextString VLA property from each.  That list can be sorted into alphabetical order:

 

(vl-sort '("A27" "B1" "A1" "ZZ" "A0") '<)

returns
("A0" "A1" "A27" "B1" "ZZ")

 

Is that the kind of return you want, or should it really be converted into "a" string, such as "A0A1A27B1ZZ"?  With spaces between, perhaps?

 

However, if you might have different quantities of digits following a the same letter, note this result from that approach:

 

(vl-sort '("A27" "B1" "A100" "ZZ" "A0") '<)

returns
("A0" "A100" "A27" "B1" "ZZ")

 

It puts 100 before 27, because 1 is early in the alphabetical sort than 2 is.  You will find threads on this Forum about sorting that kind of set of things, usually I think by padding the numerical part with enough leading zeros to give them all equal quantities of numerical characters.

Kent Cooper, AIA
Message 3 of 7
Anonymous
in reply to: Kent1Cooper

For an example:  if I would select a window containing the following text objects:

 

"A" "C" "B" "D" "B1" "B2" "B3"

 

I am looking for a result of:

 

"ABB1B2B3CD"

 

The situation which you list  "A100" as coming before "A27" is not likely ever going to be an issue, since the number rarely even passes 4.

 

My autolisp understanding is at a medium level, but most of the commands i use at work are very simple lisps that take the repetitive tasks out of CAD work, such as maintaining standards and keeping things right.  I've probably made about 200 commands and use about 50-60 of them daily.  

 

this one has me stumped though.  

 

 

 

 

Message 4 of 7
Kent1Cooper
in reply to: Anonymous


@Anonymous wrote:

For an example:  if I would select a window containing the following text objects:

 

"A" "C" "B" "D" "B1" "B2" "B3"

 

I am looking for a result of:

 

"ABB1B2B3CD"

.... 


Something like this [in simplest terms, minimally tested, without various usual controls, etc.]:

 

(defun C:TAST (/ txtss inc strlist); = Text Alphabetized and Strung Together

  (setq txtss (ssget '((0 . "TEXT"))))

  (repeat (setq inc (sslength txtss))

    (setq strlist (cons (cdr (assoc 1 (entget (ssname txtss (setq inc (1- inc)))))) strlist))

  ); repeat

  (setq strcomp (apply 'strcat (vl-sort strlist '<)))

); defun

 

That will leave the strung-together composite string in the variable called strcomp.

Kent Cooper, AIA
Message 5 of 7
Anonymous
in reply to: Kent1Cooper

Thats perfect.  

 

 

I will need to work it a bit to fit into the lisp I have but it functions exactly as I was looking for.    I hang my head in embarassment for how much code I wrote in comparison!  Thats why I came here, I knew I must've veered off majorly along the way.

 

Thanks very much!

Message 6 of 7
Kent1Cooper
in reply to: Anonymous


@Anonymous wrote:

Thats perfect.  

.... 

Thanks very much!


You're welcome.  One of the additional elements you might consider adding is that if there's a chance the User selection might not find any Text objects, you can have them do the selection, and then proceed with the concatenation only if there was a result from that.  I guess you don't need to worry about any locked Layer(s), or saving and resetting System Variables, or error handling, at least within the scope of this part of whatever operation it's a part of.

 

And you can have (ssget) filter for Layer so it only "sees" things on the known Layer you're after:

 

  (setq txtss (ssget '((0 . "TEXT") (8 . "YourKnownLayerName"))))

 

[I admit to being curious about how such a returned value would be used, but....]

Kent Cooper, AIA
Message 7 of 7
Anonymous
in reply to: Kent1Cooper

i'm using this list in a larger scheme.  for the company i work for we need to put all the part labels (a, b c, d etc) that exist on a page layout in the layout tab name.  my ocd just wants them in alphabetical order

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

Post to forums  

Autodesk Design & Make Report

”Boost