Prickle Farmer Posted October 2, 2013 Share Posted October 2, 2013 I have a need to get the Prompt string (DXF code 3) from any given block with attributes. I can access the "tag" which is part of the attribute but the Prompt belongs to the attribute definition, not the attribute. Does anyone know how to get to this value using LISP? Quote Link to comment Share on other sites More sharing options...
LibertyOne Posted October 2, 2013 Share Posted October 2, 2013 Maybe these DXF codes will help: 3 = Promt string 2 = Tag string 70 = Attributte flags 1 = Attribute is invisible (does not appear). 2 = This is a constant attribute. 4 = Verification is required on input of this attribute. 8 = Attribute is preset (no prompt during insertion). Taken from here: http://www.autodesk.com/techpubs/autocad/acadr14/dxf/attdef_al_u05_c.htm There are two different entities. ATTDEF and ATTRIB depending what info you want to extract. Quote Link to comment Share on other sites More sharing options...
Tharwat Posted October 2, 2013 Share Posted October 2, 2013 If I got you well , you need to check for group 1 in DXF for the text string Quote Link to comment Share on other sites More sharing options...
Prickle Farmer Posted October 2, 2013 Author Share Posted October 2, 2013 Perhaps I should explain in more detail what I am trying to do. I am aware of ATTRIB and ATTDEF. We have to submit a drawing to an Authority using their block definitions with their attributes. They have used a naming convention where a mandatory attribute has a prompt with a trailing "*" (asterisk). For each block reference (INSERT) in the drawing I would like to parse each attribute looking for a prompt (DXF code 3) with a blank value. This will enable the user to alerted to mandatory fields with no data. When I ssget all the INSERTs I can access the ATTRIB but I'm not sure how to get to the ATTDEF that has DXF code 3 (Prompt). You see??? Quote Link to comment Share on other sites More sharing options...
LibertyOne Posted October 2, 2013 Share Posted October 2, 2013 Ah! I get it. What you have to do is access the nested ATTDEF object. Not the INSERT itself. For example, one of the blocks you may have is made up of many nested items (LINE, CIRCLE, ATTDEF, etc.). You have to step though all these nested objects until you get to one or more of ATTDEF objects that have a prompt with an "*" refering to a manditory imput. Then you need to remember the name of the ATTDEF objects that have these and then check if your ATTRIB fields have an empty string or not. Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted October 2, 2013 Share Posted October 2, 2013 If I have understood correctly, the following example will print a list of data pertaining to attribute references (ATTRIBs) whose prompt string ends with an asterisk and whose content is empty: (defun c:attalert ( / blk ent enx idx itm lst pmt rtn sel ) (if (setq sel (ssget "_X" '((0 . "INSERT") (66 . 1)))) (repeat (setq idx (sslength sel)) (setq ent (ssname sel (setq idx (1- idx))) blk (cdr (assoc 2 (entget ent))) ent (entnext ent) enx (entget ent) ) (if (null (setq itm (cdr (assoc blk lst)))) (setq itm (getattdata blk) lst (cons (cons blk itm) lst) ) ) (while (= "ATTRIB" (cdr (assoc 0 enx))) (if (and (= "" (cdr (assoc 1 enx))) (wcmatch (setq pmt (cdr (assoc (cdr (assoc 2 enx)) itm))) "*`*") ) (setq rtn (cons (list (cdr (assoc 10 enx)) (cdr (assoc 2 enx)) pmt) rtn)) ) (setq ent (entnext ent) enx (entget ent) ) ) ) ) (mapcar 'print rtn) (princ) ) (defun getattdata ( blk / ent enx lst ) (if (setq ent (tblobjname "block" blk)) (while (setq ent (entnext ent)) (if (= "ATTDEF" (cdr (assoc 0 (setq enx (entget ent))))) (setq lst (cons (cons (cdr (assoc 2 enx)) (cdr (assoc 3 enx)) ) lst ) ) ) ) ) lst ) (princ) The printed list contains the attribute reference insertion point, tag string, and prompt string. I hope this helps! Quote Link to comment Share on other sites More sharing options...
Prickle Farmer Posted October 2, 2013 Author Share Posted October 2, 2013 Wow. While I slept quietly you have worked away tirelessly for the solution. You have hit the nail on the head with one command, "tblobjname". This is what I was looking for, which gives me access to the nested block reference in the header section of the database. I should be fine from here!! Thanks heaps. Quote Link to comment Share on other sites More sharing options...
Prickle Farmer Posted October 3, 2013 Author Share Posted October 3, 2013 Hi Lee Mac Your code has pointed me in the right direction. My app is running fine now. I found a little bug in your code: (wcmatch (setq pmt (cdr (assoc (cdr (assoc 2 enx)) itm))) "*`*") should read (wcmatch (setq pmt (cdr (assoc (cdr (assoc 2 enx)) itm))) "*\*") It was the backslash for the literal string. Just a typo!! Quote Link to comment Share on other sites More sharing options...
Prickle Farmer Posted October 3, 2013 Author Share Posted October 3, 2013 My apologies. The reverse quote IS for literals in this sense. Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted October 3, 2013 Share Posted October 3, 2013 Wow. While I slept quietly you have worked away tirelessly for the solution. Thanks - it was only a quick draft You have hit the nail on the head with one command, "tblobjname". This is what I was looking for, which gives me access to the nested block reference in the header section of the database. Yes, the tblobjname function is the key to accessing block definition entities in Vanilla AutoLISP. Though to clarify, this function will return the BLOCK entity (AcDbBlockBegin), which is the header of the block definition. This is not a nested block reference (known as an INSERT). Note also that the entity returned by the tblobjname function differs from the object returned when retrieving the same block definition from the Block Collection through Visual LISP via the vla-item method - this method will return the VLA-object representation of the BLOCK_RECORD entity (AcDbBlockTableRecord), which is the parent of the BLOCK entity. To better explain, below is the entity hierarchy of a block definition as it appears in the Block Table: +-- [color=darkred]TABLE[/color] ([color=navy]AcDbBlockTable[/color]) | +--+-- [color=darkred]BLOCK_RECORD[/color] ([color=navy]AcDbBlockTableRecord[/color]) | +--+-- [color=darkred]BLOCK[/color] ([color=navy]AcDbBlockBegin[/color]) | +-- [i][color=green]< Block Geometry Entity >[/color][/i] | +-- [i][color=green]< Block Geometry Entity >[/color][/i] | ... | +-- [i][color=green]< Block Geometry Entity >[/color][/i] | +-- [color=darkred]ENDBLK[/color] Quote Link to comment Share on other sites More sharing options...
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.