Author Topic: How can I get information from block attributes???  (Read 298 times)

0 Members and 1 Guest are viewing this topic.

Hrishikesh

  • Newt
  • Posts: 35
How can I get information from block attributes???
« on: July 14, 2017, 11:35:40 am »
Hi All,
I have attributed block for Mark Numbers in my drawing containing tag "MARK"  &  "CONTROL". Control numbers are in series like 001, 002, 003, 004 etc. Where Mark number contains information like WP-001, WP-002 etc.
I use "getattributes" method to retrieve information from block, but in result it shows MarkNumber information with every control number see below.
MARK.    CTRL NO.
WP-001       001
WP-001       002
WP-001       003
WP-002       005
WP-002       011
WP-002.      029

is it possible to get Mark number once & related control numbers under that one Mark Number as below & count if possible.
MARK.       CTRL. NO
WP-001.      001
                     002
                     003
WP-002.      005
                     011
                     029

I am using lisp which i get few months ago from internet, made some changes as per my block information, lisp I am using attached for reference.

Thanks,
Hrishikesh

Code - Auto/Visual Lisp: [Select]
  1. (setq Tag "MARK")
  2. (setq Tag1 "CONTROL")
  3. (setq ss (ssget '((0 . "INSERT") (66 . 1))))
  4. (repeat (setq i (sslength ss))
  5. (setq Obj (vlax-ename->vla-object (ssname ss (setq i (1- i)))))
  6. (foreach x (append (vlax-invoke Obj 'GetAttributes)
  7.    (vlax-invoke Obj 'GetConstantAttributes)
  8.    )
  9.  (if (eq Tag (strcase (vla-get-tagstring x)))
  10.   (progn
  11.   (setq Txt (vla-get-textstring x))
  12.   (princ "\n")
  13.   (princ Txt)
  14.   )
  15.  )
  16.  (if (eq Tag1 (strcase (vla-get-tagstring x)))
  17.   (progn
  18.   (setq Txt1 (vla-get-textstring x))
  19.   (princ "\t")
  20.   (princ Txt1)
  21.   )
  22.  )
  23. )
  24. )
  25.  

MP

  • Seagull
  • Posts: 17003
  • brevity != aggression
Re: How can I get information from block attributes???
« Reply #1 on: July 14, 2017, 12:45:45 pm »
Can you post a sample dwg?
\|// Set goal. Experiment tirelessly until
|oo| practice has become expertise.  Loop.
|- | LinkedIn | Dropbox | About

Lee Mac

  • Seagull
  • Posts: 11836
  • AutoCAD 2015 Windows 7 London, England
Re: How can I get information from block attributes???
« Reply #2 on: July 14, 2017, 07:09:56 pm »
You'll need to use a technique similar to that which I describe in my tutorial here.

Here is a quick example:
Code - Auto/Visual Lisp: [Select]
  1. (defun c:test ( / av1 av2 ent enx idx itm lst sel tag tg1 tg2 tmp )
  2.  
  3.    (setq tg1 "MARK"
  4.          tg2 "CONTROL"
  5.    )
  6.  
  7.    (defun prinx ( x ) (princ "\n") (princ x))
  8.  
  9.    (if (setq sel (ssget '((0 . "INSERT") (66 . 1))))
  10.        (progn
  11.            (repeat (setq idx (sslength sel))
  12.                (setq idx (1- idx)
  13.                      ent (entnext (ssname sel idx))
  14.                      enx (entget ent)
  15.                      av1 nil
  16.                      av2 nil
  17.                )
  18.                (while
  19.                    (and
  20.                        (= "ATTRIB" (cdr (assoc 0 enx)))
  21.                        (not (and av1 av2))
  22.                    )
  23.                    (setq tag (strcase (cdr (assoc 2 enx))))
  24.                    (cond
  25.                        (   (= tg1 tag)
  26.                            (setq av1 (cdr (assoc 1 enx)))
  27.                        )
  28.                        (   (= tg2 tag)
  29.                            (setq av2 (cdr (assoc 1 enx)))
  30.                        )
  31.                    )
  32.                    (setq ent (entnext ent)
  33.                          enx (entget  ent)
  34.                    )
  35.             )
  36.                (if (and av1 av2)
  37.                    (if (setq itm (assoc av1 lst))
  38.                        (setq lst (subst (vl-list* av1 av2 (cdr itm)) itm lst))
  39.                        (setq lst (cons  (list av1 av2) lst))
  40.                    )
  41.                )
  42.            )
  43.            (prinx (LM:padbetween ""  ""  "-" 40))
  44.            (prinx (LM:padbetween tg1 tg2 " " 40))
  45.            (prinx (LM:padbetween ""  ""  "-" 40))
  46.            (foreach  itm (vl-sort lst '(lambda ( a b ) (< (car a) (car b))))
  47.                (setq tmp (vl-sort (cdr itm) '<))
  48.                (prinx (LM:padbetween (car itm) (car tmp) " " 40))
  49.                (foreach itm (cdr tmp) (prinx (LM:padbetween "" itm " " 40)))
  50.            )
  51.        )
  52.    )
  53.    (princ)
  54. )
  55.  
  56. (defun LM:padbetween ( s1 s2 ch ln )
  57.    (   (lambda ( a b c )
  58.            (repeat (- ln (length b) (length c)) (setq c (cons a c)))
  59.            (vl-list->string (append b c))
  60.        )
  61.        (ascii ch)
  62.        (vl-string->list s1)
  63.        (vl-string->list s2)
  64.    )
  65. )
  66.  

Hrishikesh

  • Newt
  • Posts: 35
Re: How can I get information from block attributes???
« Reply #3 on: July 15, 2017, 02:51:26 am »
Thanks Lee,
I will go through the tutorial & thanks for code.
You guys are really great, you have a solution for every problem in lisp programming.

Thanks,
Hrishikesh

Lee Mac

  • Seagull
  • Posts: 11836
  • AutoCAD 2015 Windows 7 London, England
Re: How can I get information from block attributes???
« Reply #4 on: July 15, 2017, 08:35:44 am »
You're welcome Hrishikesh - feel free to ask if you have any questions about the code.

MP

  • Seagull
  • Posts: 17003
  • brevity != aggression
Re: How can I get information from block attributes???
« Reply #5 on: July 15, 2017, 10:56:52 am »
If each block instance has an attribute tag named "MARK and another named "CONTROL" here's a quick & dirty potential solution ...

Code: [Select]
(defun c:Wat ( / _GetAttribData _CollateRecord _CollateRecords _Sort _Pad _Main )

    (defun _GetAttribData ( insert )
        (mapcar
            (function (lambda ( a ) (list (vla-get-tagstring a) (vla-get-textstring a))))
            (append
                (vlax-invoke insert 'GetAttributes)
                (vlax-invoke insert 'GetConstantAttributes)
            )
        )
    )

    (defun _CollateRecord ( data )
        (   (lambda ( tags )
                (apply 'append
                    (mapcar
                        (function (lambda ( tag ) (cdr (assoc tag data))))
                        tags
                    )
                )
            )
           '("MARK" "CONTROL")
        )
    )

    (defun _CollateRecords ( records new_record / key group )
        (if new_record
            (if (setq group (assoc (setq key (car new_record)) records))
                (subst (append group (cdr new_record)) group records)
                (cons new_record records)
            )
            records
        )
    )

    (defun _Sort ( records )
        (vl-sort
            (mapcar
                (function (lambda ( g ) (cons (car g) (acad_strlsort (cdr g)))))
                records
            )
            (function (lambda ( a b ) (< (car a) (car b))))
        )
    )

    (defun _Pad ( text len )
        (while (< (strlen text) len)
            (setq text (strcat text " "))
        )
        text
    )

    (defun _Main ( / ss i records len )
        (if (setq ss (ssget '((0 . "insert") (66 . 1))))
            (progn
                (vl-load-com)
                (repeat (setq i (sslength ss))
                    (setq records
                        (_CollateRecords
                            records
                            (_CollateRecord
                                (_GetAttribData
                                    (vlax-ename->vla-object
                                        (ssname ss (setq i (1- i)))
                                    )
                                )
                            )
                        )
                    )
                )
                (setq len (+ 4 (apply 'max (mapcar 'strlen (cons "MARK" (mapcar 'car records))))))
                (princ (strcat "\n" (_Pad "MARK" len) "CONTROL\n"))
                (foreach group (_Sort records)
                    (princ (strcat "\n" (_Pad (car group) len) (cadr group)))
                    (foreach item (cddr group) (princ (strcat "\n" (_Pad "" len) item)))
                    (princ "\n")
                )
            )
        )
        (princ)
    )

    (_Main)

)

Might produce something like this:

MARK      CONTROL

WP-001    001
          002
          003
          004
          005

WP-002    001
          002
          003
          004
          005

WP-003    001
          002
          003
          004
          005


Cheers.
\|// Set goal. Experiment tirelessly until
|oo| practice has become expertise.  Loop.
|- | LinkedIn | Dropbox | About

Hrishikesh

  • Newt
  • Posts: 35
Re: How can I get information from block attributes???
« Reply #6 on: July 15, 2017, 12:18:28 pm »
Thanks Michael,
for the code you share & efforts you take to write it.

Thanks,
Hrishikesh

MP

  • Seagull
  • Posts: 17003
  • brevity != aggression
Re: How can I get information from block attributes???
« Reply #7 on: July 15, 2017, 12:43:30 pm »
Truly my pleasure -- hope it works given the blind coding -- and thanks for the thanks.
\|// Set goal. Experiment tirelessly until
|oo| practice has become expertise.  Loop.
|- | LinkedIn | Dropbox | About