Jump to content

Move layout to new position


V4Mp

Recommended Posts

Hello @all

 

I have an edited code. It creates a new layout with a new name. The new name is set by a number a user can input into autocad (variable "num").

 

Layouts get the names:

2-1, 2-2, 3-1, 3-2

and so on.

 

What the code should do, is

1. Take the name of the new page-layout as "num" (ie 4)

2. Create two new layouts (ie 4-1 and 4-2)

3. Move these layouts to the position they should be. (ie 3-2 > 4-1 > 4-2)

 

I wanted to repeat the codes, when the number of the layout befor not exists. (ie our num is 6 and we have the layout 3-1, 3-2 , 8-1, 8-2)

And then move the layout behind the next logic number. (in the example it should be 3-2, 6-1, 6-2, 8-1, 8-2)

 

I tried to edit it, but failed. Anyone who can help me?
What I tried was, to repeat the code until no error. Every error "value" should be changed to "num_befor" minus 1 and the fix string "-2", because "-2" is the last layout of the number. (ie num_befor = 5, because we have 6 as num, after an error the "value" should be changed to 4-2 and then next error to 3-2. With an error the function should be repeated with the new variables "value for tname2" as tname2 is our layout behind we try to move the layout each try.

 

Hopefully you can understand me. :)

 

(tab-after num_page1 num_page_befor num)
  
  (setvar 'CMDECHO oCMDECHO)
  (princ)
  
)

(defun tab-after (tname1 tname2 num / tabs pos1 pos2)
  (vl-load-com)
  (restart-case (/ tname1 tname2 num)
    (return-zero ()
      :report "Return 0"
      0)
    (divide-by-one ()
      :report "Divide by 1"
      (/ x 1))
    (setq tabs
           (vla-get-Layouts
             (vla-get-Activedocument (vlax-get-acad-object))
           )
    )
    (setq pos1 (vla-get-TabOrder (vla-item tabs tname1))
          pos2 (vla-get-TabOrder (vla-item tabs tname2))
    )
    
    (if (> pos1 pos2) (setq pos2 (1+ pos2)))
    (vla-put-TabOrder (vla-item tabs tname1) pos2)
    (princ)
    
    (set-new-divisor (value)
      (setq num_befor (- (atoi num) 1))
      (setq value (strcat num_befor "-2"))
      ;; and call the divide function with the new value…
      ;; … possibly catching bad input again!
      (tab-after tname1 value num)
    )
  )
) 

 

 

Edited by V4Mp
Link to comment
Share on other sites

There's plenty of code out there for this already. I usually rearrange them by dragging tabs around but use Lee Mac's http://www.lee-mac.com/tabsort.html from time to time. Coping is simply ctrl+dragging tabs and for adding layouts from templates Lee Mac's http://www.lee-mac.com/steal.html.

 

Using layout names that describe what's on them for makes them a lot easier for everyone to follow. 

I'm guessing you're referencing tab names as page numbers?

I use a modified version of Lee Mac's http://www.lee-mac.com/layoutfield.html for those that automatically modifies them when they're rearranged, added, or deleted.

 

I don't plan my posts to promote Lee Mac's code but I use a lot of it every day. Thanks Lee!

Link to comment
Share on other sites

Thanks for your reply. 

 

No, the layoutname describe what it is. In fact the complete drawing is a building and the numbers are specific parts of the building.

I knew already lee-mac's version. But for me it's over the top for the lisp I am using. It would consume to mutch time for me to edit the lee-mac code.

But I think I am changing my strategy. Insted of moving one tab to the correct position, I am now sorting all tabs. That will do the same and in the end it helps provending mistakes.

Edited by V4Mp
Link to comment
Share on other sites

This one will sort all the desired tabs and places it at the end of the list of all the layouts.

(defun c:test ( / acd ind len lst nm sortl)
    (while
	(progn
	    (initget 6)
	    (setq nm (getint "\nSpecify number <exit>: "))
	    (cond
		((not nm) nil)
		((progn
		     (setq nm (itoa nm))
		     (vl-some
			 '(lambda (x)
			      (if
				  (wcmatch x (strcat nm "`-[12]"))
				  (princ (strcat "\nLayout name " x " already exists."))
				  )
			      )
			 (layoutlist)
			 )
		     )
		 )
		)
	    )
	)
    (if nm
	(progn
	    (setq acd (vla-get-Layouts (vla-get-ActiveDocument (vlax-get-acad-object))))
	    (foreach x (list (strcat nm "-1") (strcat nm "-2"))
		(vla-Add acd x)
		)
	    (setq lst (layoutlist)
		  sortl (vl-remove-if-not '(lambda (x) (wcmatch x "#*`-[12]")) lst)
		  ind (vl-sort sortl
			  '(lambda (a b)
			       (if (= (atoi a) (atoi b))
				   (<
				       (atoi (substr a (+ (vl-string-search "-" a) 2)))
				       (atoi (substr b (+ (vl-string-search "-" b) 2)))
				       )
				   (< (atoi a) (atoi b))
				   )
			       )
			  )
		  len (length lst)
		  )
	    (mapcar '(lambda (x) (vla-put-TabOrder (vla-item acd x) len)) ind)
	    )
	)
    (princ)
    )
Edited by Jonathan Handojo
  • Like 1
Link to comment
Share on other sites

Jonathan Handojo

Thank you for your replay. The code works, but I have more then 10 layouts. If I use 2, 6, 9 everything ok. But I need also 22 or 123. That could be rooms.

With your code a number with two or three places do not work.

 

I have found a simple function that does the job, but it sorts only for one place.

 

In example the result is

1, 2, 5, 55, 6

but should be

1, 2, 5, 6, 55

Edited by V4Mp
Link to comment
Share on other sites

Unfortunately you are dealing with Windows sorting rules. You need to pad the numbers with leading zeros so that the layouts have something like "001, 002, 005, 006, 055", then you can remove the leading zeros after the sort by using (vl-string-left-trim).

Link to comment
Share on other sites

Use an alphanumerical sorting function to interpret & sort numerical data within the string, rather than sorting character-wise, e.g. to sort layouts alphanumerically, you might use:

(defun c:sortlayouts ( / ls1 ls2 ord )
    (vlax-for lyt (vla-get-layouts (vla-get-activedocument (vlax-get-acad-object)))
        (if (= :vlax-false (vla-get-modeltype lyt))
            (setq ls1 (cons (strcase (vla-get-name lyt)) ls1)
                  ls2 (cons lyt ls2)
            )
        )
    )
    (setq ord 0)
    (foreach idx (LM:alphanumsort-i ls1)
        (vla-put-taborder (nth idx ls2) (setq ord (1+ ord)))
    )
    (princ)
)

;; Alphanumerical Sort-i  -  Lee Mac
;; Sorts a list of strings containing a combination of alphabetical & numerical characters and returns the indices.
 
(defun LM:alphanumsort-i ( lst )
    (vl-sort-i (mapcar 'LM:splitstring lst)
        (function
            (lambda ( a b / x y )
                (while
                    (and
                        (setq x (car a))
                        (setq y (car b))
                        (= x y)
                    )
                    (setq a (cdr a)
                          b (cdr b)
                    )
                )
                (cond
                    (   (null x) b)
                    (   (null y) nil)
                    (   (and (numberp x) (numberp y)) (< x y))
                    (   (numberp x))
                    (   (numberp y) nil)
                    (   (< x y))
                )
            )
        )
    )
)
 
;; Split String  -  Lee Mac
;; Splits a string into a list of text and numbers
 
(defun LM:splitstring ( str )
    (
        (lambda ( l )
            (read
                (strcat "("
                    (vl-list->string
                        (apply 'append
                            (mapcar
                                (function
                                    (lambda ( a b c )
                                        (cond
                                            (   (or (= 34 b) (= 92 b))
                                                (list 32 34 92 b 34 32)
                                            )
                                            (   (or (< 47 b 58)
                                                   ;(and (= 45 b) (< 47 c 58) (not (< 47 a 58)))
                                                    (and (= 46 b) (< 47 a 58) (< 47 c 58))
                                                )
                                                (list b)
                                            )
                                            (   (list 32 34 b 34 32))
                                        )
                                    )
                                )
                                (cons nil l) l (append (cdr l) '(( )))
                            )
                        )
                    )
                    ")"
                )
            )
        )
        (vl-string->list str)
    )
)

(vl-load-com) (princ)

 

  • Like 3
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...