LISP to find a duplicate attribute value

LISP to find a duplicate attribute value

ssuoiresos
Contributor Contributor
3,937 Views
19 Replies
Message 1 of 20

LISP to find a duplicate attribute value

ssuoiresos
Contributor
Contributor

Hi all,

Can somebody please help me with a LISP that highlights the blocks with duplicate attribute values? I am after a program that will search through multiple blocks (CAR_1, CAR_2, CAR_3) in my sample drawing and looks for a duplicate just in a specific attribute value (FUEL_CONSUMPTION in my drawing). So even though there will be other duplicates in the blocks, I will need just this specific attribute value (FUEL_CONSUMPTION) to be different each time. In my drawing I have  2 blocks with 32MPG duplicate that I will need them highlighted. I would like to be able to do a quick check for duplicates without extracting all the data in excel each time. I hope this makes sense. Please see attached a sample drawing. Thank you.

0 Likes
Accepted solutions (1)
3,938 Views
19 Replies
Replies (19)
Message 2 of 20

ВeekeeCZ
Consultant
Consultant

OK. Try SEACH. It should do all you need.

https://autode.sk/2YYe05N

0 Likes
Message 3 of 20

ssuoiresos
Contributor
Contributor
Thanks for your reply. What I mean is drawings with 200 blocks, where you have made an error but you don't know where, therefore you don't know what to look for... You have to know what to search for...
0 Likes
Message 4 of 20

james_moore
Advocate
Advocate

well, I have a starting point for you... this will get you a list of the values in your FUEL_CONSUMPTION paired with the INSERT entity it is associated with.  The list will be in the variable VALUES and is in the format ((<entity> "#MPG)(<entity> "#MPG)(<entity> "#MPG)...).  From here you would use LISP to compare the values in the list to each other.  I'm not sure offhand how to highlight the blocks once you find the ones that match each other, I'm at work and not ready to search for that answer, but I hope this helps put you on the right track.

 

(setq CARBLOCKS (ssget))
(setq COUNT 0)
(repeat (sslength CARBLOCKS)
(setq FIRSTBLOCK (ssname CARBLOCKS COUNT))
(setq SELS (entnext FIRSTBLOCK))
(progn
(while (and (not (equal (cdr (assoc 0 (entget SELS))) "INSERT"))
(not (equal (cdr (assoc 0 (entget SELS))) "SEQEND")))
(if (equal (cdr (assoc 0 (entget SELS))) "ATTRIB")
(progn (setq VALUE (cdr (assoc 1 (entget SELS))))
(setq TAG (cdr (assoc 2 (entget SELS))))
(setq SELS (entnext SELS))
(if (equal TAG "FUEL_CONSUMPTION") (setq VALUES (cons (list FIRSTBLOCK VALUE) VALUES)))
)
)
)
)
(setq COUNT (1+ COUNT))
);END REPEAT
(setq COUNT nil)
(princ VALUES)

Message 5 of 20

devitg
Advisor
Advisor

@ssuoiresos , hi. Will be always the block name start with CAR_xx, and the att tag name FUEL_CONSUMPTION?

0 Likes
Message 6 of 20

james_moore
Advocate
Advocate

SEARCH is not a valid ACAD core command.  Ah, never mind... you mean FIND.

0 Likes
Message 7 of 20

ssuoiresos
Contributor
Contributor
Hi, block name can be different but the attribute tag name will always be the same. Thanks
0 Likes
Message 8 of 20

devitg
Advisor
Advisor

@ssuoiresos  about block names , will they have any COMMON part? , as I can see at the dwg CAR_ is a COMMON part 

 

0 Likes
Message 9 of 20

ssuoiresos
Contributor
Contributor
I tried to keep it really simple in the drawing. "STT-CAR NAME" will be the name of the block. "CAR NAME" can have different names ( a library with over 100 blocks), "STT" is in all of them. So "STT" Is the common part
0 Likes
Message 10 of 20

pbejse
Mentor
Mentor
Accepted solution

@ssuoiresos wrote:

Hi all,

Can somebody please help me with a LISP that highlights the blocks with duplicate attribute values?

.. . So even though there will be other duplicates in the blocks, I will need just this specific attribute value (FUEL_CONSUMPTION) to be different each time


 

(defun c:FCtag (/ _ipt ssdup ss i ev attval a b FC_Coll)
  (defun _ipt (e) (cdr (assoc 10 (entget e))))
  (if (setq ssdup (ssadd)
	    ss	  (ssget
		    "_X"
		    (list '(0 . "INSERT") '(66 . 1) (cons 410 (getvar 'Ctab)))
		  )
      )
    (progn
      (repeat (setq i (sslength ss))
	(setq ev (ssname ss (Setq i (1- i))))
	(setq attval (mapcar '(lambda (at)
				(list (vla-get-tagstring at)
				      (vla-get-textstring at)
				)
			      )
			     (vlax-invoke
			       (vlax-ename->vla-object ev)
			       'GetAttributes
			     )
		     )
	)
	(if (setq f (assoc "FUEL_CONSUMPTION" attval))
	  (setq FC_Coll (cons (list f ev) FC_Coll))
	)
      )
      (while (or b (setq a (Car FC_Coll)))
	(if
	  (setq	b (vl-some '(lambda (c)
			      (if (equal (Car a) (Car c))
				c
			      )
			    )
			   (cdr FC_Coll)
		  )
	  )
	   (progn
	     (entmakex (list (cons 0 "LINE")
			     (cons 10 (_ipt (Cadr a)))
			     (cons 11 (_ipt (Cadr b)))
		       )
	     )
	     (ssadd (Cadr a) ssdup)
	     (ssadd (Cadr b) ssdup)
	     (setq FC_Coll (Vl-remove b FC_Coll)
		   b	   a
	     )
	   )
	   (setq FC_Coll (cdr FC_Coll))
	)
      )
      (sssetfirst nil ssdup)
    )
  )
  (princ)
)

Command: FCtag

 

HTH

 

Message 11 of 20

devitg
Advisor
Advisor

@ssuoiresos  ha escrito:
I tried to keep it really simple in the drawing. "STT-CAR NAME" will be the name of the block. "CAR NAME" can have different names ( a library with over 100 blocks), "STT" is in all of them. So "STT" Is the common part

So please upload a more detailed DWG with such STT named blocks . 

Do you want to highlight  the reference blk, by steps, say first the ones that have 32mpg,  do something , and then 

to the next duplicated att string value , or better to mark  all duplicated by  any way , maybe by means of a text with the att-string value. 

 

 

0 Likes
Message 12 of 20

ssuoiresos
Contributor
Contributor
Thank you so much. It works like a charm. You really know your stuff.
0 Likes
Message 13 of 20

adminXYZ5K
Explorer
Explorer
@pbejse hello, didn't want to open a new thread as it is related. Are you able to help me out with amending this code, so that it looks for duplicates in both FUEL_CONSUMPTION and REF1? If both values are the same, then it returns and highlights the blocks. If only one value is different, it no longer highlights? I've tried looking online for assistance and couldn't find what I'm looking for.

  

0 Likes
Message 14 of 20

pbejse
Mentor
Mentor

@adminXYZ5K wrote:
@pbejse hello, didn't want to open a new thread as it is related. Are you able to help me out with amending this code, so that it looks for duplicates in both FUEL_CONSUMPTION and REF1? If both values are the same, then it returns and highlights the blocks. If only one value is different, it no longer highlights? I've tried looking online for assistance and couldn't find what I'm looking for.

  


Is that ALSO same value FUEL_CONSUMPTION AND REF1 then highlight?

 

0 Likes
Message 15 of 20

adminXYZ5K
Explorer
Explorer

FUEL_CONSUMPTION AND REF1 would be different values.

Please see the examples attached. 

In the first example, the duplicates should not highlight, as REF1 differs between blocks.

In the second example, the duplicates should highlight, as REF1 & FUEL_CONSUMPTION is the same in both.

 

Thank you for helping

0 Likes
Message 16 of 20

pbejse
Mentor
Mentor

@adminXYZ5K wrote:

FUEL_CONSUMPTION AND REF1 would be different values.

Please see the examples attached. 

In the first example, the duplicates should not highlight, as REF1 differs between blocks.

In the second example, the duplicates should highlight, as REF1 & FUEL_CONSUMPTION is the same in both.

 

Thank you for helping


 

(defun c:FCtag (/ _ipt ssdup ss i ev attval a b FC_Coll)
  (defun _ipt (e) (cdr (assoc 10 (entget e))))
  (setq theseTags '("FUEL_CONSUMPTION" "REF1"))
  (if (setq ssdup (ssadd)
	    ss	  (ssget
		    "_X"
		    (list '(0 . "INSERT") '(66 . 1) (cons 410 (getvar 'Ctab)))
		  )
      )
    (progn
      (repeat (setq i (sslength ss))
	(setq ev (ssname ss (Setq i (1- i))))
	(setq attval (mapcar '(lambda (at)
				(list (vla-get-tagstring at)
				      (vla-get-textstring at)
				)
			      )
			     (vlax-invoke
			       (vlax-ename->vla-object ev)
			       'GetAttributes
			     )
		     )
	)
	(if (vl-every '(lambda (at / ft )
				 (and (setq ft (assoc at attval))
				      (setq f (cons ft f)))) theseTags)
			
	  (setq FC_Coll (cons (append f (list ev)) FC_Coll) f nil)
	)
      )
      (while (or b (setq a (Car FC_Coll)))
	(if
	  (setq	b (vl-some '(lambda (c)
			      (if (and
				    (equal (Car a) (Car c))(equal (Cadr a) (Cadr c)))
				c
			      )
			    )
			   (cdr FC_Coll)
		  )
	  )
	   (progn
	     (entmakex (list (cons 0 "LINE")
			     (cons 10 (_ipt (last a)))
			     (cons 11 (_ipt (last b)))
		       )
	     )
	     (ssadd (last a) ssdup)
	     (ssadd (last b) ssdup)
	     (setq FC_Coll (Vl-remove b FC_Coll)
		   b	   a
	     )
	   )
	   (setq FC_Coll (cdr FC_Coll))
	)
      )
      (sssetfirst nil ssdup)
    )
  )
  (princ)
)




Message 17 of 20

adminXYZ5K
Explorer
Explorer

Thank you very much, that works.

0 Likes
Message 18 of 20

5624david
Contributor
Contributor

Hello and thanks

I have the lisp routine for M2P but I don't know where to put it.  To mirror between two points

 

(defun c:m2p (/ ent1 ent2 ep1 ep2 pt1 pt2 sp1 sp2 tmp)
 (setq ent1 (car (entsel "\nSelect first line: "))
       ent2 (car (entsel " \nselect second line: "))
       sp1  (vlax-curve-getstartpoint ent1)
       ep1  (vlax-curve-getendpoint ent1)
       sp2  (vlax-curve-getstartpoint ent2)
       ep2  (vlax-curve-getendpoint ent2))
 (if (> (distance sp1 sp2) (distance sp1 ep2))
  (setq tmp sp2
        sp2 ep2
        ep2 tmp))
 (setq pt1 (mapcar '/ (mapcar '+ sp1 sp2) '(2 2))
       pt2 (mapcar '/ (mapcar '+ ep1 ep2) '(2 2)))
 (command "._mirror" (ssget) "" pt1 pt2 "_n"))

0 Likes
Message 19 of 20

5624david
Contributor
Contributor

I tried posting this once so it may have already been posted.  My mirror between 2 points icons quit working so my reseller sent me the lisp routine but I have no idea where to put it.  I don't know anything about stuff like this  🙂

 

Thank you

 

(defun c:m2p (/ ent1 ent2 ep1 ep2 pt1 pt2 sp1 sp2 tmp)
 (setq ent1 (car (entsel "\nSelect first line: "))
       ent2 (car (entsel " \nselect second line: "))
       sp1  (vlax-curve-getstartpoint ent1)
       ep1  (vlax-curve-getendpoint ent1)
       sp2  (vlax-curve-getstartpoint ent2)
       ep2  (vlax-curve-getendpoint ent2))
 (if (> (distance sp1 sp2) (distance sp1 ep2))
  (setq tmp sp2
        sp2 ep2
        ep2 tmp))
 (setq pt1 (mapcar '/ (mapcar '+ sp1 sp2) '(2 2))
       pt2 (mapcar '/ (mapcar '+ ep1 ep2) '(2 2)))
 (command "._mirror" (ssget) "" pt1 pt2 "_n"))

0 Likes
Message 20 of 20

ec-cad
Collaborator
Collaborator

Please do not double / tripple post.

See my remarks on your topic 'Lisp'.

Here is what I posted there:

"

You say:

"I have a lisp routine someone sent me" ..

You could ask that individual what to do with it.

OR,

You could load that program with every drawing open. (assuming you have a version of AutoCAD that supports Lisp).

You place a copy of your lisp in any 'support' folder for acad, then using Notepad, make a file called acaddoc.lsp with this in it.

(load "M2P.lsp")

IF you have the file M2P.lsp stored somewhere else on you drive, use the 'path' to the M2P.lsp file, such as:

(load "c:/path/M2P.lsp"); where path is your location of the file.

Place the acaddoc.lsp  in your \AutoCADxxx\Support   folder.

Open Acad, then at the Command Prompt, type M2P<enter>

 

ECCAD"

 

0 Likes