Change block attribute values

Discussion in 'AutoCAD' started by dhorton, Oct 21, 2004.

  1. dhorton

    dhorton Guest

    Hello,

    I have over 200 drawings each containing up to 200 blocks named "RoomData". Within the block I have an attribute named "DfESCat". This attribute will contain a value from 1 thru' to 23. What I need to do is change every instance of 1 thru' to 9 to having a leading zero, i.e 01 thru to 09.

    I have started to write a bit of lisp......I can easily create a selection set of all the "RoomData" blocks and search thru' each one to find the attribute "DfESCat".....

    but, how do I assign the attribute value to a variable, analyse it to see if I need to add a leading zero and then update my block?

    I've enclosed my first bit of Lisp........any help and pointers in the right direction will be very much appreciated.

    (setq blk (ssget "x"(list (cons 0 "insert") (cons 2 "RoomData"))))
    (setq blen (entget (ssname blk 0)))
    (setq att (entget (entnext (cdr (assoc -1 blen)))))
    (while (/= (cdr (assoc 0 att)) "SEQEND")
    (if (= (cdr (assoc 2 att)) "ROOMDFESCAT")
    (progn
    ....................


    thanks

    dom
     
    dhorton, Oct 21, 2004
    #1
  2. dhorton

    T.Willey Guest

    (setq blk (ssget "x"(list (cons 0 "insert") (cons 2 "RoomData"))))
    (while (/= (sslength blk) 0)
    (setq att (ssname blk 0))
    (setq att1 att)
    (while (setq att1 (entnext att1))
    (setq att1 (entget att1))
    (if (= (cdr (assoc 2 att1)) "ROOMDFESCAT")
    (progn
    (setq str1 (cdr (assoc 1 att1))
    slen1 (strlen str1)
    ); end setq
    (if (= slen1 1)
    (entmod (subst (cons 1 (strcat "0" str1)) (assoc 1 att1) att1))
    );end if
    ); end progn
    ); end if
    ); end while
    (ssdel att blk)
    ); end while

    See if this works for you.
    Tim
     
    T.Willey, Oct 21, 2004
    #2
  3. dhorton

    dhorton Guest

    Hi Tim,

    thanks for the reply

    i tried your lisp but I got the error:
    error: bad argument type: lentityp

    I traced it using the vlisp console and it got to the line:
    (while (setq att1 (entnext att1))

    any ideas?

    thanks

    dom
     
    dhorton, Oct 21, 2004
    #3
  4. dhorton

    T.Willey Guest

    (setq blk (ssget "x"(list (cons 0 "INSERT") (cons 2 "RoomData"))))
    (while (/= (sslength blk) 0)
    (setq att (ssname blk 0))
    (setq att1 (entget att))
    (while (setq att1 (entnext (cdr (assoc -1 att1))))
    (setq att1 (entget att1))
    (if (= (cdr (assoc 2 att1)) "ROOMDFESCAT")
    (progn
    (setq str1 (cdr (assoc 1 att1))
    slen1 (strlen str1)
    ); end setq
    (if (= slen1 1)
    (entmod (subst (cons 1 (strcat "0" str1)) (assoc 1 att1) att1))
    );end if
    ); end progn
    ); end if
    ); end while
    (ssdel att blk)
    ); end while

    This seemed to work on my test drawing. See if it does for you.
    Tim
     
    T.Willey, Oct 21, 2004
    #4
  5. dhorton

    David Kozina Guest

    Off the subject, as usual, but that is WAY too close to being a disgusting
    name for an attribute, sorry...
     
    David Kozina, Oct 21, 2004
    #5
  6. dhorton

    dhorton Guest

    Tim,

    this seems to work on my test drawing, i'll need to have a closer look tomorrow when i'm back in work.

    Basically, your program concatenates a zero onto the
    variable?

    I appreciate your help on this, and would it be to much to ask if you would put a few comments by the code in the middle!?, I think I understand the general workings but I could do with the light shining on it a bit more!

    Thanks once again

    dom
     
    dhorton, Oct 21, 2004
    #6
  7. dhorton

    T.Willey Guest

    Sure no problem.

    (setq blk (ssget "x"(list (cons 0 "INSERT") (cons 2 "RoomData"))))
    ;| this is saying while the selection set blk
    has items in it do the rest
    |;
    (while (/= (sslength blk) 0)
    (setq att (ssname blk 0))
    (setq att1 (entget att))
    ; above just setting to a different varaible
    ; so that the blk name can be taken out
    ; of the selection set
    (while (setq att1 (entnext (cdr (assoc -1 att1))))
    ; stepping through the block item, once it hits
    ; the "SEQEND" it will return nil and stop this while
    (setq att1 (entget att1))
    (if (= (cdr (assoc 2 att1)) "ROOMDFESCAT")
    ; check the tag
    (progn
    (setq str1 (cdr (assoc 1 att1)) ; get the tag value
    slen1 (strlen str1) ; get the length of the tag value
    ); end setq
    ;| this if statement is saying if the length of the
    string is equal to 1 character and the ascii value
    of that character is between 48 and 57, then add a
    "0" before it. since you only wanted to change
    the value for numbers between 1-9, but this code
    will also add a "0" to the attribute if it equals "0"
    |;
    (if (and (= slen1 1) (<= 48 (ascii str1) 57))
    (entmod (subst (cons 1 (strcat "0" str1)) (assoc 1 att1) att1))
    );end if
    ); end progn
    ); end if
    ); end while
    (ssdel att blk)
    ; above just removes the block from the selection set
    ); end while


    Hope that cleared some of it up. You might want to take this version because I updated it some more within the code. The one I posted first would have but a "0" before the attribute if it was a letter, now it will only put a "0" if it is a number.

    Tim
     
    T.Willey, Oct 21, 2004
    #7
  8. dhorton

    T.Willey Guest

    David,

    Good catch... I didn't even see that, but you are correct.

    =D

    Every one needs a laugh at work, this was one of them.

    Tim
     
    T.Willey, Oct 21, 2004
    #8
  9. dhorton

    dhorton Guest

    Tim,

    Cheers for the comments and revamped code. This will be of help to me in learning the intricacies of AutoLISP!

    Thanks again

    dom
     
    dhorton, Oct 22, 2004
    #9
  10. dhorton

    dhorton Guest

    Thanks all for your responses....a continuation of the theme....

    The "Roomdata" block has an attribute named "roomarea". The block sits within a polyline outlining the actual area of the room. What would like to do is in it's most basic form, select a "Roomdata" block, select the corresponding polyline and update the "roomarea" attribute with that gleaned from the polyline.

    Adapting Tim's code and searching on this discussion group, I can get the the attribute value and polyline area, but i'm having trouble fitting it all together!.....................

    -------------

    ;;;this bit of code gets the value in the "Roomarea" attribute of the block
    (setq blk (ssget))
    (setq att (ssname blk 0))
    (setq att1 (entget att))
    ;
    (while (setq att1 (entnext (cdr (assoc -1 att1))))
    (setq att1 (entget att1))
    ;
    (if (= (cdr (assoc 2 att1)) "ROOMAREA")
    (progn
    (setq blkarea (cdr (assoc 1 att1)))
    );end progn
    );end if
    );end while
    ;
    ;
    ;;;this bit of code gets the area of the polygon
    ;
    (setq pgn (ssget))
    (setq ss1 (ssname pgn 0))
    (setq parea (rtos(/ (vlax-curve-getArea pgn) 1000000) 2 1))

    ;;;;now need to replace the "blkarea" variable with the "parea" variable...
     
    dhorton, Oct 22, 2004
    #10
  11. dhorton

    T.Willey Guest

    Dom,

    Now that you have your area as a string all you have to do is replace it within the attribute entity. You have the attribute entity stored as "att1". So the function you is "subst" with "entmod". The way to use it here is like:
    (entmod ; you need this to modify the entity
    (subst ; this is the substitute function call within lisp
    (cons 1 parea) ; this the the new value, you have to use "cons" to make it a dotted pair like the original value in the attribute entity
    (assoc 1 att1) ; this is the value we want to substitute the new value for
    att1 ; this is the entity that we want to substitute it in
    )
    )

    Hope that is clear. You may have to watch for word wrap with some of the explainations.

    Tim
     
    T.Willey, Oct 22, 2004
    #11
  12. dhorton

    dhorton Guest

    Tim,

    thanks for the help......

    i'll have a crack at it when I get a mo'

    cheers

    dom
     
    dhorton, Oct 25, 2004
    #12
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.