Jump to content

Add attributes into existing dynamic blocks


Bill McKown

Recommended Posts

Hi,

 

Wondering if someone could help me out with some code advice. I need to add new attributes into existing dynamic blocks. I know the block name I just want to automatically add attributes so the user doesn't have to do this manually for hundreds of blocks. I don't want to explode the blocks just add to them. I know AutoLISP fairly well, but I think it may be easier done in VLISP. Any help would be appriciated.:)

 

Thanks,

Bill

Link to comment
Share on other sites

  • Replies 20
  • Created
  • Last Reply

Top Posters In This Topic

  • ADSK2007

    9

  • Bhull1985

    6

  • Lee Mac

    4

  • Bill McKown

    2

Welcome to CADTutor Bill

 

Unless I've misunderstood your requirements, could you not add the necessary attribute definitions (ATTDEFs) to the dynamic block definition using the Block Editor (BEDIT), then apply the changes to all references of the dynamic block using the ATTSYNC command?

Link to comment
Share on other sites

Welcome to CADTutor Bill

 

Unless I've misunderstood your requirements, could you not add the necessary attribute definitions (ATTDEFs) to the dynamic block definition using the Block Editor (BEDIT), then apply the changes to all references of the dynamic block using the ATTSYNC command?

 

Thanks for your reply-

I can do exactly what I want with the Bedit command, but want to automate this to add to many blocks. I can't seem to call the Bedit command in a LISP routine without the dialog boxs. Ive tried cmddia =0, attdia=0, dia, Attreq=0.

Can the BEDIT command be called from LISP?

 

thanks,

B

Link to comment
Share on other sites

If you necessarily need to automate the process, I would recommend adding a VLA Attribute Definition object directly to the Block Definition Collection object using the addattribute method for the dynamic block to be updated, and then use ATTSYNC to update all references of the dynamic block.

 

Here is a simple example to point you in the right direction:

(defun c:addattrib ( / blk )
   (while
       (not
           (or (= "" (setq blk (getstring t "\nName of block to update: ")))
               (tblsearch "BLOCK" blk)
           )
       )
       (princ (strcat "\nBlock \"" blk "\" not found."))
   )
   (if (/= "" blk)
       (progn
           (vla-addattribute
               (vla-item (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object))) blk)
               (getvar 'textsize)
               acattributemodelockposition
               "New Attribute"
               (vlax-3D-point 0 0)
               "NEW_TAG"
               "New Value"
           )
           (command "_.attsync" "_N" blk)
       )
   )
   (princ)
)
(vl-load-com) (princ)

Link to comment
Share on other sites

  • 7 months later...

Hi Lee

 

Could you please tell me how I can add more than one attribute to this code? The code works great however i don't know how to add to it.

 

Thanks

 

Adsk

Link to comment
Share on other sites

Could you please tell me how I can add more than one attribute to this code? The code works great however i don't know how to add to it.

 

The code uses the ActiveX addattribute method to add the Attribute Definition to the Block Definition, hence, to add multiple Attribute Definitions you would need multiple calls to the addattribute method - however, I would recommend assigning the Block Definition argument (the vla-item expression) to a local variable to avoid repeatedly retrieving this object.

Link to comment
Share on other sites

If you necessarily need to automate the process, I would recommend adding a VLA Attribute Definition object directly to the Block Definition Collection object using the addattribute method for the dynamic block to be updated, and then use ATTSYNC to update all references of the dynamic block.

 

Here is a simple example to point you in the right direction:

   ...
           (vla-addattribute
               (vla-item (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object))) blk)
               (getvar 'textsize)
               acattributemodelockposition
               "New Attribute"
               (vlax-3D-point 0 0)
               "NEW_TAG"
               "New Value"
           )
...

[code][/quote]


That's the part you'd need to add again into your code, such as this (modified Lee's above)

[code]
(defun c:addattrib ( / blk )
   (while
       (not
           (or (= "" (setq blk (getstring t "\nName of block to update: ")))
               (tblsearch "BLOCK" blk)
           )
       )
       (princ (strcat "\nBlock \"" blk "\" not found."))
   )
   (if (/= "" blk)
       (progn
           (vla-addattribute
               (vla-item (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object))) blk)
               (getvar 'textsize)
               acattributemodelockposition
               "New Attribute"
               (vlax-3D-point 0 0)
               "NEW_TAG"
               "New Value"
           );[b]end attribute new_tag[/b]
           (vla-addattribute
               (vla-item (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object))) blk)
               (getvar 'textsize)
               acattributemodelockposition
               "New Attribute 2"
               (vlax-3D-point 0 0)
               "NEW_TAG_2"
               "New Value 2"
           );[b]end attribute NEW_TAG_2[/b]

           (command "_.attsync" "_N" blk)
       )
   )
   (princ)
)
(vl-load-com) (princ)

 

if im understanding correctly.

Just taking care of the easier requests in respect of Lee's time, hope no one gets offended.

Link to comment
Share on other sites

bhull1985

 

You are correct, I don't know why I missed those lines. The answer was already there. I will pay more attention next time

My appologies,

 

Fred

Link to comment
Share on other sites

Thanks Brandon :thumbsup:

 

A minor point for efficiency: since all Attribute Definitions are being added to the same Block Definition, I would suggest assigning the Block Definition object to a local variable to avoid the need to retrieve the Application Object, Document Object, Blocks Collection & Block Definition from the Blocks Collection for every Attribute Definition added, e.g.:

 

(defun c:addattribs ( / blk [color=red]def[/color] )
   (while
       (not
           (or (= "" (setq blk (getstring t "\nName of block to update: ")))
               (tblsearch "BLOCK" blk)
           )
       )
       (princ (strcat "\nBlock \"" blk "\" not found."))
   )
   (if (/= "" blk)
       (progn
           [color=red](setq def (vla-item (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object))) blk))[/color]
           (vla-addattribute [color=red]def[/color]
               (getvar 'textsize)
               acattributemodelockposition
               "New Attribute 1"
               (vlax-3D-point 0 0)
               "NEW_TAG1"
               "New Value 1"
           )
           (vla-addattribute [color=red]def[/color]
               (getvar 'textsize)
               acattributemodelockposition
               "New Attribute 2"
               (vlax-3D-point 0 (- (* 1.5 (getvar 'textsize))))
               "NEW_TAG2"
               "New Value 2"
           )
           (command "_.attsync" "_N" blk)
       )
   )
   (princ)
)
(vl-load-com) (princ)

Link to comment
Share on other sites

Lee your routine is working on an existing block. how do I change the routine to create a block, ask for a name for the block then add the attributes to it?

 

Also, is it possible to link field info from "Drawing properties" to your lisp? Let's say I already created 5 names with values inside "Drawing properties" window and now I want to associate them to the new created block using your lisp.

Link to comment
Share on other sites

Hi again.

For clarification purposes would you please look at the following:

Firstly do you have the block objects already on your screen, as in what you'd expect to be doing in a "wblock" command? Where the block is already constructed and placed into a drawing, and you're giving it it's own .dwg extension once removed from the rest of the dwg....this is almost like a "block extraction"

Or by create used in the context of a lisp routine could mean to "place into drawing" i.e. insert an existing block and rename that block to a new name where the new attributes are included, making it different from the original and thus requiring a new name?

You ask specifically for Lee, but keep in mind this is a public forum where many gurus come to answer questions. I'm not one of them, but I still like to help when I can :) Just wanted to make mention that Lee will undoubtedly be able to assist in a lisp problem but sometimes it can be akin to asking the CIA what the time is. If that analogy makes sense....I hope it does heh. And not that anyone blames you from requesting Lee's help but he's a busy man and you limit yourself from getting answers from the other gurus. Probably not intentional or maybe it is- all the more reason to ask and see.

Link to comment
Share on other sites

bhull1985

 

Hello bhull, I guess you mis-understood me or maybe it's the way I wrote the last post (in both ways, I am sorry for not being clear) - Just like this post, I am placing your name at the begining and it means a reply to your comment. I thought I am doing the same for Mr. Lee. However; I did not mean I am asking only him to answer my question. I have respect for all of you and understand everyone is busy. Please forgive me if I write thing in a way that doesn't look right. All of you are great and helped me alot when you had the time and I really appreciate this. If you were in my town, I sure would somehow pay back or show more respect for each one of you. We all are experienced in something different, I hope some day I could be a helping hand for something different to help you out. I am sorry if my lisp knowledge is not as advanced as you guys and that is why I need your help with things. I hope you and others accept my apology.

 

Now please let me explain what we are doing and what we would like to accomplish. we manufacture Complex electronic devices. We use AutoCAD and SolidWorks to design and model every part. Those familiar with SolidWorks know how the software works and how a product gets developed in the application. Unfortunately not all designers here know the software well enough and therefore we are in the process of advancing the AutoCAD functions in order to produce same results in Solidworks.

 

Let me give a simple example. We draw a table with a top and 4 legs, 3D first then generate 2D drawings - (I know this is not the best practice but that is out of my control). Anyway, once all parts are drawn, we need to create blocks from drawn objects (table top, table legs, etc.) What we were originally asking was, we do know what should each block contain with attributes. This is why the attribute information is already inside the lisp. However that lisp only works when you already have a block. What we want to achive is a lisp routine that first activate the block command and ask for a name for the block, then apply those attributes (the attributes we already have inside the lisp) inside that block. SO this is the process of draw an object, make it a block with attributes and move on to next drawing (ex. a chair with 4 legs, arm rest, back rest, etc.).

 

My question from Mr. Lee was to use Fields as attributes inside the lisp routine which means, we create the same attribute information inside drawing properties window. This window is linked to an excel sheet and all Assemblies, Sub assemblies and parts are already named inside the the excel sheet with more info (ex. description of the part, size, finish and so on).

 

Anyway, The lisp above works fine on the blocks that are already created. We wanted the first part of the routine to change from "Name of the block to update" to "enter a name for the new block" which means we are creating a block and giving it a name, the rest of the routine if perfect.

 

I hope I could clearly explain what we are looking for. Again please accept my apology

 

Best Regards

 

Adsk

Link to comment
Share on other sites

Thank you for taking the time to very clearly and concisely explain your thoughts and the issue at hand.

The irony is not lost on me that this is the time in which I should reply and then wait for Mr. Lee Mac or other autolisp Guru to give you a more correct response than one I would be able to supply you with.

I do have one query though...and I think it's pretty important to your eventual program. Do you want to select all of the objects before assigning a name to them? If there are multiple small solid shapes that comprise a larger portion of the table and these portions fit together to complete your table in full, and you want this program to operate by

1 asks for objects that belong to table piece or "larger object"

2 asks for the name of what the block should be

3 makes all of the objects selected into the block with name of what you told it

4 supplies new block with multiple attributes and saves the definition

...

5 (?) closes the current dwg and opens the next? This is possible but depending on what you need (likely quantity of dwg related) it may be easier to run the program for all necessary items then manually save the dwg and close and open the next...

 

I think this process would be easily achievable with autolisp indeed, but as previously mentioned here is where we should wait for a better lisp coder

Link to comment
Share on other sites

Hi bhull

 

the table and the chair was just an example to make things simple to understand, we don't make furniture here - anyway, to answer your questions please see below

Q:Do you want to select all of the objects before assigning a name to them?

A: Yes, it would be nice if we could select by window or multiple entities at once - we only need a top view of the part to make it as a block and add attributes to it. The block will be used in a table to identify the components of an assembly.

 

Q:If there are multiple small solid shapes that comprise a larger portion of the table and these portions fit together to complete your table in full

A: Each part will be a block, multiple objects are sub assembly and they are recognized as a group, therefore they wont be inside a block together

 

Q:you want this program to operate by

1 - asks for objects that belong to table piece or "larger object"

A: asking to select entities would be fine, no need for a complex routine

 

2 asks for the name of what the block should be

A: yes

 

3 makes all of the objects selected into the block with name of what you told it

A: Yes

 

4 supplies new block with multiple attributes and saves the definition

A: yes

 

5 (?) closes the current dwg and opens the next?

A: there are no multiple drawings, we draw all objects inside one drawing. Blocks are saved inside the drawing itself

 

Regards

 

Adsk

Link to comment
Share on other sites

http://forums.autodesk.com/t5/Visual-LISP-AutoLISP-and-General/Block-Automated-attribute-values-add-subtract/m-p/4590267/highlight/false#M316592

 

or

 

(defun c:adsk (/ ss pt i ent elist)
 ; Get Entities
   (while (not ss)
   (princ "\nSelect Objects to Convert to Blocks:")
   (setq ss (ssget '((-4 . "<NOT") (0 . "INSERT,POLYLINE,VIEWPORT") (-4 . "NOT>"))))
   ) ;_  end while
 ; Get Block Name and Base Point
   (while (or (not bn)
          (not (snvalid bn))
      ) ;_  end or
   (setq bn (getstring "Specify Block Name: "))
   ) ;_  end while
   (initget 1)
   (setq pt (getpoint "Specify Base Point for Block: "))
;;; Create BLOCK Header
   (entmake (list (cons 0 "BLOCK") (cons 10 pt) (cons 2 bn) (cons 70 0)))
;;;STEP THRU THE SET
   (setq i (sslength ss))
   (while (>= i (setq i (1- i)) 0)
   (setq ent   (ssname ss i)
         elist (entget ent)
   ) ;_  end setq
   (entmake elist)
   ) ;_  end while
;;;FINISH THE BLOCK DEFINITION
   (entmake (list (cons 0 "ENDBLK") (cons 8 "0")))
;;;Insert the Block & Delete Originals
   (entmake (list (cons 0 "INSERT") (cons 2 bn) (cons 8 "0") (cons 10 pt)))
   (command "_.ERASE" ss "")
   (redraw)
   (AddAttribs)    
   (prin1)
) ;_  end defun
(defun addattribs ( / blk def)
   (while
       (not
           (or (= "" (setq blk bn))
               (tblsearch "BLOCK" blk)
           )
       )
       (princ (strcat "\nBlock \"" blk "\" not found."))
   )
   (if (/= "" blk)
       (progn
           (setq def (vla-item (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object))) blk))
           (vla-addattribute def
               (getvar 'textsize)
               acattributemodelockposition
               "New Attribute 1"
               (vlax-3D-point 0 0)
               "NEW_TAG1"
               "New Value 1"
           )
           (vla-addattribute def
               (getvar 'textsize)
               acattributemodelockposition
               "New Attribute 2"
               (vlax-3D-point 0 (- (* 1.5 (getvar 'textsize))))
               "NEW_TAG2"
               "New Value 2"
           )
           (command "_.attsync" "_N" blk)
       )
   )
   (princ)
)
(vl-load-com) (princ)

 

HTH ADSK, sorry for the delay. You're not the only one who's busy ;)

Link to comment
Share on other sites

If you would need to include POLYLINES as objects to convert to your blocks I believe the word POLYLINE should be removed from the 5th line. Someone might come and inform why they're not included in the first place but afaik it should be quite easy to allow them in selection again.....simply removing the entity type name from the selection filter should do it.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...