Author Topic: compare 2 blocks attributes values  (Read 4103 times)

0 Members and 1 Guest are viewing this topic.

serge_c

  • Newt
  • Posts: 39
compare 2 blocks attributes values
« on: August 15, 2015, 12:41:26 PM »
I post this topic also on others  forums , I know the main gurus are aproximately the same ones   :-) , but still hoping for 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
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 )

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: compare 2 blocks attributes values
« Reply #1 on: August 15, 2015, 01:49:16 PM »
The blocks you want to compare have obviously been generated by a program.
They are quite peculiar.
  • Each block has over a thousand attributes.
  • The blocks have different names and different attribute tags.
  • Each block has multiple attributes with the same tag.
  • Empty cells do not contain an attribute.
  • The blocks have the same number of cells but for the cells to match one of the blocks has to be scaled.
  • The cells are not all rectangular.
All of this makes what you plan to do quite hard. I thinks scaling one of the blocks and then comparing the approximate coordinates of attributes is one of the few ways that can work to match up attributes.

serge_c

  • Newt
  • Posts: 39
Re: compare 2 blocks attributes values
« Reply #2 on: August 15, 2015, 06:09:08 PM »
I know that is not easy , that why I am calling for yours help ,
The blocks wich generate the blocks , make it a WMF file , when I put this WMF file in autocad , it show like a block , but I transform it in block with atributes , I think It could help

Tharwat

  • Swamp Rat
  • Posts: 707
  • Hypersensitive
Re: compare 2 blocks attributes values
« Reply #3 on: August 16, 2015, 01:05:22 AM »
Hello ,

Here is my attempt in this regard , so try it and let me know .

Code - Auto/Visual Lisp: [Select]
  1. (defun c:test (/ s ss e e1 e2 l a b objs p bk)
  2. ;;;     Author : Tharwat 16.08.2015                             ;;
  3. ;;;-------------------------------------------------------------;;
  4. ;;; Compares between two attributed blocks values then          ;;
  5. ;;; write minimum attributes text strings in a new block        ;;
  6. ;;; that is one of the two previous selected blocks             ;;
  7. ;;; NOTE: the new text string should consider the maximum       ;;
  8. ;;; value and if it's equal to empty string replace it with 0   ;;
  9. ;;;-------------------------------------------------------------;;
  10.   (princ "\nSelect First Attribute block :")
  11.   (and (setq s (ssget "_+.:S:E" '((0 . "INSERT") (66 . 1))))
  12.        (princ "\nSelect Second Attribute block :")
  13.        (setq ss (ssget "_+.:S:E" '((0 . "INSERT") (66 . 1))))
  14.        (setq objs (mapcar '(lambda (o)
  15.                              (vlax-invoke
  16.                                (vlax-ename->vla-object o)
  17.                                'getattributes
  18.                                )
  19.                              )
  20.                           (list (ssname s 0) (ssname ss 0))
  21.                           )
  22.              )
  23.        (mapcar '(lambda (j k)
  24.                   (setq l
  25.                          (cons (list (vla-get-textstring j) (vla-get-textstring k))
  26.                                l
  27.                                )
  28.                         )
  29.                   )
  30.                (car objs)
  31.                (cadr objs)
  32.                )
  33.        (if (or (eq (setq a (length (mapcar 'car l)))
  34.                    (setq b (length (mapcar 'cadr l)))
  35.                    )
  36.                (> a b)
  37.                )
  38.          (setq e s)
  39.          (setq e ss)
  40.          )
  41.        (setq p (getpoint "\nSpecify insertion point for third Block :"))
  42.        (setq bk (vla-insertblock
  43.                   (vla-get-block
  44.                     (vla-get-activelayout
  45.                       (vla-get-activedocument (vlax-get-acad-object))
  46.                       )
  47.                     )
  48.                   (vlax-3d-point p)
  49.                   (vla-get-effectivename
  50.                     (vlax-ename->vla-object (ssname e 0))
  51.                     )
  52.                   1.0
  53.                   1.0
  54.                   1.0
  55.                   0.
  56.                   )
  57.              )
  58.        (mapcar '(lambda (val att)
  59.                   (setq v
  60.                          (mapcar '(lambda (x) (read (vl-string-translate "," "." x)))
  61.                                  val
  62.                                  )
  63.                         )
  64.                   (cond ((not (car v)) (setq v (list 0 (cadr v))))
  65.                         ((not (cadr v)) (setq v (list (car v) 0)))
  66.                         )
  67.                   (vla-put-textstring
  68.                     att
  69.                     (vl-string-translate
  70.                       "."
  71.                       ","
  72.                       (vl-princ-to-string
  73.                         (if (> (car v) (cadr v))
  74.                           (car v)
  75.                           (cadr v)
  76.                           )
  77.                         )
  78.                       )
  79.                     )
  80.                   )
  81.                l
  82.                (vlax-invoke bk 'getattributes)
  83.                )
  84.        )
  85.   (princ)
  86.  

serge_c

  • Newt
  • Posts: 39
Re: compare 2 blocks attributes values
« Reply #4 on: August 16, 2015, 05:04:59 AM »
Hi again Tharwat , thanks for fast attempting , but it does not work
For some values it work, but not for all !!!
For some values it's take the maximum values , for other ones it take the minimum values
sometimes go wrong way
« Last Edit: August 16, 2015, 05:23:20 AM by sergiu_ciuhnenco »

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: compare 2 blocks attributes values
« Reply #5 on: August 16, 2015, 05:25:54 AM »
I know that is not easy , that why I am calling for yours help ,
The blocks wich generate the blocks , make it a WMF file , when I put this WMF file in autocad , it show like a block , but I transform it in block with atributes , I think It could help
I don't understand at all. Try explaining in more detail and post the WMF files you are using.

serge_c

  • Newt
  • Posts: 39
Re: compare 2 blocks attributes values
« Reply #6 on: August 16, 2015, 06:25:47 AM »
The wmf file are at work , I will post it tomorow morning ,
This numbers are area of rebars wich I have to cover , I have to choose , the maximum values  (same cell but oposite block)
And in dependent of this maximum value I  Reinforce the diaphragm

serge_c

  • Newt
  • Posts: 39
Re: compare 2 blocks attributes values
« Reply #7 on: August 16, 2015, 06:45:35 AM »
here a atach again the blocks , I change the text style

Tharwat

  • Swamp Rat
  • Posts: 707
  • Hypersensitive
Re: compare 2 blocks attributes values
« Reply #8 on: August 16, 2015, 06:51:11 AM »
Hi again Tharwat , thanks for fast attempting , but it does not work
For some values it work, but not for all !!!
For some values it's take the maximum values , for other ones it take the minimum values
sometimes go wrong way

This should be expected because we are comparing values according to their random collection by codes and not by tag name .

If you can modify the tag name to be logic or at least in order so in that time we can sort the text strings by them otherwise mistakes should take a place with no doubt.

Good luck.

serge_c

  • Newt
  • Posts: 39
Re: compare 2 blocks attributes values
« Reply #9 on: August 16, 2015, 01:22:03 PM »
This answer I've got here :http://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/compare-2-blocks-attributes-values/m-p/5773022#M334355
"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."
Code: [Select]
(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)
)
or  onother one
 
Code: [Select]
(vl-load-com)
(defun c:demo (/ *error* ATT BLK INS_PT L1 L2 L3 LAST_E LST OBJ PT RECQ)

   (defun *error* (msg)
      (if req
         (setvar 'ATTREQ req)
      )
      (cond ((not msg))
            ((member msg '("Function cancelled" "quit / exit abort")))
            ((princ (strcat "\n** Error: " msg " ** ")))
      )
      (princ)
   )
   (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 req (getvar 'ATTREQ))
         (setvar 'ATTREQ 0)
         (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))
               )
            )
         )
      )
   )
   (*error* nil)
   (princ)
)
write by onother master : Henrique Silva
If somebody will need this , or use the some Ideeas , enjoy this


« Last Edit: August 16, 2015, 04:25:12 PM by sergiu_ciuhnenco »