Visual LISP, AutoLISP and General Customization
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Change block layers based on Attribute Name tags

9 REPLIES 9
SOLVED
Reply
Message 1 of 10
Anonymous
1219 Views, 9 Replies

Change block layers based on Attribute Name tags

What I am trying to do is grab the value of the owner tag (of which there are four), and use that value to determine which layer to place it on.  What it seems to be doing is hanging.

 

Here is what I have so far:

(setq SSBlks (ssget "x"'((0 . "*INSERT"))))
(while (/= (sslength SSBlks) 0)
(setq w(sslength SSBlks) V 0)
(setq attentity (ssname SSBlks 0))
(setq attname (entget attentity))
(setq cntr 0)
(while (< V cntr)
(setq layername (entnext (cdr (assoc -1 attname))))
(setq attname(entget layername))
(setq tempname(assoc 2 attname))
(if (= (cdr (assoc 2 attname)) "OWNER")
(progn
(setq oldname (assoc 1 attname))
(If (= oldname "*GRBM*")
(progn
(setq newv (entget attentity))
(setq newv (subst (cons 8 "GRADE BEAM") (assoc 8 newv)newv))
(entmod newv)))
(If (= oldname "*PILE*")
(progn
(setq newv (entget attentity))
(setq newv (subst (cons 8 "STEEL-HD") (assoc 8 newv)newv))
(entmod newv)))
(If (= oldname "*PCAP*")
(progn
(setq newv (entget attentity))
(setq newv (subst (cons 8 "SPREAD FOOTING") (assoc 8 newv)newv))
(entmod newv)))
(If (= oldname "*GL*")
(progn
(setq newv (entget attentity))
(setq newv (subst (cons 8 "GRIDLINE") (assoc 8 newv)newv))
(entmod newv)))
(setq cntr (1+ cntr))
))))

9 REPLIES 9
Message 2 of 10
Kent1Cooper
in reply to: Anonymous


@Anonymous wrote:

What I am trying to do is grab the value of the owner tag (of which there are four), and use that value to determine which layer to place it on.  What it seems to be doing is hanging.

 

....

(setq w(sslength SSBlks) V 0)
....

(setq cntr 0)
(while (< V cntr)
....
(setq cntr (1+ cntr))
....


I don't know what your V variable is intended for, but I think that's where the problem is.  V and cntr both start at 0, and cntr gets increased, but V doesn't get changed.  Right from the start, V is not less than cntr, so it won't do anything in that (while) function that's checking whether it is less.

 

I would also recommend using (cond) for the four possibilities, rather than four (if) functions.  As you have it, even after it has found the "right" one and done its thing, it still has to check whether any of the other situations are "right" [which none of them will be].  But with (cond), as soon as it finds the "right" one, it ignores the rest.  It also lets you do multiple things within each possible condition without needing to wrap them in (progn), as you need to when they're collectively an (if) function's 'then' argument.

Kent Cooper, AIA
Message 3 of 10
pbejse
in reply to: Anonymous

Are you wanting to chagne the layer of the block itself?

 

It appears that after a succesful match with a an attribtue TAG you are trying to use attribute string value for comparison

 

(setq oldname (assoc 1 attname)<---- but this will give you a list and not a string value

(= oldname "*GBRN*) <--- will always be nil as you are comparing a list with a string value

 

Try this:

 

(defun c:BTL (/ SSBlks i ent TarAtt AttVal)
  (if (setq SSBlks (ssget "x" '((0 . "*INSERT") (66 . 1))))
	  (repeat (setq i (sslength SSBlks))
	    (setq ent (ssname SSBlks (setq i (1- i))))
	    (if	(and (setq TarAtt (assoc "OWNER"
					 (mapcar '(lambda (j)
						    (list (vla-get-tagstring j)
							  (vla-get-textstring j)
						    )
						  )
						 (vlax-invoke
						   (vlax-ename->vla-object ent)
						   'GetAttributes
						 )
					 )
				  )
		     )
		     (setq AttVal (member (cadr TarATT)
					  '("*GRBM*"	    "GRADE BEAM"
					    "*PILE*"	    "STEEL-HD"
					    "*PCAP*"	    "SPREAD FOOTING"
					    "*GL*"	    "GRIDLINE"
					   )
				  )
		     )
		)
	      (entmod (subst (cons 8 (cadr AttVal))
			     (assoc 8 (entget ent))
			     (entget ent)
		      )
	      )
	    )
	  )
    )
  (princ)
)

 

 

HTH

 

Message 4 of 10
Kent1Cooper
in reply to: Anonymous

A few other things [perhaps irrelevant if you go with pbejse's suggestion]:

 

There's nothing to remove the Block that was just processed from the selection set, so it can move on by next looking at the first one remaining in the set.  It needs something down near the end like:

 

(ssdel attentity SSBlks)

 

And it doesn't use the 'w' or 'tempname' variables for anything.

 

Also, I find the variable names misleading, which makes it more challenging to understand what's going on.  What you call 'attentity' is really a Block's entity name; 'attname' is really a Block's entity data list; 'layername' is really an Attribute's entity name; 'attname' [the second time] is really an Attribute's entity data list; 'tempname' is really the whole dotted-pair entity-data item containing the Attribute's tag [but isn't used, anyway].  And 'newv' seems to be the same as the first version of 'attname', which could be re-used if it hadn't been overwritten with a different value.

Kent Cooper, AIA
Message 5 of 10
Anonymous
in reply to: pbejse

I ended up going a different route and used COND.

 

(setq SSBlks (ssget "x"'((0 . "*INSERT"))))
(while (/= (sslength SSBlks) 0)
(setq w(sslength SSBlks))
(setq attentity (ssname SSBlks 0))
(setq attname (entget attentity))
(setq layername (entget attentity))
(while (/= (cdr (assoc 0 attname)) "SEQEND")
(progn
(setq attname (entnext (cdr (assoc -1 attname))))
(setq attname(entget attname))
(if (= (cdr (assoc 2 attname)) "OWNER")
(progn
(setq blktag (cdr (assoc 1 attname)))
(cond ((wcmatch blktag "*GRBM*")
(setq layername (subst (cons 8 "GRADE BEAM") (assoc 8 layername)layername))
(entmod layername))
    ((wcmatch blktag "*PILE*")
(setq layername (subst (cons 8 "STEEL-HD") (assoc 8 layername)layername))
(entmod layername))
    ((wcmatch blktag "*PCAP*")
(setq layername (subst (cons 8 "SPREAD FOOTING") (assoc 8 layername)layername))
   (entmod layername))
    ((wcmatch blktag "*/GL/*")
(setq layername(subst (cons 8 "GRIDLINE") (assoc 8 layername)layername))
(entmod layername))
    ((wcmatch blktag "*PIER*")
(setq layername(subst (cons 8 "PILASTER") (assoc 8 layername)layername))
(entmod layername))
    ((wcmatch blktag "*SLAB*")
(setq layername(subst (cons 8 "CONC") (assoc 8 layername)layername))
(entmod layername))
)))
))
(ssdel attentity SSBlks))

 

Kent, I realised that error last night, I was sitting and watching tv when I realised I had a bad loop.

 

Thanks guys!

Message 6 of 10
stevor
in reply to: Anonymous

 Combining several posts, to follow Jolo's scheme:

 

 ; 'Change block layers based on Attribute Name tags'
 ; somewhat explicit method, Jolo/Pbejse/AusCadd
 (defun c:BTL (/ SS i ien avs idl adl nlyn ) ; no global SS's
  (if (setq SS (ssget "x" '((0 . "*INSERT") (66 . 1))))
   (repeat (setq i (sslength SS ))
    (setq i (1- i)  ien (ssname SS i)
            idl (entget ien) ; data list of  Insert
            adl (entget (entnext ien) ) ) ; data of presumed ATT
    (if (= (cdr (assoc 2 adl)) "OWNER") ; tag name str
     (progn  (setq avs (cdr (assoc 1 adl)))  ; Att value str
      (if (setq nlyn (cond  ; for a New Layer Name
            ((WCMATCH  avs "*GRBM*")  "GRADE BEAM"     )  
            ((WCMATCH  avs "*PILE*")  "STEEL-HD"       )  
            ((WCMATCH  avs "*PCAP*")  "SPREAD FOOTING" )  
            ((WCMATCH  avs "*GL*"  )  "GRIDLINE"       ) ) ) ; setq
         (entmod (subst (cons 8 nlyn ) (assoc 8 idl ) idl))
         (progn (princ"\n No match of old value: ") (princ avs) )
       ) ; if
     )) ) (princ"\n No Inserts with Atts found "))
  (princ" Done. ")  (princ) )

S
Message 7 of 10
pbejse
in reply to: stevor

Good one Stevor, didnt ealize the OP wanted wild card matching

 

One thing though, if the target TAG is not the first attribute then it wont process the 2nd or 3rd and so on.

 

Try this way (Vanilla)

 

(defun c:BLT (/ SSBlks en an ad avs nlyn)
(if (setq SSBlks (ssget "x"'((0 . "INSERT")(66 . 1))))
(repeat (sslength SSBlks)
	 (setq en (ssname SSBlks 0)
	       an (entnext en)
	       ad (entget an)
	 )
	(while (= "ATTRIB" (cdr (assoc 0 ad)))
	  	(if (= (cdr (assoc 2 ad)) "OWNER")
		  	(progn
			  	(setq avs (cdr (assoc 1 ad)))
		  		(if (setq nlyn
				(cond  ; for a New Layer Name
    			            ((wcmatch  avs "*GRBM*")  "GRADE BEAM"     )  
			            ((wcmatch  avs "*PILE*")  "STEEL-HD"       )  
			            ((wcmatch  avs "*PCAP*")  "SPREAD FOOTING" )  
			            ((wcmatch  avs "*GL*"  )  "GRIDLINE"       )))
				(entmod (subst (cons 8 nlyn ) (assoc 8 (entget en)) (entget en)))
				(progn (princ"\n No match of old value: ") (princ avs))
				  )
			)
		  )
			(setq an (entnext an)
                    		ad (entget an))
		  )
  (setq SSBlks (ssdel (ssname SSBlks 0) SSBlks))
		)
  (princ"\n No Inserts with Atts found "))
  (princ"\nDone. ")(princ)
  )

 HTH

 

Message 8 of 10
pbejse
in reply to: pbejse

(defun c:BTL (/ SSBlks i ent TarAtt AttVal)
  (if (setq SSBlks (ssget "x" '((0 . "*INSERT") (66 . 1))))
	  (repeat (setq i (sslength SSBlks))
	    (setq ent (ssname SSBlks (setq i (1- i))))
	    (if	(and (setq TarAtt (assoc "OWNER"
					 (mapcar '(lambda (j)
						    (list (vla-get-tagstring j)
							  (vla-get-textstring j)
						    )
						  )
						 (vlax-invoke
						   (vlax-ename->vla-object ent)
						   'GetAttributes
						 )
					 )
				  )
		     )
			(setq AttVal (vl-remove-if-not
				     '(lambda (k)
					(wcmatch  (cadr TarAtt)(car k))
				      )
				     (list '("*GRBM*" "GRADE BEAM")
					   '("*PILE*" "STEEL-HD")
					   '("*PCAP*"
					     "SPREAD FOOTING"
					    )
					   '("*GL*" "GRIDLINE")
				     )
				   )
			)		     
		)
	      (entmod (subst (cons 8 (cadar AttVal))
			     (assoc 8 (entget ent))
			     (entget ent)
		      )
	      )
	    )
	  )(princ "\nNo Attribute Blocks Found:")
    )
  (princ)
)

 Modified for wild card matching

Message 9 of 10
stevor
in reply to: pbejse

 
   To Pbejse, etal:
   
 1.  Wild cards: seems to me that your included them.

 2. ' target TAG is not the first attribute then it wont process'  I missed that also; may investigate. For better code, the other Attributes should be handled.
 
 Mine is just the OP's with the redundancy reduced, inside your ename 'server.'     
 

S
Message 10 of 10
pbejse
in reply to: stevor

No worries stevor, i kinda like the  compact ed code you posted, which made me realize my own mistakes

 

cheers stevor

 

 

 

 

 

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report

”Boost