AaronHolmes Posted February 8, 2012 Posted February 8, 2012 Hi. I'm trying to extract two attributes from a block, roomname and roomnumber. When I get through the routine, the values of a (princ roomnumber) ;comes back as B040"B040" It's the value I want, but then repeated in double quotes. - What have I overlooked? (defun c:entitylist () ;inspired in large part by http://www.jefferypsanders.com/autolispexp_enti.html (if (setq ent(entsel "\n Select a Block: ")) ;- Let the user select a block ;;Get the attribute list and set the variables. (progn (setq en(car ent)) ;- Get the entity name of the block (setq enlist(entget en)) ;- Get the DXF group codes (setq blkType(cdr(assoc 0 enlist))) ;- Save the type of entity (if (= blkType "INSERT") ;- If the entity type is an Insert entity (progn (if(= (cdr(assoc 66 enlist)) 1) ;- See if the attribute flag equals one (if so, attributes follow) (progn (setq en2(entnext en)) ;- Get the next sub-entity (setq enlist2(entget en2)) ;- Get the DXF group codes (while (/= (cdr(assoc 0 enlist2)) "SEQEND") ;- Start the while loop and keep ;- looping until SEQEND is found. ;(princ "\n ") ;(princ (cdr(assoc 1 enlist2))) ;(princ (cdr(assoc 2 enlist2))) ;check to see if the attribute tag is the one we want, if so, set the variable. (if (= (cdr(assoc 2 enlist2)) "ROOMOBJECTS:NAME") (setq roomname (cdr(assoc 1 enlist2))) ) ;Check to see if the attribute tag is the one we want, if so, set the variable (if (= (cdr(assoc 2 enlist2)) "ROOMOBJECTS:NUMBERPROJECTBASED") (setq roomnumber (cdr(assoc 1 enlist2))) ) ;(princ "\n ") ;-Print a new line ;(princ enlist2) ;- Print the attribute DXF group codes (setq en2(entnext en2)) ;- Get the next sub-entity (setq enlist2(entget en2)) ;- Get the DXF group codes ) ) ) ;- Close the if group code 66 = 1 statement ) ) ;- Close the if block type = "ATTRIB" statement ) ) ;commented out until we can get the variables right. ;(while (setq pt (getpoint "\nPick Insertion Point:")) ; (command "-insert" "ROOMTAG.DWG" "_NON" pt "1" "1" "0" (cdr roomname) "" (cdr roomnumber) ) ) Thanks. Quote
Lee Mac Posted February 8, 2012 Posted February 8, 2012 I haven't studied the code you have posted (don't have time), but from the result you have posted, this is the correct return for the princ function. To quote the documentation: princ Prints an expression to the command line, or writes an expression to an open file. (princ [expr [file-desc]]) Arguments expr A string or AutoLISP expression. Only the specified expr is printed; no newline or space is included. file-desc A file descriptor for a file opened for writing. Return Values The value of the evaluated expr. If called with no arguments, princ returns a null symbol. Hence, when evaluating your function, princ will print the supplied expression to the command-line, then return the value of the expression. This return value is then the return value of the defun function enclosing the expressions since, defun Defines a function (defun [i]sym ([arguments] [/ variables...][/i]) expr...) Arguments sym A symbol naming the function. arguments The names of arguments expected by the function. / variables The names of one or more local variables for the function. expr Any number of AutoLISP expressions to be evaluated when the function executes. ... Return Values The result of the last expression evaluated. This behaviour is commonly used in subfunctions, take for example: (defun Add2 ( x ) (+ x 2)) _$ (Add2 5) 7 In your case: (defun PrincIt ( it ) (princ it)) _$ (PrincIt "abc") abc"abc" You see, 'abc' is printed by the princ function, then this argument is returned since it is the result of the last expression in the defun expression. However, at this point we note another characteristic of the princ function: princ ... Return Values The value of the evaluated expr. If called with no arguments, princ returns a null symbol. We can use this to our advantage to 'silence' the last expression of the defun statement: (defun PrincIt ( it ) (princ it) (princ) ) _$ (PrincIt "abc") abc The prin1 function can equally be used; in fact, this is directly noted in the function documentation: prin1 ... Return Values The value of the evaluated expr. If called with no arguments, prin1 returns a null symbol. Used as the last expression in a function, prin1 without arguments prints a blank line when the function completes, allowing the function to exit "quietly." Not sure how to access the help? See here. Hope this helps, Lee Quote
AaronHolmes Posted February 9, 2012 Author Posted February 9, 2012 Hi Lee, Thanks for your extensive reply. In particular, the VLIDE and the help documentation will be particularly useful. As you might have suspected, I"m new at this, and heretofore my development environment of choice was 'notepad'. Your generosity with comments on this site, as well as the resources on your website have been of tremendous help to me in getting started and nearly functional with autolisp to make my cad life easier. Thanks for all that you do. Once I get the double attribute reference solved I'll post the code here. Regards, Aaron. Quote
Lee Mac Posted February 9, 2012 Posted February 9, 2012 Thanks for your extensive reply. In particular, the VLIDE and the help documentation will be particularly useful. As you might have suspected, I"m new at this, and heretofore my development environment of choice was 'notepad'. For LISP or DCL, the VLIDE would definitely be my choice of editor (for almost everything else I use Notepad++), for one, you have direct access to the LISP Help Documentation (and, if you are using a version of AutoCAD pre 2011, a reference for the ActiveX properties and methods); and two, you have far superior debugging capabilities for AutoLISP than any other editor I know of (I've written a short tutorial surrounding this topic, here). There are also all sorts of formatting tricks (offered by most code editors) and shortcuts. Your generosity with comments on this site, as well as the resources on your website have been of tremendous help to me in getting started and nearly functional with autolisp to make my cad life easier. Thanks for all that you do. That's very kind of you to say - I enjoy writing the code and programs, so I'm glad that my posts are of benefit to those learning. Lee Quote
AaronHolmes Posted February 10, 2012 Author Posted February 10, 2012 (defun c:RTG ( / ipt ROOMNAME ROOMNUMBER) ;inspired in large part by http://www.jefferypsanders.com/autolispexp_enti.html ; The While command with no exit conditions lets you do this over and over again without restarting the command. (while (if (setq ent(entsel "\n Select a Block: ")) ;- Let the user select a block ;;Get the attribute list and set the variables. (progn (setq en(car ent)) ;- Get the entity name of the block (setq enlist(entget en)) ;- Get the DXF group codes (setq blkType(cdr(assoc 0 enlist))) ;- Save the type of entity (setq ipt (cdr (assoc 10 enlist))) ;get insertion point of block, for use later during insert (if (= blkType "INSERT") ;- If the entity type is an Insert entity (progn (if(= (cdr(assoc 66 enlist)) 1) ;- See if the attribute flag equals one (if so, attributes follow) (progn (setq en2(entnext en)) ;- Get the next sub-entity (setq enlist2(entget en2)) ;- Get the DXF group codes (while (/= (cdr(assoc 0 enlist2)) "SEQEND") ;- Start the while loop and keep ;- looping until SEQEND is found. ;check to see if the attribute tag is the one we want, if so, set the variable. (if (= (cdr(assoc 2 enlist2)) "[THE ROOM NAME ATTRIBUTE FROM THE OLD BLOCK") (setq roomname (assoc 1 enlist2)) ) ;Check to see if the attribute tag is the one we want, if so, set the variable (if (= (cdr(assoc 2 enlist2)) "THE ROOM NUMBER ATTRIBUTE NAME FROM THE OLD BLOCK") (setq roomnumber (assoc 1 enlist2)) ) (princ) group codes (setq en2(entnext en2)) ;- Get the next sub-entity (setq enlist2(entget en2)) ;- Get the DXF group codes ) ) ) ;- Close the if group code 66 = 1 statement ) ) ;- Close the if block type = "ATTRIB" statement ) ) (command "-insert" "ROOMTAG.DWG" "_NON" ipt "1" "1" "0" (CDR ROOMNAME) "" (CDR ROOMNUMBER)) ;delete the original block (entdel en) );close the While loop (princ) ) In operation, I need to go around and pick each block I want to change this way. Much improved from the original way, but how could I group select all the blocks, then run this on each of them in turn? Thanks! -Aaron. 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.