Pull Attribute Value from a block

400 views Asked by At

I'm trying to pull the attribute value out of a block but I'm hitting a bit of a wall. The block's name is fixed (ShtScale), the attribute tag is also fixed (Scale), but I'm not sure what functions I would use to pull this information out as I don't know how its stored. To make this a bit more tricky, I can't use any of the VL, VLA, or VLAX functions as this is part of a larger routine that I run thru accoreconsole and it won't accept any of those (even after loading the acapp.arx). This also means I can't use any user prompts, but I don't really see as being too big of an issue as the block name and att value are both 100% fixed and always will be for the purpose of this function. So far the only snipped of code I've gotten to is:

(setq blk (ssget "_X" '((0 . "INSERT") (2 . "ShtScale") (410 . ltab))))

But this brings up issue 2 that I've hit a wall with, which is how to pass the layout tab name of the current layout tab to the selection set. I've tried this:

(setq ltab (getvar "ctab"))

But what gets set to the "ltab" variable isn't useable in the selection set filter as I'm currently using it and I don't understand why.

Ideally the information it should pull from the block is: "1/8" = 1'-0""

3

There are 3 answers

0
Dustin On

Lee Mac, thank you for your response as well as commenting each line. I tinkered around with it a little bit after I posted yesterday and found a solution to pull the block attribute value:

(setq blk (ssget "_x" '((0 . "INSERT") (2 . "SHTSCALE"))))
(setq ent (entget (ssname blk 0)))
(setq en (cdr (car ent)))
(setq en2 (entnext en))
(setq enlist2 (entget en2))
(setq blkscale (cdr (assoc 1 enlist2)))
(setq blkscale (car blkscale))

What I don't get is why I wasn't able to pull the DXF group code "1", which held the block attribute definition, until this line here:

(setq enlist2 (entget en2))

I typically use this little code to quickly look at group code information but its making we wonder if its not pulling in as much DXF info as it could be:

(defun c:info (/ ent targent)
   (setq ent (car (entsel)))
   (setq targent (entget ent))
   )
0
gileCAD On

You can get an attribute 'value' more directly with the getpropertyvalue function which consider the attribute tag as a property.

(setq val (getpropertyvalue ent "Scale")
0
Lee Mac On

The reason that your variable ltab is not being evaluated within the ssget filter list is due to the use of the apostrophe, which quotes the list as literal data (i.e. not to be evaluated). You can find more information about the use of the apostrophe and quote function by reading my tutorial here.

To evaluate the ltab variable, you'll need to construct the ssget filter list using the list and cons functions, e.g.:

(setq blk (ssget "_X" (list '(0 . "INSERT") '(2 . "ShtScale") (cons 410 ltab))))

Here, the literal data remains quoted, but the ltab variable will be evaluated when the cons expression is evaluated to return a dotted pair.

I should note that if your target block is dynamic, you'll also need to include anonymous block references in the selection set, otherwise dynamic block references with the target block name whose dynamic parameters have been modified will be ignored.

You'll then need to iterate over the selection set to operate on each block reference entity individually. There are many ways to do this. Personally, I like to opt for a basic repeat loop, e.g.

(repeat (setq idx (sslength blk))
    (setq idx (1- idx)
          ent (ssname blk idx)
    )
)

Attribute references held by a block reference will follow the block reference entity in the drawing database, until a terminating SEQEND entity is reached. With this information, you can use the entnext function to iterate over the drawing database records following the block reference entity, until you reach a SEQEND entity.

Here is a basic example of this:

(repeat (setq idx (sslength blk))
    (setq idx (1- idx)
          ent (ssname blk idx)
    )

    (setq att (entnext ent) ;; ATTRIB entity
          atx (entget  att) ;; ATTRIB DXF data
    )
    (while (= "ATTRIB" (cdr (assoc 0 atx))) ;; While we have an ATTRIB
        (if (= "SCALE" (cdr (assoc 2 atx))) ;; If we've reached our target ATTRIB
            (setq val (cdr (assoc 1 atx)))  ;; Obtain the ATTRIB value
        )
        (setq att (entnext att) ;; Get next entity
              atx (entget  att) ;; Get DXF data for next entity
        )
    )
)

Here, the attribute value for each block reference will be held by the val variable.