Denimoth Posted August 21, 2009 Posted August 21, 2009 G'day all, I have just joined this forum and after using AutoCAD for a dozen years, I wish I had found this place sooner! I'm looking for help to make an autolisp function that will let me select multiple titleblocks in the same layout tab, and create a View for each titleblock named after the titleblock's page number attribute (called PageNo). I'm using AutoCAD 2004 and have limited Autolisp knowledge. The goal is to help me speed things up when plotting as I can select the View instead of making a window and zooming around all over the place. I might try my hand at batch plotting later on, but PDF is tricky and I'll be happy with just having named Views. What I'm trying to figure out is: 1) How to get the value of the PageNo attribute in the titleblock by selecting the block itself. 2) How to get the insertion point information of the titleblock, so that with a little math, I can create the View for that titleblock. 3) How to make this all work by selecting multiple titleblocks at the same time. Any help that can be offered would be greatly appreciated. Quote
Denimoth Posted August 24, 2009 Author Posted August 24, 2009 Ok, I figured out how to get the insertion point information of a block with Autolisp. Took a few days of searching the web. I should be able to draw the viewport around a selected titleblock with that. Anyone know how I can get a specific attribute value out of a block using Autolisp? Quote
gile Posted August 24, 2009 Posted August 24, 2009 Hi, Here's a little sub routine. ;;; GetAttValue (gile) ;;; Retuns an attribute reference value ;;; ;;; Arguments ;;; blk: (ENAME) block reference ename ;;; tag: (STR) attribute tag ;;; ;;; Return: The attribute value or nil if not found (defun GetAttValue (blk tag / att lst loop val) (setq att (entnext blk) lst (entget att) loop (= "ATTRIB" (cdr (assoc 0 lst))) ) (while loop (if (= (strcase tag) (cdr (assoc 2 lst))) (setq val (cdr (assoc 1 lst)) loop nil ) (setq att (entnext att) lst (entget att) loop (= "ATTRIB" (cdr (assoc 0 lst))) ) ) ) val ) Quote
Lee Mac Posted August 24, 2009 Posted August 24, 2009 Another option: ;; blk = VLA-Object ;; tag = STRing (defun getAtt (blk tag / tag lst t1 val) (setq tag (strcase tag) lst (append (vlax-invoke blk 'GetAttributes) (vlax-invoke blk 'GetConstantAttributes))) (while (progn (setq t1 (car lst)) (cond ((eq (strcase (vla-get-TagString t1)) tag) (setq val (vla-get-TextString t1)) nil) ((setq lst (cdr lst))) (t nil)))) val) Quote
Denimoth Posted August 25, 2009 Author Posted August 25, 2009 Thanks for the suggestions guys. But I can't seem to get either of those routines to work. I'm leaning more towards using Gile's suggestion only because Lee's seems to incorporate some VBA(?) for which I am completly unfamiliar with. Still appreciate the help Lee! Here's a test routine I've tried to get to work: ;; blk = VLA-Object;; tag = STRing (defun c:getAtt (blk tag / att lst loop val) (setq blk (car (entsel "\n Select a block:"))) (setq att (entnext blk) lst (entget att) loop (= "ATTRIB" (cdr (assoc 0 lst))) ) (while loop (if (= (strcase tag) (cdr (assoc 2 lst))) (setq val (cdr (assoc 1 lst)) loop nil ) (setq att (entnext att) lst (entget att) loop (= "ATTRIB" (cdr (assoc 0 lst))) ) ) ) val ) When I try using the code I've pieced together so far, I get the error message "; error: too few arguments". The other part of my problem is I'm not really sure where I swap something out and replace it with the name of the attribute I want to extract. In my case, I'm trying to get the value from the attribute called DRWG. Should I replace the "tag" with "dwrg"? That doesn't seem to work. Just to clarify, the attribute name is DRWG, I'm trying to get the corresponding attribute value which would be a page number. Any ideas where I went wrong? Quote
gile Posted August 25, 2009 Posted August 25, 2009 Hi, You cant built a LISP defined command (a LISP function with the c: prefix to be called from command prompt) which requires arguments. GetAttValue is a sub routine, notice it doesn't have the c: prefix and requires two arguments. A sub routine, while it's loaded, can be used the same as a LISP native function. You can call it from whithin another function (command or sub routine). (defun c:test (/ ent) (if (setq ent (car (entsel "\nSelect a block: "))) (princ (GetAttValue ent "DRWG")) ) (princ) ) Quote
Denimoth Posted August 25, 2009 Author Posted August 25, 2009 Well, looks like I keep learning new things everyday. Thanks for clearing that up Gile. Quote
Lee Mac Posted August 25, 2009 Posted August 25, 2009 Denimoth, FYI, my routine uses Visual LISP (derived from VBA I think). For more help on Sub-Routines and such, take a read of this: http://www.afralisp.net/lispa/lisp5.htm (You may need to view it in IE if you are using Mozilla - else change the colour settings). Quote
gile Posted August 25, 2009 Posted August 25, 2009 Just want to pass over 9 messages to be allowed to post anything Quote
gile Posted August 25, 2009 Posted August 25, 2009 derived from VBA I think Not exactly "derived" both VBA (VB6) and Visual LISP use the COM / ActiveX Automation interface. Many others languages can access and use it too (.NET langages for example). Quote
Lee Mac Posted August 25, 2009 Posted August 25, 2009 Not exactly "derived" both VBA (VB6) and Visual LISP use the COM / ActiveX Automation interface.Many others languages can access and use it too (.NET langages for example). Thanks Gile for the clarification - I wasn't sure Quote
Recommended Posts
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.