Author Topic: Extract an attribute value from a block  (Read 12483 times)

0 Members and 1 Guest are viewing this topic.

diarmuid

  • Bull Frog
  • Posts: 417
Extract an attribute value from a block
« on: November 05, 2010, 06:02:24 AM »
I have 300 titleblocks that have a drawing number in them.  These titleblocks do not match the actual filename. I been asked to save the drawing as the drawing number in the titleblock which is an attribute.  no, my lisp is not great but i am trying to lift this info via an ssget funtion


so

(setq ax1 (ssget "x"  (100 . "AcDbAttribute") (2 . "DRAWING_NO")))

Where the "DRAWING_NO" is the actual value i will assign to a value and get lisp to do a "save as" to another location

Diarmuid
If you want to win something run the 100m, if you want to experience something run a marathon

David Bethel

  • Swamp Rat
  • Posts: 656
Re: Extract an attribute value from a block
« Reply #1 on: November 05, 2010, 06:21:33 AM »
You can't ssget attributes like you can other entities.  You will need to make a pickset of the titleblock inserts, and then step thru the set looking for the tagname of the attribute

This could be a starting point:

Code: [Select]

(defun c:ps-tagvl (/ tag val ps i ss en an ad)

  (while (or (not tag)
             (not (snvalid tag)))
         (setq tag (strcase (getstring "\nTag Name:   "))))

  (while (not val)
         (setq val (strcase (getstring t "\nAttrib Value ( Not Case Sensitive) :   "))))

  (and (setq ps (ssadd)
              i -1
             ss (ssget "X" '((0 . "INSERT")(2 . "TITLEBLOCK")(66 . 1))))
       (setq en (ssname ss (setq i (1+ i)))
             an (entnext en)
             ad (entget an))
       (while (= "ATTRIB" (cdr (assoc 0 ad)))
              (and (= tag (strcase (cdr (assoc 2 ad))))
                   (= val (strcase (cdr (assoc 1 ad))))
                   (not (ssmemb en ps))
                   (ssadd en ps))
              (setq an (entnext an)
                    ad (entget an))))
  (eval ps))

This make a pickset ( ps ) of matching tagnames and attribute values.  -David
R12 Dos - A2K

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Extract an attribute value from a block
« Reply #2 on: November 05, 2010, 06:32:01 AM »
Just for something different to play with ..
Code: [Select]

(setq Border-Number-Attribute-Value (cdr (assoc 1 (entget (car (nentsel "Select File Number Attribute"))))))


This should return the value of the attribute you select.
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Extract an attribute value from a block
« Reply #3 on: November 05, 2010, 06:41:40 AM »

.. or if all the borders have the same name and ate attribute is always named "DRAWING_NO"
there is an easier way.

What is the border block name ??
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

diarmuid

  • Bull Frog
  • Posts: 417
Re: Extract an attribute value from a block
« Reply #4 on: November 05, 2010, 07:06:58 AM »
thanks for the replies guys,

The tileblock name is (for all of them)

amw_title

Thanks

again, i was clearly barking up the wrong tree  :laugh:
If you want to win something run the 100m, if you want to experience something run a marathon

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Extract an attribute value from a block
« Reply #5 on: November 05, 2010, 07:08:48 AM »
.. for instance :

Code: [Select]
;; Library code
;;
(defun getattributes (objselection)
  (if (= (type objselection) 'ename)
    (setq objselection (vlax-ename->vla-object objselection))
  )
  (if (= (vla-get-hasattributes objselection) :vlax-true)
    (mapcar
      '(lambda (x) (cons (vla-get-tagstring x) (vla-get-textstring x)))
      (vlax-safearray->list (variant-value (vla-getattributes objselection)))
    )
  )
)

Test Code

Code: [Select]


(defun c:doit ()
  (setq Block-Name     "amw_title"
        Attribute-Name "DRAWING_NO"
  )
  (if (and (setq Border-Blocks (ssget "X" (list (cons 2 Block-Name))))
           (setq Attribute-List (getattributes (ssname Border-Blocks 0)))
           (setq Attribute-Value (cdr (assoc Attribute-Name Attribute-List)))
      )
    (progn (alert Attribute-Value)
           ;; .. save the drawing with the contents of Attribute-Value
    )
  )
)

kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Extract an attribute value from a block
« Reply #6 on: November 05, 2010, 07:40:06 AM »

of course, I'm not suggesting for a moment that David's solution is anything other than perfect :)

.. this is just another way to skin the problem.
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

Lee Mac

  • Seagull
  • Posts: 12926
  • London, England
Re: Extract an attribute value from a block
« Reply #7 on: November 05, 2010, 07:42:07 AM »
To save processing all attributes, I would sometimes use this:

Code: [Select]
;;----------------=={ Get Attribute Value }==-----------------;;
;;                                                            ;;
;;  Returns the attribute value associated with the specified ;;
;;  tag, within the supplied block, if present.               ;;
;;------------------------------------------------------------;;
;;  Author: Lee McDonnell, 2010                               ;;
;;                                                            ;;
;;  Copyright © 2010 by Lee McDonnell, All Rights Reserved.   ;;
;;  Contact: Lee Mac @ TheSwamp.org, CADTutor.net             ;;
;;------------------------------------------------------------;;
;;  Arguments:                                                ;;
;;  block - VLA Block Reference Object                        ;;
;;  tag   - Attribute TagString                               ;;
;;------------------------------------------------------------;;
;;  Returns:  Attribute TextString, else nil                  ;;
;;------------------------------------------------------------;;

(defun LM:GetAttributeValue ( block tag )
  ;; © Lee Mac 2010
  (vl-some
    (function
      (lambda ( attrib )
        (if (eq tag (vla-get-Tagstring attrib))
          (vla-get-TextString attrib)
        )
      )
    )
    (vlax-invoke block 'GetAttributes)
  )
)

Example:

Code: [Select]
(defun c:test ( / ent )
  
  (if (setq ent (car (entsel "\nSelect Attributed Block: ")))
    (princ
      (LM:GetAttributeValue
        (vlax-ename->vla-object ent) (strcase (getstring "\nSpecify Tag String: "))
      )
    )
  )

  (princ)
)

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Extract an attribute value from a block
« Reply #8 on: November 05, 2010, 07:45:18 AM »
Lee
If you're going to ask the user for input
ie
(entsel "\nSelect Attributed Block: ")
and
(getstring "\nSpecify Tag String: "))

it would be much better to just use Nentsel as per my first example.
.. a simple one liner.
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

Lee Mac

  • Seagull
  • Posts: 12926
  • London, England
Re: Extract an attribute value from a block
« Reply #9 on: November 05, 2010, 07:53:04 AM »
Lee
If you're going to ask the user for input
ie
(entsel "\nSelect Attributed Block: ")
and
(getstring "\nSpecify Tag String: "))

it would be much better to just use Nentsel as per my first example.
.. a simple one liner.

'Twas purely example code to show how to call the function - it could be used without any user input at all :-)

diarmuid

  • Bull Frog
  • Posts: 417
Re: Extract an attribute value from a block
« Reply #10 on: November 05, 2010, 08:16:20 AM »
Thanks for the input guy's really appreciate it.

When i run the code i get

Select Attributed Block: ; error: no function definition: VLAX-ENAME->VLA-OBJECT

thanks for this, it been Friday n'all

Diarmuid
If you want to win something run the 100m, if you want to experience something run a marathon

diarmuid

  • Bull Frog
  • Posts: 417
Re: Extract an attribute value from a block
« Reply #11 on: November 05, 2010, 08:20:37 AM »
hold the phone, i see now where i screwed up!!!!!

that'll learn me :ugly:
If you want to win something run the 100m, if you want to experience something run a marathon

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Extract an attribute value from a block
« Reply #12 on: November 05, 2010, 11:49:06 AM »
If you don't mind losing the preview of the drawing, then you can do something like this ( not tested, but should work, so test before ).

Code: [Select]
(function
    (lambda ( x / BlkName AttTag DwgName OldPath )
       
        (setq BlkName "EnterBlockName")
        (setq AttTag "EnterAttributeTag")
       
        (vlax-for lo (vla-get-Layouts x)
            (vlax-for obj (vla-get-Block lo)
                (if
                    (and
                        (= (vla-get-ObjectName obj) "AcDbBlockReference")
                        (= (vla-get-Name obj) BlkName)
                    )
                    (foreach att (vlax-invoke obj 'GetAttributes)
                        (if (= (vla-get-TagString att) AttTag)
                            (setq DwgName (vla-get-TextString att))
                        )
                    )
                )
            )
        )
        (if DwgName
            (progn
                (setq OldPath (vla-get-Name x))
                (vla-SaveAs x (strcat (vl-filename-directory OldPath) DwgName ".dwg"))
                (vl-file-delete OldPath)
            )
        )
    )
)

In-conjunction with one of these.
[ http://www.theswamp.org/index.php?topic=29933.0 ] - by me
[ http://www.theswamp.org/index.php?topic=31827.0 ] - by Lee
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

MPD

  • Mosquito
  • Posts: 5
Re: Extract an attribute value from a block
« Reply #13 on: June 01, 2022, 01:55:09 AM »
lee its a great lisp
Is there a way to export the value as a field?

To save processing all attributes, I would sometimes use this:

Code: [Select]
;;----------------=={ Get Attribute Value }==-----------------;;
;;                                                            ;;
;;  Returns the attribute value associated with the specified ;;
;;  tag, within the supplied block, if present.               ;;
;;------------------------------------------------------------;;
;;  Author: Lee McDonnell, 2010                               ;;
;;                                                            ;;
;;  Copyright © 2010 by Lee McDonnell, All Rights Reserved.   ;;
;;  Contact: Lee Mac @ TheSwamp.org, CADTutor.net             ;;
;;------------------------------------------------------------;;
;;  Arguments:                                                ;;
;;  block - VLA Block Reference Object                        ;;
;;  tag   - Attribute TagString                               ;;
;;------------------------------------------------------------;;
;;  Returns:  Attribute TextString, else nil                  ;;
;;------------------------------------------------------------;;

(defun LM:GetAttributeValue ( block tag )
  ;; © Lee Mac 2010
  (vl-some
    (function
      (lambda ( attrib )
        (if (eq tag (vla-get-Tagstring attrib))
          (vla-get-TextString attrib)
        )
      )
    )
    (vlax-invoke block 'GetAttributes)
  )
)

Example:

Code: [Select]
(defun c:test ( / ent )
 
  (if (setq ent (car (entsel "\nSelect Attributed Block: ")))
    (princ
      (LM:GetAttributeValue
        (vlax-ename->vla-object ent) (strcase (getstring "\nSpecify Tag String: "))
      )
    )
  )

  (princ)
)