-
Controlling the Machine is no longer being updated. Don't worry, though, you can still follow Nate Holt at his new blog, AutoCAD Electrical Etcetera. You'll find it at http://nateholt.wordpress.com. Or you can subscribe to his feed to get latest words of wisdom automatically: http://nateholt.wordpress.com/feed/. You also can continue to view the Controlling Machine archives for Nate's AutoCAD Electrical tips and tricks.
-
Nate's Simple AutoLisp - Lesson 004
October 28, 2008, 07:35 AM Nate HoltGeeze, it's been over two years since lesson "003". Busy times. Anyway, we're back. If you have 10 minutes to kill and want to take a chance with an exciting, hands-on experience, then read on.
Warning/Disclaimer: I'm neither a professional teacher nor am I well versed in the theory behind AutoLisp programming. But even beginners can come up with something useful and... best of all, have fun at the same time!
Here's what we'll do in the next 10 minutes. We will build up, step-by-step, a useful program consisting of just one line of code. Then we'll add it as a button on the AutoCAD menu. Note: We're using AutoCAD Electrical as our example application but this applies to AutoCAD in general.
Step-by-Step... A Really Simple "Wire Layer" Lister
We just want to have a lead-pipe simple tool to quickly list the layer name of the picked object, let’s say a series of AutoCAD Electrical wire segments, one at a time, boom…boom…boom. We don’t want a screen-full of data about the object, we don’t want some kind of property dialog to display, we just want this one piece of info and we want it fast.Just for fun, let’s start develop this little tool with nothing more than the “Command:” window. With your AutoCAD schematic drawing active on screen, let’s start here:Command: (entsel) [Enter]Select object: [pick on wire segment, return=] (<Entity name: 7ef05f60> (19.5858 16.9905 0.0))The (entsel) function returns a two-element list: the first element is the entity name of the picked line segment and the second element is the XY coordinate of the mouse pick point. We just want the entity name, the first element of this returned list. Use the AutoLISP "car" function to extract the first element. So let’s next try this:Command: (car (entsel)) [Enter]Select object: [pick on wire segment, return=] <Entity name: 7ef05f60>Remember, gotta keep those "(" and ")" balanced out. For each "(" you add, you need to balance it with a ")". Okay, good so far. Now let’s modify our “program” to open up the selected line segment with a call to “entget”Command: (entget (car (entsel))) [Enter]Select object: [pick on wire segment, return=] ((-1 . <Entity name: 7ef05f60>) (0 . "LINE") (330 . <Entity name: 7ef05c10>) (5 . "6C") (100 . "AcDbEntity") (67 . 0) (410 . "Model") (8 . "RED_18AWG") (100 . "AcDbLine") (10 20.0 17.0 0.0) (11 18.5625 17.0 0.0) (210 0.0 0.0 1.0))Wow, got a lot more information than we really need. The part we want to focus in on is the “8” subrecord which is used to carry the entity’s layer assignment. We'll use the "assoc" call to filter out all but the first instance of the target subrecord...Command: (assoc 8 (entget (car (entsel)))) [Enter]Select object: [pick on wire segment, return=] (8 . "RED_18AWG")Really close. The layer name is in the second part of this return. We can use the “cdr” function to strip off the first part of this list of data…Command: (cdr (assoc 8 (entget (car (entsel))))) [Enter]Select object: [pick on wire segment, return=] "RED_18AWG"Okay, we did it. Pick entity, get layer name instantly. But it only does one at a time. Let’s add a “while” loop around our little program like this:Command: (while (princ (cdr (assoc 8 (entget (car (entsel))))))) [Enter]Select object: RED_18AWGSelect object: RED_18AWGSelect object: BLK_14AWGSelect object: BLK_14AWGSelect object:; error: bad argument type: lentityp nilCommand: *Cancel*Nice. We could stop now. We’re can pick,pick,pick and get instant gratification with each pick. It doesn’t look too pretty when we decide to kick out with [ESC] or pick in empty space. Let’s do just a tiny clean-up so that it exits nicely when we just pick in empty space to finish. We will store the return from (entsel) in variable “x”. If valid, then we go ahead and dig out the layer name of “x” and “princ” it out to the command window. The extra “(princ)” at the very end also helps give a clean return.Command: (while (setq x (entsel))(princ (cdr (assoc 8 (entget (car x))))))(princ) [Enter]Select object: BLK_14AWGSelect object: RED_18AWGSelect object: RED_18AWGSelect object: BLK_14AWGSelect object:Nifty.
Now let’s add our cool tool to the pull-down menu so we don’t have to type it in each time. Type CUI to bring up the standard “Customize User Interface” dialog. Select “ELECTRICAL” and “Menus” for the pull-down menu customization. Let’s put our new tool under the “Wires” pull-down. So expand “Wires” as shown here.
Highlight an existing command, let’s say “Insert Wire” and right-click. Pick “Duplicate”. Now you’ll end up with two “Insert Wire” entries, one above the other. Click on the new, lower one and begin to edit it.
Change the Display name, description. Carefully enter in your new program in the “Macro” line as shown here. The “^C^C^P” prefix is not absolutely necessary but does serve a useful purpose. If you are in some existing command and then pick on this new menu item, the ^C^C part will cancel out of the previous command before starting your new command. Be careful about NOT adding in extra spaces. These can sometimes be interpreted as an [Enter] keystroke when the “Macro” string is executed.
Save the CUI changes. Now, go to your “Wires” pull-down menu.WOW! There it is! Give it a try!

BUT… this cool utility is encoded right into my current version of the menu. Could be easy to lose and a hassle to remember it and to type it back in 100% correctly. Let’s make it a bit safer – put the one-line program into an ASCII text file, call the file “cool.lsp”, and just reference this file from our new menu entry instead of having to encode the program itself into the menu entry.
The key here is to create the cool.lsp ASCII text file and save to some folder that is one of the support paths defined for AutoCAD (or a new support path you add for your cool utilities). This way, a simple call to the AutoLISP function “findfile” will find it.After you create the one-line ASCII text file called “cool.lsp”, do this: test at command line to make sure it works. Type this string:Command: (if (setq x (findfile "cool.lsp"))(load x)) [Enter]Select object: BLK_10AWGSelect object: BLK_10AWGSelect object:Okay, the above test worked. It found, loaded, and executed the one line of code. It worked! Now edit the menu button and encode this “findfile” command string into it. To do this, type CUI and find your “Cool layer lister” entry. Change the macro string to match below. OK out of CUI command and test the menu button.

Time's up! Was that fun or what... ? ! ! !
You must be logged in to post a comment.