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

compare 2 blocks attributes values

24 REPLIES 24
SOLVED
Reply
Message 1 of 25
sergiu_ciuhnenco
1040 Views, 24 Replies

compare 2 blocks attributes values

Hi everyone, I have an idea but , is gonna be made only with your help ...
I have 2 blocks with attributes , I have to compare each cell value in first block with its opposite cell value in other block , and choose the maximum cell value
the blank cell we should consider 0 value ...
for a newbie is hard to made this
Hope on your help !
P.S. we can create a third block , for the maximum value ( make a copy of one of block , and there put the maximum values )

24 REPLIES 24
Message 2 of 25
hmsilva
in reply to: sergiu_ciuhnenco

Hi Sergiu,

It would be easier if all cells have attributes, and TAGs were common to both...

But, with this situation, all TAG's are different, and not all cells have attributes, the number of attributes are different in both blocks, but the blocks are similar, what occurs to me is to store in two lists, the relative position from each Att (from the block insertion point to text insertion point) and the tag/value, and use the relative position, with some fuzz, to test the value, and save the relative position and maximum value in a third list...

 

Hope this helps,
Henrique

 

 

EESignature

Message 3 of 25

Try this code. As has been said by Henrique, its somewhat unnecessarily complicated, so I tried to simplify.

 

You need to prepare your drawing first... see the attachment. Copy the tables on top of each other, align them and explode them. Then you can run the lisp.

 

Spoiler
(vl-load-com)

(defun c:MaxAttTable ( / *error* doc oVAR ss i pt ssi n0 n1 endel point name)

  (defun *error* (errmsg)
    (if (not (wcmatch errmsg "Function cancelled,quit / exit abort,console break"))
      (princ (strcat "\nError: " errmsg)))
    (foreach e oVAR (setvar (car e) (cdr e)))
    (vla-endundomark doc)
    (princ))


  (vla-startundomark (setq doc (vla-get-activedocument (vlax-get-acad-object))))
  (foreach e '(CMDECHO ORTHOMODE OSMODE ATTREQ)
    (setq oVAR (cons (cons e (getvar e)) oVAR)))

  (setvar 'CMDECHO 	0)
  (setvar 'ORTHOMODE 	0)
  (setvar 'ATTREQ 	0)
  (setvar 'OSMODE 	0)

  
  (if (and (princ "\nNeed ATTDEFs of exploded blocks placed on top of each other, ")
	   (setq ss (ssget '((0 . "ATTDEF"))))
	   (setq i (sslength ss))
      )
    (progn
      (while (not (minusp (setq i (1- i))))
        (setq pt (cdr (assoc 10 (entget (ssname ss i))))
	      ssi (ssget "_C" pt (polar pt 0.5 3) '((0 . "ATTDEF"))))
        (cond ((= 1 (sslength ssi)))
	      ((and (= 2 (sslength ssi))
		    (numberp (setq n0 (read (vl-string-subst "." "," (cdr (assoc 1 (entget (ssname ssi 0))))))))
		    (numberp (setq n1 (read (vl-string-subst "." "," (cdr (assoc 1 (entget (ssname ssi 1)))))))))
	       (setq endel (ssname ssi (car (vl-sort-i (list n0 n1) '<))))
	       (if (not (equal endel 				; for deleting - if deleted ent is NOT
			       (ssname ss  i)))   		; the current of while loop
		 (setq i (1- i)))				; decrease the index
	       (ssdel  endel ss)
	       (entdel endel))
      	      (T
	       (princ "\nSomething is wrong, problematic texts are marked yellow!")
	       (command "_.CHPROP" ssi "" "_C" 2 ""))))
      
      (setvar 'OSMODE (cdr (assoc 'OSMODE oVAR)))
      (if (setq point (getpoint "\nSpecify insertion point <don't make a block>: "))
	(progn
	  (setq i 0)
	  (while (tblsearch "block" (setq name (strcat "MyBlock" (itoa (setq i (1+ i)))))))
	  (command "_.-BLOCK"  name "_none" point ss ""
		   "_.-INSERT" name "_none" point 1 "" "")))
    )
  )
  (foreach e oVAR (setvar (car e) (cdr e)))
  (vla-endundomark doc)
  (princ)
)
Message 4 of 25
hmsilva
in reply to: sergiu_ciuhnenco

Sergiu,

as I said in my previous message, one solution was to use the relative position from each Att ,from the block insertion, to point to text insertion point.

But to use this approach, the blocks must be identical, I did edit the two blocks, to ensure that, in my dwg, both blocks, are identical, I did edit the bloks in the Block Editor, and scale both, to the same size.

 

The following quick and dirty 'demo', sorry but I don't have much spare time to write a cleaner code, is just one possible approach to make the comparison between both blocs...

 

(vl-load-com)
(defun c:demo (/ ATT BLK INS_PT L1 L2 L3 LAST_E LST OBJ PT SS)
   (if (and (princ "\n Select the two blocks: ")
            (setq ss (ssget '((0 . "INSERT") (2 . "MyBlock1,MyBlock2") (66 . 1))))
            (= (sslength ss) 2)
            (setq pt (getpoint "\ Enter point to insert the result: "))
            (setq last_e (entlast))
       )
      (progn
         (setq obj    (vlax-ename->vla-object (ssname ss 0))
               ins_pt (vlax-get obj 'insertionpoint)
               blk    (vla-get-effectivename obj)
               l1     (mapcar
                         '(lambda (att)
                             (cons (mapcar '- (vlax-get att 'insertionpoint) ins_pt) (vla-get-TextString att))
                          )
                         (vlax-invoke obj "GetAttributes")
                      )
               obj    (vlax-ename->vla-object (ssname ss 1))
               ins_pt (vlax-get obj 'insertionpoint)
               l2     (mapcar
                         '(lambda (att)
                             (cons (mapcar '- (vlax-get att 'insertionpoint) ins_pt) (vla-get-TextString att))
                          )
                         (vlax-invoke obj "GetAttributes")
                      )
               l1     (vl-remove-if
                         '(lambda (x)
                             (vl-some '(lambda (y)
                                          (if (equal (car x) (car y) 3.5)
                                             (setq l2 (vl-remove y l2)
                                                   l3 (cons (if (> (atof (vl-string-subst "." "," (cdr x))) (atof (vl-string-subst "." "," (cdr y))))
                                                               x
                                                               y
                                                            )
                                                            l3
                                                      )
                                             )
                                          )
                                       )
                                      l2
                             )
                          )
                         l1
                      )
               lst    (append l1 l2 l3)
         )
         (command "-insert" blk "_Scale" 1 pt 0)
         (command "_.explode" "_L")
         (setq ss (ssget "_P" '((0 . "ATTDEF"))))
         (command "_.erase" ss "")
         (foreach x lst
            (entmake
               (list
                  (cons 0 "TEXT")
                  (cons 100 "AcDbText")
                  (cons 40 2.5)
                  (cons 10 (mapcar '+ (car x) pt))
                  (cons 1 (cdr x))
               )
            )
         )
      )
   )
   (princ)
)

 

Hope this helps,
Henrique

EESignature

Message 5 of 25
sergiu_ciuhnenco
in reply to: hmsilva

Thanks guys for fast attempting ,Henrique  your code give in final an error , somethings is goin wrong

Message 6 of 25
hmsilva
in reply to: sergiu_ciuhnenco


@sergiu_ciuhnenco wrote:

...Henrique  your code give in final an error , somethings is goin wrong


Did you try the code with the dwg I've attached?

I did test the code with the dwg I've attached, without error...

 

Henrique

EESignature

Message 7 of 25


@sergiu_ciuhnenco wrote:

... code give in final an error , somethings is goin wrong


Are you having non-english version of autocad? If so, add "_." like this... 

 

(command "_.-insert" blk "_Scale" 1 pt 0)
Message 8 of 25
sergiu_ciuhnenco
in reply to: hmsilva

It show me this kind of thing : "; error: Function cancelled "
I use the dwg file that you atached , write demo comand , selecting the 2 blocks , and when I have to insert the point : error ..
May be I am doing something different from your steps ?

Message 9 of 25
hmsilva
in reply to: ВeekeeCZ


@ВeekeeCZ wrote:

@sergiu_ciuhnenco wrote:

... code give in final an error , somethings is goin wrong


Are you having non-english version of autocad? If so, add "_." like this... 

 

(command "_.-insert" blk "_Scale" 1 pt 0)

Hi BeekeeCZ,

probably is that what is causing the error...

 

Thank you

Henrique

 

EESignature

Message 10 of 25
sergiu_ciuhnenco
in reply to: hmsilva

now , it's english version

Message 11 of 25
hmsilva
in reply to: sergiu_ciuhnenco


@sergiu_ciuhnenco wrote:

now , it's english version


What is the error?

 

Henrique

EESignature

Message 12 of 25
sergiu_ciuhnenco
in reply to: hmsilva

error.jpg

Message 13 of 25
hmsilva
in reply to: sergiu_ciuhnenco

Invalid... It is not sufficient to understand the error...

 

Just for debugging:

  • Open the file I did post
  • appload the demo1.lsp
  • type demo
  • select both blocks
  • pick a point

 

It worked as expected?

 

Henrique

EESignature

Message 14 of 25
sergiu_ciuhnenco
in reply to: hmsilva

same thing , I will try tomorow at work in 2013 version ,, for me is the first time when is happening something like this
I let you know already tomorow , hope with good news

Message 15 of 25
hmsilva
in reply to: sergiu_ciuhnenco


@sergiu_ciuhnenco wrote:

same thing , I will try tomorow at work in 2013 version ,, for me is the first time when is happening something like this
I let you know already tomorow , hope with good news


Ok!

I did test the code in AutoCAD 2010, 2012, 2014 and 2016...

 

Try the attached code, and see if it works better.

 

Henrique

EESignature

Message 16 of 25
ВeekeeCZ
in reply to: hmsilva


@hmsilva wrote:

Hi BeekeeCZ,

probably is that what is causing the error...

 

Thank you

Henrique

 


Hi Henrique, you're welcome. I tried your code as well (AutoCAD 2015 EN) and it's fine with me.

Message 17 of 25
hmsilva
in reply to: ВeekeeCZ


@ВeekeeCZ wrote:
.. I tried your code as well (AutoCAD 2015 EN) and it's fine with me.

Thank you, BeekeeCZ, for testing the code also.

It's a weird error, and I can't understand what may be causing the error.

 

Cheers

Henrique

EESignature

Message 18 of 25
sergiu_ciuhnenco
in reply to: hmsilva

finaly , It work :Thanks a lot
both of you do a great job , thanks again !!!!!!!
nice to meet profesionals like you guys !!!!!!!!!!!!

Message 19 of 25
hmsilva
in reply to: sergiu_ciuhnenco


@sergiu_ciuhnenco wrote:

finaly , It work :Thanks a lot
both of you do a great job , thanks again !!!!!!!
nice to meet profesionals like you guys !!!!!!!!!!!!


Finaly!!! 🙂

You're welcome, Sergiu!

Henrique

EESignature

Message 20 of 25
ВeekeeCZ
in reply to: hmsilva


@hmsilva wrote:
Thank you, BeekeeCZ, for testing the code also.

It's a weird error, and I can't understand what may be causing the error.

Cheers

Henrique


Congrats! 🙂 I had ATTREQ 0 from previous... so didn't see that coming.
BTW (error nil) is new to me, nice. Thx

 

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

Post to forums  

Autodesk Design & Make Report

”Boost