Selection by attribute value

Discussion in 'AutoCAD' started by yavid, Aug 18, 2004.

  1. yavid

    yavid Guest

    I have a drawing containing many copies of a block called "point". Each "point" block has 3 attributes, elev, point and desc. I need to write a LISP that will allow me to select a block based on the value of the point attribute. Any ideas?
     
    yavid, Aug 18, 2004
    #1
    1. Advertisements

  2. yavid

    Jim Claypool Guest

    You will have to first select all of the blocks
    (setq ss (ssget "x" ' ((0 . "INSERT") (2 . "POINT"))))
    Then step through each one to get the attribute values and look for the
    values you want.

    "point" block has 3 attributes, elev, point and desc. I need to write a
    LISP that will allow me to select a block based on the value of the point
    attribute. Any ideas?
     
    Jim Claypool, Aug 18, 2004
    #2
    1. Advertisements

  3. Here is a subroutine to create a selection set of the found blocks. Note -
    there are no checks for the Attribute Value type (int,real,str).

    (defun GetBlock (BlockName AttribName AttribValue /)
    (if (setq ss (ssget "X" (list (cons 0 "INSERT") (cons 2 BlockName))))
    (progn
    (setq SSN (ssadd))
    (setq KK 0 KS (sslength SS))
    (setq BlocksFound 0)
    (while (< KK KS)
    (setq EG (entget (ssname SS KK)))
    (setq EN (entget (entnext (cdr (assoc -1 EG)))))
    (while (/= (cdr (assoc 0 EN)) "SEQEND")
    (if (and (= (cdr (assoc 2 EN)) AttribName) (= (cdr (assoc 1 EN))
    AttribValue))
    (progn
    (ssadd (cdr (assoc -1 EG)) SSN)
    (setq BlocksFound (1+ BlocksFound))
    ;here is were you can do something to the block attribute
    values
    )
    )
    (setq EN (entget (entnext (cdr (assoc -1 EN)))))
    )
    (setq KK (1+ KK))
    )
    )
    )
    (if SSN (princ (strcat "\n" (itoa BlocksFound) " Block(s) = " BlockName "
    with Attribute = " AttribName " & Value = " AttribValue " was Found!")))
    (princ)
    )
     
    Alan Henderson @ A'cad Solutions, Aug 18, 2004
    #3
  4. yavid

    yavid Guest

    I am fairly new to LISP and I am getting pretty confused. I guess I should have explained everything a little better. I have a drawing containing many blocks called "point". Each point block has 3 attributes; elev, point and desc. The point attribute is always the second attribute and has a unique value for each block. I need to be able to give autocad a list of point values, have it find each one (in order) and then connect them with a polyline. For example, I run the lisp and give it the numbers 100-110, the lisp begins with 100, finds the block whose point attribute has a value of 100, then the block whose point attribute has a value of 101 and so on. Then the LISP would connect the block insert points with a polyline (beginning with 100 and ending in 110). I tried running the LISP you gave me just to see if I could use it as a starting point but I keep getting an error that says: bad SSGET list value
    I appreciate your help.
     
    yavid, Aug 18, 2004
    #4
  5. I left off how to start the program.
    (GetBlock "YourBlockName" "YourAttributeName" "YourAttributeValue")
    This program was just a start to show you how to find all the blocks with
    specific value.
    You would have to modify the program to perform to your requirements.
    Pseudo-code
    get range of point numbers
    getstring - as range of numbers (more difficult)
    2 getreals - start and end numbers (easier)
    get all blocks via ssget
    set value of starting point number
    use while to find first point number in block
    have error message if number not found
    start pline command
    draw pline from found point - (cdr (assoc 10 EG)) is insertion point of
    block
    use while to find next block
    have error message if number not found
    continue pline command
    loop until last number found
    end pline command
     
    Alan Henderson @ A'cad Solutions, Aug 18, 2004
    #5
  6. yavid

    yavid Guest

    Thank you. I appreciate the help.
     
    yavid, Aug 18, 2004
    #6
  7. yavid

    Jim Claypool Guest

    (defun connect-the-dots (blkstart blkend / pt blkcnt cnt ss)
    (setq ss (ssget "x" '((0 . "INSERT") (2 . "POINT"))))
    (if ss
    (progn
    (setq blkcnt blkstart)
    (while (<= blkcnt blkend)
    (setq cnt 0)
    (repeat (sslength ss)
    (setq pt nil)
    (setq ename (ssname ss cnt))
    (if (= (atoi (cdr (assoc "POINT" (getatts ename)))) blkcnt)
    (progn
    (setq pt (cdr (assoc 10 (entget ename))))
    (if (= blkcnt blkstart)
    (command ".pline" pt)
    (command pt)
    );end if
    ));end if
    (setq cnt (1+ cnt))
    );end repeat
    (setq blkcnt (1+ blkcnt))
    );end while
    (command)
    ));end if
    (princ)
    )

    (defun GetAtts (Obj)
    (setq obj (vlax-ename->vla-object obj))
    (mapcar
    '(lambda (Att)
    (cons (vla-get-TagString Att) (vla-get-TextString Att))
    )
    (vlax-invoke Obj "GetAttributes")
    )
    )

    should have explained everything a little better. I have a drawing
    containing many blocks called "point". Each point block has 3 attributes;
    elev, point and desc. The point attribute is always the second attribute
    and has a unique value for each block. I need to be able to give autocad a
    list of point values, have it find each one (in order) and then connect them
    with a polyline. For example, I run the lisp and give it the numbers
    100-110, the lisp begins with 100, finds the block whose point attribute has
    a value of 100, then the block whose point attribute has a value of 101 and
    so on. Then the LISP would connect the block insert points with a polyline
    (beginning with 100 and ending in 110). I tried running the LISP you gave
    me just to see if I could use it as a starting point but I keep getting an
    error that says: bad SSGET list value
     
    Jim Claypool, Aug 18, 2004
    #7
  8. yavid

    yavid Guest

    Thanks. I will run this step by step and see if I can follow the logic. I appreciate your help.
     
    yavid, Aug 18, 2004
    #8
  9. yavid

    Jim Claypool Guest

    You're welcome. If you have trouble following it let me know and I will try
    to explain.

    I appreciate your help.
     
    Jim Claypool, Aug 19, 2004
    #9
  10. yavid

    yavid Guest

    The LISP you wrote works great, it is exactly what I required. I put a couple stops in it so I could follow through it, it helped me understand how it works. I have one question though. Is there a way to make it work without using activex? I don't know anything about activex so if I were to have written it I would likely have had to go an entirely different route.
     
    yavid, Aug 20, 2004
    #10
  11. yavid

    Jim Claypool Guest

    Here you go.

    (defun getAtts (e / attlist)
    (while (= (cdr (assoc 0 (entget (setq e (entnext e))))) "ATTRIB")
    (setq attlist (cons (cons (cdr (assoc 2 (entget e))) (cdr (assoc 1 (entget
    e)))) attlist))
    )
    attlist
    )

    couple stops in it so I could follow through it, it helped me understand how
    it works. I have one question though. Is there a way to make it work
    without using activex? I don't know anything about activex so if I were to
    have written it I would likely have had to go an entirely different route.
     
    Jim Claypool, Aug 20, 2004
    #11
  12. yavid

    yavid Guest

    Works great. Thanks.
     
    yavid, Aug 20, 2004
    #12
  13. yavid

    dieptp

    Joined:
    Oct 5, 2017
    Messages:
    1
    Likes Received:
    0
    Sorry dude, i'm noob. Please tell me how to load and use this lisp. I used Appload but cannot call your lisp out
     
    dieptp, Oct 5, 2017
    #13
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.