LISP auto page number layout tabs

LISP auto page number layout tabs

infoJV782
Contributor Contributor
7,433 Views
33 Replies
Message 1 of 34

LISP auto page number layout tabs

infoJV782
Contributor
Contributor

Hi,

I have been using a LISP routine written by @dbhunia (attached) that puts page numbers in titleblocks using an attribute. It works great but i would like to make some changes to it, but i'm quite new to lisp and don't really know where to start. 

In addition to the pagenumber for current page, i would like a counter for total amount of layout pages in the document (format: Page x of xx). I know (length (layoutlist)) can be used to get total amount of layout tabs but i can't seem to make it work. 

Can anyone lend a helping hand? 

 

0 Likes
Accepted solutions (1)
7,434 Views
33 Replies
Replies (33)
Message 2 of 34

pendean
Community Legend
Community Legend
While you wait... if you use SSM (SheetSet Manager) with your layouts that feature is built-in and ready to use anytime you want as a simple to use FIELD. Give it a try.
0 Likes
Message 3 of 34

peter_pan_y_vino
Contributor
Contributor

Hello.

I am not an expert in lisp programming. Try the attached lisp routine.

Greetings from Spain.

 

0 Likes
Message 4 of 34

ronjonp
Mentor
Mentor

Give this a try untested. You will need to supply the correct tag name ( tag_name2 ) for your total sheet attribute.

;;Written by dbhunia;;
(defun c:tabnumber (/ layt_lst lay_list blk_name n tag_name tag_name2 layoutname)
  ;;Put temp variables
  (vl-load-com)
  (setq	blk_name  "BLK_NAME"
	;;Put Titel Block Name in place of "BLK_NAME" as per your drawing
	tag_name  "NO"
	;; You need to change this tag to your total sheet tag in your block
	tag_name2 "TOTAL"
	;;Put Att Tag Name of sheet number in place of "NO" as per your drawing its case sensitive
	l	  -1
	tab	  (getvar 'ctab)
  )
  (vlax-for layt (vla-get-layouts (vla-get-activedocument (vlax-get-acad-object)))
    (if	(> (vla-get-taborder layt) 0)
      (setq layt_lst (cons (cons (vla-get-taborder layt) (vla-get-name layt)) layt_lst))
    )
  )
  (setq layt_lst (vl-sort layt_lst '(lambda (x y) (< (car x) (car y)))))
  (foreach layt layt_lst (setq layoutname (cons (cdr layt) layoutname)))
  (setq lay_list (reverse layoutname))
  (repeat (setq n (length lay_list))
    (setq lay_name (nth (setq l (+ l 1)) lay_list))
    (setvar 'ctab lay_name)
    (setq ss (ssget "_A" (list '(0 . "INSERT") (cons 2 blk_name) (cons 410 lay_name))))
    (repeat (setq nos (sslength ss))
      (vlax-for	blk (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object)))
	(if (= (vla-get-name blk) blk_name)
	  (progn (setq obj (vlax-ename->vla-object (ssname ss (setq nos (- nos 1)))))
		 (foreach att (vlax-invoke obj 'getattributes)
		   (if (= (vla-get-tagstring att) tag_name)
		     (vla-put-textstring att (+ 1 (vl-position lay_name lay_list)))
		   )
		   (if (= (vla-get-tagstring att) tag_name2)
		     (vla-put-textstring att (itoa n))
		   )
		 )
	  )
	)
      )
    )
  )
  (setvar 'ctab tab)
  (princ)
)

 

0 Likes
Message 5 of 34

ronjonp
Mentor
Mentor

Here's a simpler version that does not cycle the tabs:

(defun c:tabnumber (/ _put a blk_name e i n o s tag_name tag_name2)
  ;;Put temp variables
  (vl-load-com)
  (defun _put (blk tag val)
    (vl-some
      '(lambda (x) (and (wcmatch (vla-get-tagstring x) (strcase tag)) (vla-put-textstring x val)))
      (vlax-invoke blk 'getattributes)
    )
  )
  ;; Edit below for your use
  (setq	blk_name  "TITLEBLOCKNAME"
	tag_name  "SHEET_NAME"
	tag_name2 "TOTAL_SHEETS"
  )
  (setq i (itoa (length (layoutlist))))
  (vlax-for l (vla-get-layouts (vla-get-activedocument (vlax-get-acad-object)))
    (setq a (cons (list (vla-get-name l) (vla-get-taborder l)) a))
  )
  (if (setq s (ssget "_A" (list '(0 . "INSERT") (cons 2 blk_name) '(66 . 1))))
    (foreach b (mapcar 'cadr (ssnamex s))
      (if (setq n (cadr (assoc (cdr (assoc 410 (entget b))) a)))
	(progn (_put (setq o (vlax-ename->vla-object b)) tag_name (itoa n)) (_put o tag_name2 i))
      )
    )
  )
  (princ)
)
0 Likes
Message 6 of 34

infoJV782
Contributor
Contributor

Thank you @ronjonp for your help, it's very appriciated!

The short version works, but the long version that cycles through tabs gives this error message: "error: bad argument type: lselsetp nil". 

I'm also wondering how to add text "Page (current page) of (total pages)." in the lisp?

0 Likes
Message 7 of 34

ronjonp
Mentor
Mentor

Do you want to be able to input the start number and then the total amount of sheets?

0 Likes
Message 8 of 34

infoJV782
Contributor
Contributor

No i want the pagecounter to be automated, i just want the output to be Page x of xx instead of just x xx (as it is now) but i don't know how to add that in lisp. 

0 Likes
Message 9 of 34

ronjonp
Mentor
Mentor
Accepted solution

@infoJV782 wrote:

No i want the pagecounter to be automated, i just want the output to be Page x of xx instead of just x xx (as it is now) but i don't know how to add that in lisp. 


Maybe this ?

(defun c:tabnumber (/ _put a blk_name e i n s tag_name)
  (defun _put (blk tag val)
    (vl-some
      '(lambda (x) (and (wcmatch (vla-get-tagstring x) (strcase tag)) (vla-put-textstring x val)))
      (vlax-invoke blk 'getattributes)
    )
  )
  ;; Edit below for your use
  (setq	blk_name "YOURTITLEBLOCKNAME"
	tag_name "YOURATTRIBUTETAG"
  )
  (setq i (itoa (length (layoutlist))))
  (vlax-for l (vla-get-layouts (vla-get-activedocument (vlax-get-acad-object)))
    (setq a (cons (list (vla-get-name l) (vla-get-taborder l)) a))
  )
  (if (setq s (ssget "_A" (list '(0 . "INSERT") (cons 2 blk_name) '(66 . 1))))
    (foreach b (mapcar 'cadr (ssnamex s))
      (if (setq n (cadr (assoc (cdr (assoc 410 (entget b))) a)))
	(_put (vlax-ename->vla-object b) tag_name (strcat "Page " (itoa n) " of " i))
      )
    )
  )
  (princ)
)(vl-load-com)
0 Likes
Message 10 of 34

infoJV782
Contributor
Contributor

Yes exactly like that, thank you! Ok last question i promise, then i'll stop pestering you: If i have several blocks with the same attributes in, can i include them in this lisp too somehow? Like say if i have two kinds of titleblocks and i want tis lisp to apply to both of them at the same time?

 

0 Likes
Message 11 of 34

ronjonp
Mentor
Mentor

Yes, simply separate your values with commas like so .. this will work for your tags as well assuming you're not filling in two attributes with the same data within the same block.

 

(setq	blk_name "YOURTITLEBLOCKNAME,YOURTITLEBLOCKNAME2,YOURTITLEBLOCKNAME3"
	tag_name "YOURATTRIBUTETAG,YOURATTRIBUTETAG2,YOURATTRIBUTETAG3"
  )

 

0 Likes
Message 12 of 34

infoJV782
Contributor
Contributor

Aah okay i was trying to use the same attributename in all my blocks.. Works perfectly now, thank you!

0 Likes
Message 13 of 34

ronjonp
Mentor
Mentor

@infoJV782 wrote:

Aah okay i was trying to use the same attributename in all my blocks.. Works perfectly now, thank you!


Glad we got it sorted! 🍻

0 Likes
Message 14 of 34

Sea-Haven
Mentor
Mentor

Nice idea using multi tags and values this is the old fashioned way. May update one day.

 

 

(foreach att (vlax-invoke (vlax-ename->vla-object (ssname SS1 0 )) 'getattributes)
        (if (= oldtag1 (strcase (vla-get-tagstring att)))
        (vla-put-textstring att newstr1) 
        ) ; end if

        (if (= oldtag2 (strcase (vla-get-tagstring att)))
        (vla-put-textstring att newstr2) 
        ) ; end if

        (if (= oldtag3 (strcase (vla-get-tagstring att)))
        (vla-put-textstring att newstr3) 
        ) ; end if

 

 

For InfoJV782 we have multiple update title block lisps to suit task, like your request. Easier than trying to do one big one. For example our 3rd party software creates layouts with correct title block but no attribute data, so fill in 1 title block and it updates all the others with same info. 

0 Likes
Message 15 of 34

infoJV782
Contributor
Contributor

Okay i lied earlier, i acually have one more question! Is there a simple way to exclude a layout tab? Either by tabname or just subtract (-1) from the total count? 

0 Likes
Message 16 of 34

ronjonp
Mentor
Mentor

@infoJV782 wrote:

Okay i lied earlier, i acually have one more question! Is there a simple way to exclude a layout tab? Either by tabname or just subtract (-1) from the total count? 


Give this a try:

 

(defun c:tabnumber (/ _put a blk_name e exclude i n s tag_name)
  (defun _put (blk tag val)
    (vl-some
      '(lambda (x) (and (wcmatch (vla-get-tagstring x) (strcase tag)) (vla-put-textstring x val)))
      (vlax-invoke blk 'getattributes)
    )
  )
  ;; Edit below for your use
  (setq	blk_name "YOURTITLEBLOCKNAME"
	tag_name "YOURATTRIBUTETAG"
	;; List of tab names to exclude
	exclude	 (mapcar 'strcase '("tabname1" "tabname2" "tabname2"))
  )
  ;; Subtract the excluded tabs from the total
  (setq i (- (itoa (length (layoutlist))) (length exclude)))
  (vlax-for l (vla-get-layouts (vla-get-activedocument (vlax-get-acad-object)))
    (or	(vl-position (strcase (vla-get-name l)) exclude)
	(setq a (cons (list (vla-get-name l) (vla-get-taborder l)) a))
    )
  )
  (if (setq
	s (ssget "_A"
		 (list '(0 . "INSERT") (cons 2 blk_name) '(66 . 1) (410 . "~NAMEOFTABTOEXCLUDE"))
	  )
      )
    (foreach b (mapcar 'cadr (ssnamex s))
      (if (setq n (cadr (assoc (cdr (assoc 410 (entget b))) a)))
	(_put (vlax-ename->vla-object b) tag_name (strcat "Page " (itoa n) " of " i))
      )
    )
  )
  (princ)
)
(vl-load-com)
0 Likes
Message 17 of 34

infoJV782
Contributor
Contributor

I get this error when i run the lisp; error: bad argument type: consp "~NAMEOFTABTOEXCLUDE" (same error when i change NAMEOFTABTOEXCLUDE to my tabname)

0 Likes
Message 18 of 34

ronjonp
Mentor
Mentor

Ooops .. I left a filter in that I shouldn't have. Take this out and is should work.

(410 . "~NAMEOFTABTOEXCLUDE")

Use the 'exclude' portion of the code to add tabs .. then your total should be correct.

0 Likes
Message 19 of 34

Sea-Haven
Mentor
Mentor

Bit old fashioned but can do a

(If (or (= (vla-get-name tab) "layout1" )(= (vla-get-name tab) "layout2" )(= (vla-get-name tab) "Model") )

(princ)

(progn

rest of code

 

Ok for 1 or 2 etc as when you want lots then as you have suggested, Dont forget "Model".

0 Likes
Message 20 of 34

infoJV782
Contributor
Contributor

after removing that piece of code i still get a error, but this time it's error: bad argument type: numberp: "3" (3 is the number of layouttabs in my drawing, if that helps). 

0 Likes