Visual LISP, AutoLISP and General Customization

Visual LISP, AutoLISP and General Customization

Reply
Valued Contributor
AR12
Posts: 90
Registered: ‎12-28-2009
Message 1 of 12 (237 Views)
Accepted Solution

Find a Block based on value of an attribute

237 Views, 11 Replies
04-30-2014 08:52 AM

HI All,

I did some searching and can't seem to find what I'm looking for, so I apologize if it exists somewhere and I missed it. If I did miss the information if you could kindly direct me to the specific thread I would appreciate it.

 

Ok, so what I'm trying to do is find a specific copy of a block, the block I'm trying to find is used multiple times in 1 drawing as part of the bill of material. I know the value of 1 attribute in the block, which in this case is a part number, now I want to be able to modify the value of a different attribute in the block based on finding it by the value of the part number. How would I go about figuring out which block is the one that I want to modify?

Thanks,
Adam Richardson

If needed: AutoCAD 2013 User using Visual LISP for editing LISP and DCL files

AR12 wrote:

HI All,

I did some searching and can't seem to find what I'm looking for, so I apologize if it exists somewhere and I missed it. If I did miss the information if you could kindly direct me to the specific thread I would appreciate it.

 

Ok, so what I'm trying to do is find a specific copy of a block, the block I'm trying to find is used multiple times in 1 drawing as part of the bill of material. I know the value of 1 attribute in the block, which in this case is a part number, now I want to be able to modify the value of a different attribute in the block based on finding it by the value of the part number. How would I go about figuring out which block is the one that I want to modify?


Methinks that some of the other replies have missed your main goal (as highlighted above)...

Try this (it will return a selection set of blocks on your current layout tab that match a given block name, with a given Attribute Name, and a given value for that attribute):

 

;returns a selection set of all blocks matching requested values
;call with something like:
;(setq Blkset (GetBlksByAttVal "Block Name" "Attribute Name" "Attribute Value"))
(defun GetBlksByAttVal (BlkName AttName AttVal /
ss ReturnSS Ctr InsEnt Att AttList)
(setq ss (ssget "_X" (list
'(0 . "INSERT")
(cons 2 BlkName)
'(66 . 1)
(cons 410 (getvar "ctab"))
)))
(setq ReturnSS (ssadd))
(setq Ctr 0)
(while (< Ctr (sslength ss))
(setq InsEnt (ssname ss Ctr))
(setq Att (entnext InsEnt))
(setq AttList (entget Att))
(while (= "ATTRIB" (cdr (assoc 0 Attlist)))
(if (and
(= (strcase AttName) (strcase (cdr (assoc 2 Attlist))))
(= (strcase AttVal) (strcase (cdr (assoc 1 Attlist))))
)
(ssadd InsEnt ReturnSS)
);if the correct attribute
(setq Att (entnext Att))
(setq AttList (entget Att))
);while attributes
(setq Ctr (1+ Ctr))
);while ss members
(if (> (sslength ReturnSS) 0)
ReturnSS
nil
)
);defun

 Happy Lisping

-Gary

*Expert Elite*
3wood
Posts: 1,061
Registered: ‎03-25-2009
Message 2 of 12 (207 Views)

Re: Find a Block based on value of an attribute

04-30-2014 02:18 PM in reply to: AR12

I think if the there is not much duplication happens among attribute values under different attribute tags, you can just Find and Replace.

Otherwise you can try attached ALTEXT.vlx and set the "Start from" and "End at" to the same value, as the example settings below.

Input a new text in "New text" box, or add a number to existing figures by filling in "Increment" box.

altext.png

Valued Contributor
AR12
Posts: 90
Registered: ‎12-28-2009
Message 3 of 12 (205 Views)

Re: Find a Block based on value of an attribute

04-30-2014 02:21 PM in reply to: 3wood

Hi 3wood,

It sounds like this is something that the user of the program would have to use. I want to make it so that the user won't have to use anything like that to change the quantity(which is the value that I want to change)

Thanks,
Adam Richardson

If needed: AutoCAD 2013 User using Visual LISP for editing LISP and DCL files
*Expert Elite*
Lee_Mac
Posts: 1,178
Registered: ‎12-29-2009
Message 4 of 12 (195 Views)

Re: Find a Block based on value of an attribute

04-30-2014 02:35 PM in reply to: AR12

Here is a very simple attribute find & replace function - it will simply iterate over all attributed blocks in all layouts of the drawing, and if the first supplied value is found, it will be replaced with the second supplied value:

 

 

(defun replace-att-value ( old new / a e i s x )
    (setq old (strcase old)
          new (cons 1 new)
    )
    (if (setq s (ssget "_X" '((0 . "INSERT") (66 . 1))))
        (repeat (setq i (sslength s))
            (setq e (entnext (ssname s (setq i (1- i))))
                  x (entget e)
            )
            (while (= "ATTRIB" (cdr (assoc 0 x)))
                (if (= old (strcase (cdr (setq a (assoc 1 (reverse x))))))
                    (entmod (subst new a x))
                )
                (setq e (entnext e)
                      x (entget  e)
                )
            )
        )
    )
    (princ)
)

 

Call the above with the find & replace strings:

 

 

(replace-att-value "abc" "123")

 

The 'find' string is not case-sensitive.

 

The function is very generic, but could easily be modified to search only blocks of a specific name, or on a particular layer etc.

Lee Mac ProgrammingTwitterExchange App StoreDropbox (500MB free)
Expert Elite
With Mathematics there is the possibility of perfect rigour, so why settle for less?
Valued Mentor
Gary_J_Orr
Posts: 314
Registered: ‎09-23-2008
Message 5 of 12 (178 Views)

Re: Find a Block based on value of an attribute

04-30-2014 08:13 PM in reply to: AR12

AR12 wrote:

HI All,

I did some searching and can't seem to find what I'm looking for, so I apologize if it exists somewhere and I missed it. If I did miss the information if you could kindly direct me to the specific thread I would appreciate it.

 

Ok, so what I'm trying to do is find a specific copy of a block, the block I'm trying to find is used multiple times in 1 drawing as part of the bill of material. I know the value of 1 attribute in the block, which in this case is a part number, now I want to be able to modify the value of a different attribute in the block based on finding it by the value of the part number. How would I go about figuring out which block is the one that I want to modify?


Methinks that some of the other replies have missed your main goal (as highlighted above)...

Try this (it will return a selection set of blocks on your current layout tab that match a given block name, with a given Attribute Name, and a given value for that attribute):

 

;returns a selection set of all blocks matching requested values
;call with something like:
;(setq Blkset (GetBlksByAttVal "Block Name" "Attribute Name" "Attribute Value"))
(defun GetBlksByAttVal (BlkName AttName AttVal /
			ss ReturnSS Ctr InsEnt Att AttList)
  (setq ss (ssget "_X" (list
			 '(0 . "INSERT")
			 (cons 2 BlkName)
			 '(66 . 1)
			 (cons 410 (getvar "ctab"))
			 )))
  (setq ReturnSS (ssadd))
  (setq Ctr 0)
  (while (< Ctr (sslength ss))
    (setq InsEnt (ssname ss Ctr))
    (setq Att (entnext InsEnt))
    (setq AttList (entget Att))
    (while (= "ATTRIB" (cdr (assoc 0 Attlist)))
      (if (and
	    (= (strcase AttName) (strcase (cdr (assoc 2 Attlist))))
	    (= (strcase AttVal) (strcase (cdr (assoc 1 Attlist))))
	    )
	(ssadd InsEnt ReturnSS)
	);if the correct attribute
      (setq Att (entnext Att))
      (setq AttList (entget Att))
      );while attributes
    (setq Ctr (1+ Ctr))
    );while ss members
  (if (> (sslength ReturnSS) 0)
    ReturnSS
    nil
    )
  );defun

 Happy Lisping

-Gary

Gary J. Orr
(Your Friendly Neighborhood) CADD/BIM/VDC Applications Manager
http://www.linkedin.com/in/garyorr

aka (current and past user names):
Gary_J_Orr (GOMO Stuff 2008-Present); OrrG (Forum Studio 2005-2008); Gary J. Orr (LHB Inc 2002-2005); Orr, Gary J. (Gossen Livingston 1997-2002)
Valued Contributor
AR12
Posts: 90
Registered: ‎12-28-2009
Message 6 of 12 (158 Views)

Re: Find a Block based on value of an attribute

05-01-2014 05:59 AM in reply to: Gary_J_Orr

Gary,

Thanks, I will try that and see if I can make that work for what I'm trying to do.

 

Lee,

While this sounds like it could possibly work, the issue I have is the value that I want to change could potentially be the same in multiple spots of the same block name which is why I need to be able to find the value of a different attribute in the block.

Thanks,
Adam Richardson

If needed: AutoCAD 2013 User using Visual LISP for editing LISP and DCL files
Valued Contributor
AR12
Posts: 90
Registered: ‎12-28-2009
Message 7 of 12 (153 Views)

Re: Find a Block based on value of an attribute

05-01-2014 06:12 AM in reply to: AR12

Hi Gary,

I'm not sure if I'm making a mistake with how I'm trying to use the function but I pasted it into Visual LISP and Loaded the Function. Then in the console I tried to use the function and I'm getting a Error: bad SSGET list value. I've attached the screenshots to this post so you can see the Attribute edit box which you can see the Block Name, Attribute Name and the current value and I've also attached a screenshot of the Console in Visual LISP so you can see what I input.

Thanks,
Adam Richardson

If needed: AutoCAD 2013 User using Visual LISP for editing LISP and DCL files
Valued Mentor
Gary_J_Orr
Posts: 314
Registered: ‎09-23-2008
Message 8 of 12 (141 Views)

Re: Find a Block based on value of an attribute

05-01-2014 06:28 AM in reply to: AR12
you're passing what should be strings as variables:
(GetBlksByAttVal TP_BOM PART "GP23566")
Unless you have preset those variables you are passing "nil" for the arguments...

Enclose your arguments in quotes:
(GetBlksByAttVal "TP_BOM" "PART" "GP23566")

To make my life easier as things progress, could you copy and paste any console info directly into the message? popping back and forth between the message and the screenshots (not to mention having to retype what is in your capyure) goes against the grain of my ingrained "laziness" *ReallyBigGrin*
-Gary
Gary J. Orr
(Your Friendly Neighborhood) CADD/BIM/VDC Applications Manager
http://www.linkedin.com/in/garyorr

aka (current and past user names):
Gary_J_Orr (GOMO Stuff 2008-Present); OrrG (Forum Studio 2005-2008); Gary J. Orr (LHB Inc 2002-2005); Orr, Gary J. (Gossen Livingston 1997-2002)
Valued Contributor
AR12
Posts: 90
Registered: ‎12-28-2009
Message 9 of 12 (137 Views)

Re: Find a Block based on value of an attribute

05-01-2014 06:38 AM in reply to: Gary_J_Orr

Hi Gary,

Thanks. Now that I put those items in parentheses the function worked. Now that I see how the function worked I'll see if I can utilize it for what I'm looking to do.

Thanks,
Adam Richardson

If needed: AutoCAD 2013 User using Visual LISP for editing LISP and DCL files
Valued Mentor
Gary_J_Orr
Posts: 314
Registered: ‎09-23-2008
Message 10 of 12 (132 Views)

Re: Find a Block based on value of an attribute

05-01-2014 06:51 AM in reply to: AR12
Adam,
There are a number of directions that you can take with that snippet... I have it returning a selection set as that is what you asked for (indirectly at least), but it can easily be modified to "do the work" within itself or be part of a larger module that defines any number of preset arguments for various conditions then takes action on the returned sel set...

Have fun... if it stops being fun, give a hollar and I'll be glad to help out.
-Gman
Gary J. Orr
(Your Friendly Neighborhood) CADD/BIM/VDC Applications Manager
http://www.linkedin.com/in/garyorr

aka (current and past user names):
Gary_J_Orr (GOMO Stuff 2008-Present); OrrG (Forum Studio 2005-2008); Gary J. Orr (LHB Inc 2002-2005); Orr, Gary J. (Gossen Livingston 1997-2002)
Announcements
Are you familiar with the Autodesk Expert Elites? The Expert Elite program is made up of customers that help other customers by sharing knowledge and exemplifying an engaging style of collaboration. To learn more, please visit our Expert Elite website.
Need installation help?

Start with some of our most frequented solutions or visit the Installation and Licensing Forum to get help installing your software.