copy attribute value

Discussion in 'AutoCAD' started by jclaidler, May 17, 2004.

  1. jclaidler

    jclaidler Guest

    With lisp, how can I copy the attribute value for tag "title1".
    Then assign that copied value to a new title block with tag "description1".

    What I'm doing, is setting up a lisp to convert drawings from one title block to another, and carry over the attribute values.

    Any help would be greatly appreciated.


    Thanks.
     
    jclaidler, May 17, 2004
    #1
  2. jclaidler

    ECCAD Guest

    JC,
    I have a lisp that will swap 'old' title-block to 'new' title-block,
    but need to know particulars. I can tune it to extract all attributes of 'old' TB, but need to know the order of attributes in 'new' title block. Also, Drive / Path to the 'new' title-block.
    No charge. Just send me a sample .dwg with 'old' title-block,
    and one with 'new' title-block.
    E-Mail is:
    remove the nospam.

    Bob Shaw
     
    ECCAD, May 17, 2004
    #2
  3. jclaidler

    Josh Guest

    try the following:

    ;extract data from dotted pair
    (defun dxf (code elist) (cdr (assoc code elist)))

    ;extract attr enames from block ename
    ;return list: ie. (("ELEV" . <Entity name: 400f1718>) ("BW-HP" . <Entity
    name: 400f1720>))
    (defun getattrs (block_ename / data attr_list)
    (setq data (entget block_ename))
    (while (not (= (dxf 0 data) "SEQEND"))
    (if (= (dxf 0 data) "ATTRIB")
    (setq attr_list (cons (cons (dxf 2 data) (dxf -1 data)) attr_list))
    )
    (setq data (entget (entnext (dxf -1 data))))
    )
    (setq attr_list (reverse attr_list))
    )

    (setq old_tb (getattrs <ename of old tb>)); get old tb attributes
    (setq new_tb (getattrs <ename of new tb>)); get new tb attributes

    (setq title1 (dxf 1 (entget (dxf "TITLE1" old_tb)))); get value of old
    attribute
    (setq description1 (entget (dxf "DESCRIPTION1" new_tb))); get dxf data for
    new attribute
    (entmod (subst (cons 1 title1) (assoc 1 description1) description1)); push
    old value into new new tb

    If you have a number of values to change you could wrap the last 3 lines
    into a function and pass the two tags as arguments.


    block to another, and carry over the attribute values.
     
    Josh, May 17, 2004
    #3
  4. jclaidler

    ECCAD Guest

    John,
    You should have the Lisp now, have a good day.

    Bob Shaw
     
    ECCAD, May 17, 2004
    #4
  5. jclaidler

    jclaidler Guest

    this doesn't seem to work
     
    jclaidler, May 18, 2004
    #5
  6. jclaidler

    jclaidler Guest

    here is an example of what is needed....

    copy attribute value for 'title1' to a variable
    copy attribute value for 'title2' to a variable

    after insertion of the new TB,
    assign 1st variable to 'newtitle1'
    assign 2nd variable to 'newtitle2'

    thanks
     
    jclaidler, May 18, 2004
    #6
  7. jclaidler

    Josh Guest

    Did the code error out or just show no apparent change? Try a regen after
    the code runs. You could also add this at the end: (entupd <ename of new
    tb>)
     
    Josh, May 18, 2004
    #7
  8. jclaidler

    jclaidler Guest

    it errored out
     
    jclaidler, May 18, 2004
    #8
  9. I haven't read this thread, but perhaps this may help:

    Code:
    (defun children ( ename / result )
    (if (assoc 66 (entget ename))
    (reverse
    (while
    (/= "SEQEND"
    (cdr
    (assoc 0
    (entget
    (setq ename
    (entnext ename)
    )
    )
    )
    )
    )
    (setq result (cons ename result))
    )
    )
    )
    )
    
    This function, if passed an entity name, will return all
    the child enames of that entity name as an ordered list.
    If the entity is a block instance with attributes, it will
    return a list of all the attribute entities; if the entity
    is a polyline entity, a list of the vertices.

    For example, pull out a list of the entity names, the tag
    names, and the current values for a given block instance:

    Code:
    (mapcar
    '(lambda (ename / data)
    (setq data (entget ename))
    (mapcar
    '(lambda (key) (cdr (assoc key data)))
    '(-1 2 1)
    )
    )
    (children <valid_ename>)
    )
    
    Might return:

    Code:
    (
    (
    <Entity name: 400d3268>
    "TITLE_LINE_1"
    "ELECTRIC HEAT TRACING ISOMETRIC"
    )
    
    (   <Entity name: 400d3270>
    "TITLE_LINE_2"
    "EHT ZONE DRAWING - <DELETED TO PROTECT CLIENT>"
    )
    
    (   <Entity name: 400d3278>
    "TITLE_LINE_3"
    "<DELETED TO PROTECT CLIENT>"
    )
    
    )
    
    So, if used with the appropriate block instances you can
    use it to find attribute values for specified tags and to
    modify targeted blocks. Holler if you need additional info
    <don't want to assume your programming level and / or take
    all the fun out of it>.

    here is an example of what is needed....

    copy attribute value for 'title1' to a variable
    copy attribute value for 'title2' to a variable

    after insertion of the new TB,
    assign 1st variable to 'newtitle1'
    assign 2nd variable to 'newtitle2'

    thanks
     
    michael puckett, May 18, 2004
    #9
  10. jclaidler

    Josh Guest

    I tried the code I sent to using two test blocks with no problem. Could you
    be more specific about where the error occured and what it returned?
     
    Josh, May 18, 2004
    #10
  11. jclaidler

    jclaidler Guest

    What is this for: "<valid_ename>" ??
     
    jclaidler, May 19, 2004
    #11
  12. jclaidler

    jclaidler Guest

    I can't get this to work.
     
    jclaidler, May 19, 2004
    #12
  13. It is a place holder for a valid entity name.

    For example, if variable 'data' contained the dxf data for
    a block insert, its entity name would be associated with
    dxf key -1:

    !data ...

    (
    (-1 . <Entity name: 4006bdc0>) ;; <- this
    (0 . "INSERT")
    (330 . <Entity name: 4006bcf8>)
    (5 . "38")
    (100 . "AcDbEntity")
    (67 . 0)
    (410 . "Model")
    (8 . "0")
    (100 . "AcDbBlockReference")
    (66 . 1)
    (2 . "MyBlock")
    (10 0.0 0.0 0.0)
    (41 . 1.0)
    (42 . 1.0)
    (43 . 1.0)
    (50 . 0.0)
    (70 . 0)
    (71 . 0)
    (44 . 0.0)
    (45 . 0.0)
    (210 0.0 0.0 1.0)
    )

    To retrive it you might use something like

    (progn
    (setq ename (cdr (assoc -1 data)))
    ;; now do something with ename
    (setq enames (children ename))
    ;; ...
    )

    Alternatively, it might be garnered by using entsel ...

    (if (setq ent (entsel))
    (progn
    (setq ename (car ent))
    ;; do something with ename
    (setq enames (children ename))
    ;; ...
    )
    )

    HTH ...

    What is this for: "<valid_ename>" ??
     
    michael puckett, May 19, 2004
    #13
  14. jclaidler

    jclaidler Guest

    With this code:
    (if (setq ent (entsel))
    (progn
    (setq ename (car ent))
    ;; do something with ename
    (setq enames (children ename))
    ;; ...
    )
    )



    I get this result:
    Command: (princ enames)(princ)
    (<Entity name: 7eca2018> <Entity name: 7eca2020> <Entity name: 7eca2028>
    <Entity name: 7eca2030> <Entity name: 7eca2038> <Entity name: 7eca2040> <Entity
    name: 7eca2048> <Entity name: 7eca2050> <Entity name: 7eca2058> <Entity name:
    7eca2060> <Entity name: 7eca2068> <Entity name: 7eca2070> <Entity name:
    7eca2078> <Entity name: 7eca2080> <Entity name: 7eca2088> <Entity name:
    7eca2090> <Entity name: 7eca2098> <Entity name: 7eca20a0> <Entity name:
    7eca20a8> <Entity name: 7eca20b0> <Entity name: 7eca20b8> <Entity name:
    7eca20c0> <Entity name: 7eca20c8> <Entity name: 7eca20d0> <Entity name:
    7eca20d8> <Entity name: 7eca20e0> <Entity name: 7eca20e8> <Entity name:
    7eca20f0> <Entity name: 7eca20f8> <Entity name: 7eca2100> <Entity name:
    7eca2108> <Entity name: 7eca2110> <Entity name: 7eca2118> <Entity name:
    7eca2120> <Entity name: 7eca2128>)
     
    jclaidler, May 19, 2004
    #14
  15. jclaidler

    jclaidler Guest

    This code will save the attribute tag to a variable... how can this be changed to save the 'value' ??

    (setq var1 (cdr (assoc 2 (entget (car (nentsel))))))
     
    jclaidler, May 19, 2004
    #15
  16. jclaidler

    Jeff Mishler Guest

    (assoc 1 .......

    Jeff
     
    Jeff Mishler, May 19, 2004
    #16
  17. Please post the code you've put together so far.


    With this code:
    (if (setq ent (entsel))
    (progn
    (setq ename (car ent))
    ;; do something with ename
    (setq enames (children ename))
    ;; ...
    )
    )
    <snip>
     
    michael puckett, May 19, 2004
    #17
  18. jclaidler

    jclaidler Guest

    I've got this code to work... with selecting the title block.

    (setq result nil)
    (vlax-for block (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object)))
    (setq result (cons (vla-get-name block) result ) ))

    (foreach name (reverse result)

    (if (setq ss (ssget "X" (list '(0 . "INSERT")(cons 2 name)(cons 66 1))))

    (if (not (or (or
    (findfile (strcat "N:/AutoCAD Support Files/Acco Standard Files/Standard Symbols/Symbols/" name ".dwg"))
    (findfile (strcat "N:/AutoCAD Support Files/" name ".dwg"))
    (findfile (strcat "N:/AutoCAD Support Files/Acco Standard Files/Standard Title Blocks/" name ".dwg"))
    ))
    )


    (progn

    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;Save title block information

    (defun get-att-val (TagNme / CurEnt CurObj RetVal)

    (vl-load-com)

    (if (setq CurEnt (car (entsel)))
    (progn
    (setq CurObj (vlax-ename->vla-object CurEnt))
    (if (and
    (eq (vla-get-ObjectName CurObj) "AcDbBlockReference")
    (vla-get-HasAttributes CurObj) )

    (mapcar '(lambda (Att)(if (eq TagNme (vla-get-TagString Att))(setq RetVal (vla-get-TextString Att))))
    (vlax-invoke CurObj "GetAttributes")
    )
    )
    )
    )

    RetVal
    )

    (setq designation1 (get-att-val "DESCRIPTION_ONE"))
    (setq designation2 (get-att-val "DESCRIPTION_TWO"))
    (setq designation3 (get-att-val "DESCRIPTION_THREE"))

    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

    (repeat (setq i (sslength ss))(vl-catch-all-apply 'vla-delete (list (vlax-ename->vla-object (ssname ss (setq i (1- i)))))))

    )


    )
    )
    )



    What I need, is to replace "(if (setq CurEnt (car (entsel)))" with the current selection set, which is select by this code in the program "(if (setq ss (ssget "X" (list '(0 . "INSERT")(cons 2 name)(cons 66 1))))"
     
    jclaidler, May 19, 2004
    #18
  19. jclaidler

    jclaidler Guest

    the code that I'd like to replace is located in "get-att-val"
     
    jclaidler, May 19, 2004
    #19
  20. (ssname SelectionSet index) will retrieve an entity name
    from a selection set. Index is a zero based integer, so
    (ssname ss 0) would retrieve the first entity name from
    selection set 'ss'.

    I'm sorry but I'm swamped today, otherwise I'd offer more
    complete information and code snips. Perhaps someone can
    help fill in the blanks and take the hand off.

    In the interim, the online help details all this information
    rather well; in concert with the kindly folks here a
    combination that's pretty hard to beat.

    </nudge>


    I've got this code to work... with selecting the title block.

    <big snip>

    What I need, is to replace "(if (setq CurEnt (car (entsel)))" with the current selection set, which is select by this code in the
    program "(if (setq ss (ssget "X" (list '(0 . "INSERT")(cons 2 name)(cons 66 1))))"
     
    michael puckett, May 19, 2004
    #20
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.