TheSwamp

Code Red => AutoLISP (Vanilla / Visual) => Topic started by: V-Man on January 26, 2012, 04:24:03 PM

Title: Block Attribute (null) value
Post by: V-Man on January 26, 2012, 04:24:03 PM

I need to search for a particular block name and once found check to see if the attribute is null. If so, I want to delete the block(s) for all instances in the drawing. If the attribute is "filled" in with a value then leave those blocks alone. Any simple code out there to accomplish?

Thnx.
Title: Re: Block Attribute (null) value
Post by: alanjt on January 26, 2012, 04:32:17 PM
Quick and untested...

Code: [Select]
(defun _EraseBlockReferencesWithNullAttributeValue (blockname attributetag / ss i e)
  (if (setq ss (ssget "_X" (list '(0 . "INSERT") '(66 . 1) (cons 2 blockname))))
    (repeat (setq i (sslength ss))
      (if
        (vl-some
          (function (lambda (a)
                      (and (eq (strcase (vla-get-tagstring a)) (strcase attributetag))
                           (eq (vla-get-textstring a) "")
                      )
                    )
          )
          (vlax-invoke (vlax-ename->vla-object (setq e (ssname ss (setq i (1- i))))) 'GetAttributes)
        )
         (entdel e)
      )
    )
  )
  (princ)
)
Title: Re: Block Attribute (null) value
Post by: CAB on January 26, 2012, 04:36:19 PM
Quote
for all instances in the drawing

Does that include inserts where one insert has a null attribute but another of the same name does not?
Title: Re: Block Attribute (null) value
Post by: ronjonp on January 26, 2012, 04:43:24 PM
Code: [Select]
[quote author=alanjt link=topic=40781.msg460478#msg460478 date=1327613537]
Quick and untested...

...
[/quote]

Nice  8-)
Title: Re: Block Attribute (null) value
Post by: V-Man on January 26, 2012, 04:52:42 PM

Quote
Does that include inserts where one insert has a null attribute but another of the same name does not?


Yes
Title: Re: Block Attribute (null) value
Post by: irneb on January 27, 2012, 12:46:46 AM
Pure AutoLisp (no VisualLisp calls):
Code: [Select]
(defun _EraseBlockReferencesWithNullAttributeValue_A (blockname attributetag / ss n en an ad ToErase)
  (if (setq ss (ssget "_X" (list '(0 . "INSERT") '(66 . 1) (cons 2 blockname))))
    (progn
      (setq n (sslength ss))
      (while (> (setq n (1- n)) -1)
        (setq en      (ssname ss n)
              ToErase nil
              ad      (entget (setq an (entnext en)))
        )
        (while (and (not ToErase) (eq (cdr (assoc 0 ad) "ATTRIB")))
          (setq ToErase (and (eq (cdr (assoc 2 ad)) attributetag) (eq (cdr (assoc 1 ad)) ""))
                ad      (entget (setq an (entnext an)))
          )
        )
        (if ToErase (entdel en))
      )
    )
  )
)
Also "quick & untested".  :|
Title: Re: Block Attribute (null) value
Post by: V-Man on January 27, 2012, 07:34:03 AM

ok, how do I call it?
Title: Re: Block Attribute (null) value
Post by: mjfarrell on January 27, 2012, 08:01:00 AM

ok, how do I call it?
1 888 THE SWAMP
Title: Re: Block Attribute (null) value
Post by: V-Man on January 27, 2012, 10:24:16 AM

Code: [Select]
(defun _EraseBlockReferencesWithNullAttributeValue (blockname attributetag / ss i e)
  (if (setq ss (ssget "_X" (list '(0 . "INSERT") '(66 . 1) (cons 2 blockname))))
    (repeat (setq i (sslength ss))
      (if
        (vl-some
          (function (lambda (a)
                      (and (eq (strcase (vla-get-tagstring a)) (strcase attributetag))
                           (eq (vla-get-textstring a) "")
                      )
                    )
          )
          (vlax-invoke (vlax-ename->vla-object (setq e (ssname ss (setq i (1- i))))) 'GetAttributes)
        )
         (entdel e)
      )
    )
  )
  (princ)
)


Thanks, This works great!
Title: Re: Block Attribute (null) value
Post by: irneb on January 30, 2012, 12:34:32 AM
ok, how do I call it?
Same way as you do with Alan's code, the function name simply has a _A suffix to differentiate it from Alan's.

1 888 THE SWAMP
Is that true? I didn't know there was a hotline!  :lmao:
Title: Re: Block Attribute (null) value
Post by: Pad on February 08, 2012, 01:31:43 PM
Nice lisp

I've been trying to make a couple of edits, so that instead of erasing the selection set it instead moves them to a defined layer.
The first bit was easy, the second bit is easy as long as the layer exists in the drawing.  So I have been trying to add code to check existence and make the layer if necessary but have ended up with a syntax error.

the first bit is this:
Code - Auto/Visual Lisp: [Select]
  1. ;         (entdel e)
  2.     (command  "_.CHPROP" e "" "_LA" "Clashing-Null" "")

and this is the code i have been trying to integrate:
Code - Auto/Visual Lisp: [Select]
  1. (if (not (tblsearch "LAYER" "CLASHING-Null")) (command "LAYER" "N" "CLASHING-Null" ""))
  2.  
  3.     (command "layer" "F" "CLASHING_LEVELS" ^C)
  4.  
  5.     (command ".-layer" "c" "6" "CLASHING_LEVELS" "")

could some one please show me the correct place to put this code?

Also whilst I'm at it, it would be great is the selection set would filter out any blocks which are already on any layers  prefixed with 'clashing-' beforehand.

Thanks
P
Title: Re: Block Attribute (null) value
Post by: irneb on February 09, 2012, 06:49:47 AM
You mean like this?
Code: [Select]
(defun _EraseBlockReferencesWithNullAttributeValue_A (blockname attributetag / ss n en ed an ad ToErase)
  (if (not (tblsearch "LAYER" "CLASHING-Null"))    (command "LAYER" "N" "CLASHING-Null" "")  )  (command "layer" "F" "CLASHING_LEVELS" ^C)  (command ".-layer" "c" "6" "CLASHING_LEVELS" "")

  (if (setq ss (ssget "_X"
                      (list '(0 . "INSERT") '(66 . 1) (cons 2 blockname) '(8 . "~CLASHING-*"))
               )
      )
    (progn
      (setq n (sslength ss))
      (while (> (setq n (1- n)) -1)
        (setq en      (ssname ss n)
              ed (entget en)
              ToErase nil
              ad      (entget (setq an (entnext en)))
        )
        (while (and (not ToErase) (eq (cdr (assoc 0 ad)) "ATTRIB"))
          (setq ToErase (and (eq (cdr (assoc 2 ad)) attributetag) (wcmatch (cdr (assoc 1 ad)) ""))
                ad      (entget (setq an (entnext an)))
          )
        )
        (if ToErase
          ;; (entdel en)
          (entmod (subst '(8 . "CLASHING-Null") (assoc 8 ed) ed))
        )
      )
    )
  )
)
Title: Re: Block Attribute (null) value
Post by: irneb on February 09, 2012, 06:58:54 AM
Or if you prefer alan's VL code, here's a slight optimization of his as well as including your changes:
Code: [Select]
(vl-load-com)

(defun _EraseBlockReferencesWithNullAttributeValue (blockname attributetag / ss)
  (if (not (tblsearch "LAYER" "CLASHING-Null"))
    (command "LAYER" "N" "CLASHING-Null" "")
  )
  (command "layer" "F" "CLASHING_LEVELS" ^C)
  (command ".-layer" "c" "6" "CLASHING_LEVELS" "")
  (setq blockname    (strcase blockname)
        attributetag (strcase attributetag)
  )

  (if (and (ssget "_X"
                  (list '(0 . "INSERT") '(66 . 1) (cons 2 blockname) '(8 . "~[Cc][Ll][Aa][Ss][Hh][Ii][Nn][Gg]-*"))
           )
           (setq ss (vla-get-ActiveSelectionSet (vla-get-ActiveDocument (vlax-get-acad-object))))
      )
    (progn
      (vlax-for e ss
        (if (vl-some (function (lambda (a)
                                 (and (eq (strcase (vla-get-TagString a)) attributetag)
                                      (eq (vla-get-TextString a) "")
                                 )
                               )
                     )
                     (vlax-invoke (vlax-ename->vla-object (setq e (ssname ss (setq i (1- i))))) 'GetAttributes)
            )
          (vla-put-Layer e "CLASHING-Null")
        )
      )
      (vla-Delete ss)
    )
  )
  (princ)
)
Title: Re: Block Attribute (null) value
Post by: Pad on February 10, 2012, 06:01:58 AM
thanks Irneb.  Thats brilliant.

Your version works perfectly but your version of Alan's errors:

Command: (_EraseBlockReferencesWithNullAttributeValue "PD" "LEVEL")
bad argument type: numberp: nil
Command: (_EraseBlockReferencesWithNullAttributeValue_A "PD" "LEVEL")
nil

I don't know why.
Thanks!

P  :-)