Jump to content

LISP Routines: How To.


resullins

Recommended Posts

Forgive me if this has already been covered, I'm new here and I couldn't find it.

 

I've been using ACAD for a VERY long time, but have never consciously used a LISP routine. A little bit of research has sort of told me what they are.... but I have NO idea how to make them work.

 

My dilemma: Auto-numbering selct attributes in blocks. I found one here that people say works perfecly, and I've saved it to my support file, and I've loaded it in to my drawing, but how do I actually make it run?

 

Sorry for my ignorance. All help is appreciated!

Link to comment
Share on other sites

  • Replies 27
  • Created
  • Last Reply

Top Posters In This Topic

  • resullins

    11

  • Lee Mac

    9

  • BlackBox

    3

  • CyberAngel

    1

Top Posters In This Topic

Posted Images

If you look at the code, it should begin with a parenthesis, the word "defun" (for DEfine FUNction), and the name of the routine. Once you load the routine in your AutoCAD session, you only have to type the name to run it. In effect, you've created a new command.

Link to comment
Share on other sites

Thanks Lee... It all makes sense now. I've just never had the privilege of working with LISPS before since I'm not much of a programmer.

 

One more question, since you seem to have a metric s-ton of experience in this stuff... I know this topic has been discussed ad-nauseum around here, but I can't seem to find the answer I need. I need to autonumber certain block attributes, with a prefix. For example, I need a whole bunch of blocks to number from L-001 to L-010. Then later in the drawing, I might need to number some from L-201 to L-221. I've found a lisp that will auto-number well, but it won't leave a prefix on there.

 

Has anyone figured this one out?

Link to comment
Share on other sites

One more question, since you seem to have a metric s-ton of experience in this stuff... I know this topic has been discussed ad-nauseum around here, but I can't seem to find the answer I need. I need to autonumber certain block attributes, with a prefix. For example, I need a whole bunch of blocks to number from L-001 to L-010. Then later in the drawing, I might need to number some from L-201 to L-221. I've found a lisp that will auto-number well, but it won't leave a prefix on there.

 

I wrote this a while back, and have quickly modified it to accept an optional prefix and zero padding - it will number from left to right currently:

 

(defun c:AttNum ( / *error* _StartUndo _EndUndo _PadLeft doc ss lst ) (vl-load-com)
 ;; © Lee Mac 2010

 (defun *error* ( msg )
   (if doc (_EndUndo doc))
   (or (wcmatch (strcase msg) "*BREAK,*CANCEL*,*EXIT*")
       (princ (strcat "\n** Error: " msg " **")))
   (princ)
 )

 (defun _StartUndo ( doc ) (_EndUndo doc)
   (vla-StartUndoMark doc)
 )

 (defun _EndUndo ( doc )
   (if (= 8 (logand 8 (getvar 'UNDOCTL)))
     (vla-EndUndoMark doc)
   )
 )

 (defun _PadLeft ( str cha len )
   (if (< (strlen str) len)
     (_PadLeft (strcat cha str) cha len)
     str
   )
 )

 (setq doc  (vla-get-ActiveDocument (vlax-get-acad-object)))  

 (setq *tag (cond ( *tag ) ( "TAG1" ))
       
 )

 (setq *tag
   (strcase
     (cond
       (
         (eq ""
           (setq tmp
             (getstring
               (strcat "\nSpecify Attribute Tag to be Numbered <"
                 (setq *tag
                   (cond ( *tag ) ( "TAG1" ))
                 )
                 "> : "
               )
             )
           )
         )
         *tag
       )
       ( tmp )
     )
   )
 )

 (setq *pre (getstring t "\nSpecify Prefix <None> : "))

 (initget 6)
 (setq len  (getint "\nSpecify Number Length <Any> : "))

 (setq *num
   (1-
     (cond
       (
         (getint
           (strcat "\nSpecify Starting Number <"
             (itoa
               (setq *num
                 (1+
                   (cond ( *num ) ( 0 ))
                 )
               )
             )
             "> : "
           )
         )
       )
       ( *num )
     )
   )
 )

 (if (ssget "_:L" '((0 . "INSERT") (66 . 1)))
   (progn      
     (vlax-for o (setq ss (vla-get-ActiveSelectionSet doc))
       (setq lst
         (cons
           (cons (vlax-get o 'InsertionPoint) o) lst
         )
       )
     )
     (vla-delete ss)

     (_StartUndo doc)

     (mapcar
       (function
         (lambda ( block )
           (mapcar
             (function
               (lambda ( attrib )
                 (if (eq *tag (strcase (vla-get-TagString attrib)))
                   (vla-put-TextString attrib
                     (strcat *pre
                       (_PadLeft (itoa (setq *num (1+ *num))) "0" (cond ( len ) ( 0 )))
                     )
                   )
                 )
               )
             )
             (vlax-invoke (cdr block) 'GetAttributes)
           )
         )
       )
       (vl-sort lst
         (function
           (lambda ( a b ) (< (caar a) (caar b)))
         )
       )
     )

     (_EndUndo doc)
   )
 )

 (princ)
)


Link to comment
Share on other sites

You really have. In fact, I'm going to see if I can alter your code to remove on of the input options. We ALWAYS need to change one specific tag, so I think I can take out that prompt.

Link to comment
Share on other sites

  • 3 weeks later...

Ok Lee: I'm having trouble with this LISP editing. I can't seem to get it right. I'm trying to update the above LISP so that it always alters the attribute called LINE#, and so that the default value for number length is 3. But I seem to keep screwing it up. (Luckily, I'm smart enough to keep a copy of the original that I keep going back to.) Any tips?

Link to comment
Share on other sites

try the tutorials.. i know they helped me.. you may need a reread them a few times as your learning ( i reread about 20 time for a 4 line command i made)

these are the tutorials lee mac refered me to AfraLISP or JeffreySanders

Edited by mathew21
found link
Link to comment
Share on other sites

Just remove the prompts for those parameters should do the trick:

 

(defun c:AttNum ( / *error* _StartUndo _EndUndo _PadLeft doc ss lst len ) (vl-load-com)
 ;; © Lee Mac 2010

 (defun *error* ( msg )
   (if doc (_EndUndo doc))
   (or (wcmatch (strcase msg) "*BREAK,*CANCEL*,*EXIT*")
       (princ (strcat "\n** Error: " msg " **")))
   (princ)
 )

 (defun _StartUndo ( doc ) (_EndUndo doc)
   (vla-StartUndoMark doc)
 )

 (defun _EndUndo ( doc )
   (if (= 8 (logand 8 (getvar 'UNDOCTL)))
     (vla-EndUndoMark doc)
   )
 )

 (defun _PadLeft ( str cha len )
   (if (< (strlen str) len)
     (_PadLeft (strcat cha str) cha len)
     str
   )
 )

 (setq doc  (vla-get-ActiveDocument (vlax-get-acad-object)))  

[color=red]  (setq *tag "LINE#" len 3)[/color]
 
 (setq *pre (getstring t "\nSpecify Prefix <None> : "))

 (setq *num
   (1-
     (cond
       (
         (getint
           (strcat "\nSpecify Starting Number <"
             (itoa
               (setq *num
                 (1+
                   (cond ( *num ) ( 0 ))
                 )
               )
             )
             "> : "
           )
         )
       )
       ( *num )
     )
   )
 )

 (if (ssget "_:L" '((0 . "INSERT") (66 . 1)))
   (progn      
     (vlax-for o (setq ss (vla-get-ActiveSelectionSet doc))
       (setq lst
         (cons
           (cons (vlax-get o 'InsertionPoint) o) lst
         )
       )
     )
     (vla-delete ss)

     (_StartUndo doc)

     (mapcar
       (function
         (lambda ( block )
           (mapcar
             (function
               (lambda ( attrib )
                 (if (eq *tag (strcase (vla-get-TagString attrib)))
                   (vla-put-TextString attrib
                     (strcat *pre
                       (_PadLeft (itoa (setq *num (1+ *num))) "0" (cond ( len ) ( 0 )))
                     )
                   )
                 )
               )
             )
             (vlax-invoke (cdr block) 'GetAttributes)
           )
         )
       )
       (vl-sort lst
         (function
           (lambda ( a b ) (< (caar a) (caar b)))
         )
       )
     )

     (_EndUndo doc)
   )
 )

 (princ)
)

 

Untested however.

Link to comment
Share on other sites

  • 4 weeks later...

Ok, I'm ressurecting this thing in hopes that someone can help me further.

 

I need to alter the Lisp program the very kind LeeMac provided in this thread. I simply need to remove some of the user inputs, and make them default to an attribute I dictate. But the only thing I can find on how to learn LISP is all about AutoLisp. Is there anything out there that's not going to take me 18 years to learn?

Link to comment
Share on other sites

... Is there anything out there that's not going to take me 18 years to learn?

 

That entirely depends on you, the student. :wink:

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...