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 )
Solved! Go to Solution.
Solved by hmsilva. Go to Solution.
Solved by hmsilva. Go to Solution.
Solved by ВeekeeCZ. Go to Solution.
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
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.
(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) )
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
Thanks guys for fast attempting ,Henrique your code give in final an error , somethings is goin wrong
@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
@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)
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 ?
@В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
Invalid... It is not sufficient to understand the error...
Just for debugging:
It worked as expected?
Henrique
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
@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
finaly , It work :Thanks a lot
both of you do a great job , thanks again !!!!!!!
nice to meet profesionals like you guys !!!!!!!!!!!!
@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