Jump to content
tmelancon

Get VALUE of Attribute in Block and insert in new block

Recommended Posts

tmelancon

I have a basic routine I run to delete a title block, purge all, then inserts a new title block. The one value I need to retrieve from the old title block to insert in the new title block is "DIMENSION" so I am trying to expand it to do the following:

A) prompt user to select which block is to be deleted and replaced

B) get the value of attribute tag "DIMENSION"

C) delete old block

D) purge all

E) insert the new block

F) populate the new title block attribute "DIMENSION" with the text string or VALUE from the old title block.

 

This is what I currently have, and it works great but I am hoping to expand it to automate the dimension.

(defun C:bpv ()
(princ "\nSelect a Titleblock to be erased and replaced?")
(command "erase" PAUSE "")
(command "-purge" "all" "" "N")
(command "-insert" "TITLEBLOCK.DWG" "9,0" "" "" "" "explode" "last")
(PRINC))

 

Any and all help is tremendously appreciated because I know how busy everyone is. God bless.

Share this post


Link to post
Share on other sites
dlanorh

Try this. It uses VL to get the the attributes and find the attribute value, and again for setting it in the new block. Minor testing and NO error checking. The title block must be on an unlocked layer.

 

(defun c:bpv ( / ss obj atts)

  (prompt "\nSelect a Titleblock to be replaced : ")
  (setq ss (ssget "_+.:E:S:L" '((0 . "INSERT") (66 . 1)))
        obj (vlax-ename->vla-object (ssname ss 0))
        atts (vlax-invoke obj 'getattributes)
  );end_setq
  
  (foreach att atts
   (if (= (strcase (vlax-get-property att 'tagstring)) "DIMENSION") (setq t_val (vlax-get-property att 'textstring)))
  );end_foreach
  
  (vla-delete obj)
  
  (command "-purge" "_A" "*" "_N")
  (command "-insert" "TITLEBLOCK.DWG" "9,0" "" "" "")
  (command "explode" "last" "")
  
  (setq obj (vlax-ename->vla-object (entlast))
        atts (vlax-invoke obj 'getattributes)
  );end_setq
  
  (foreach att atts
   (if (= (strcase (vlax-get-property att 'tagstring)) "DIMENSION") (vlax-put-property att 'textstring t_val))
  );end_foreach
  
  (princ)
);end_defun

 

Share this post


Link to post
Share on other sites
tmelancon

dlanorh,

 

Thanks for your kind reply. I do appreciate all of your hard work. I am getting the following error:

 

Error: ActiveX Server returned the error: unknown name: "GETATTRIBUTES"

Share this post


Link to post
Share on other sites
tmelancon

Would even be open to a modification of adding multiple attributes in the future, i.e. drawing dates and stuff like that from the old title blocks. If anyone is up for the challenge I greatly appreciate any and all support. I am also working on debugging the current code, I have just been out of LISP for a minute :)

Share this post


Link to post
Share on other sites
dlanorh

Is this happening before the new block is inserted or after?

Share this post


Link to post
Share on other sites
tmelancon

After. The routine runs, deletes the block, then nothing happens and I see the error. Hope this helps and again thanks for your replies I appreciate it. Hope to hear from you soon. 

Share this post


Link to post
Share on other sites
dlanorh

When I tested this with one of my own attributed blocks in a drawing, and stored externally in a differently named drawing, it worked.

 

If the lisp gets to the recently inserted block, it has already invoked a 'getattributes on the deleted block. This makes me think that the new Title block is/has a block within a block within the drawing. This means that once the new titleblock drawing is exploded, the block left has no attributes because they are still inside a block. This would cause the error you are seeing.

 

Check your new titleblock drawing by opening it, then opening block within in the block editor to see if there is yet another block inside it

 

I hope that makes sense

Share this post


Link to post
Share on other sites
Tharwat

@dlanorh You need to move the two expressions that gets the entlast (obj) & getattributes (atts) before the explode command.

Share this post


Link to post
Share on other sites
dlanorh
36 minutes ago, Tharwat said:

@dlanorh You need to move the two expressions that gets the entlast (obj) & getattributes (atts) before the explode command.

 

That will get the inserted drawing, not the block within it, unless I'm misunderstanding how this is all set up. That's how the OP's original code led me.

 

If the drawing is the block then the explode would leave an exploded titke block, but with no drawing supplied it's difficult to figure out.

  • Like 1

Share this post


Link to post
Share on other sites
dlanorh

I'm now wondering if I've left QAFLAGS set to 1 and perhaps I shouldn't have the final "" in the explode command.

 

I'll have to wait until I'm in the office tomorrow to find out. It would explain some anomolies I've been having.

Share this post


Link to post
Share on other sites
tmelancon

Thanks guys so much for the continued discussions. All of our “title blocks” are created in and stored individually as “clientname-facility.dwg” in our master blocks folder. Now the actual block with attributes within that .dwg is named TBLOCK-NEW. Is this not typical? I have been doing it this way for a decade YIKES! Could this be where I am confusing you guys?

 

So a quick run down ... When I open an old drawing I run my routine which deletes the current title block named TBLOCK. After TBLOCK gets deleted It runs the purge all to get rid of any existing references so we have nothing conflicting when we insert our new block (or drawing with my titleblock in it?), next is to insert clientname-facility.dwg with the attributed block inside called TBLOCK-NEW, finally we explode clientname-facility.dwg because the insert command puts that block in as a block on its own thus not allowing the user to select it to edit attributes. 

 

Gosh I didn’t think it would be this complicated but I guess when your talking about code you have to evaluate all of these things. I will be in the office first thing in the morning as well I will be in touch. Looking forward to your response. Thanks guys. 

Share this post


Link to post
Share on other sites
dlanorh

OK. QAFLAGS WAS set to 1 :facepalm::oops:

 

So try this. I had included a "" after the "last" in the explode command, but this was required because of the faulty sysvar setting.

 

I've removed this and added a while loop which will explode the last entity until it finds a block with attributes. This should take care of a block within a block within the drawing. I've also added (vl-load-com) after the end of the lisp routine to make sure the VL bits are loaded into AutoCAD. This must be part of the saved file.

 

This works in my tests, however there is only one block within the block, and one block within the drawing in my test scenario. If there are more blocks within the drawing or more blocks within the block within the drawing;  it will fail and we'll have to think of expanding to find the correct block.

   

(defun c:bpv ( / ss obj atts flg)

  (prompt "\nSelect a Titleblock to be replaced : ")
  (setq ss (ssget "_+.:E:S:L" '((0 . "INSERT") (66 . 1)))
        obj (vlax-ename->vla-object (ssname ss 0))
        atts (vlax-invoke obj 'getattributes)
  );end_setq
  
  (foreach att atts
   (if (= (strcase (vlax-get-property att 'tagstring)) "DIMENSION") (setq t_val (vlax-get-property att 'textstring)))
  );end_foreach
  
  (vla-delete obj)
  
  (command "-purge" "_A" "*" "_N")
  (command "-insert" "TITLEBLOCK.DWG" "9,0" "" "" "")
  
  (while (not flg)
    (command "explode" "last")
    (setq obj (vlax-ename->vla-object (entlast)))
    (cond ( (= (vlax-get-property obj 'hasattributes) :vlax-true)
            (setq atts (vlax-invoke obj 'getattributes))
            (foreach att atts
              (if (= (strcase (vlax-get-property att 'tagstring)) "DIMENSION") (vlax-put-property att 'textstring t_val))
            );end_foreach
            (setq flg t)
          )
    );end_cond
  );end_while
  (princ)
);end_defun
(vl-load-com)
;end

 

Share this post


Link to post
Share on other sites
tmelancon

Just ran the updated code received this error:

 

Cancel: ActiveX Server returned the error: unknown name: HASATTRIBUTES

Share this post


Link to post
Share on other sites
tmelancon

Here is the sample versions of both the titleblock I am using as well as a stripped down drawing example where I would replace the titleblocks.

TESTER-DRAWING.dwg TESTER-TITLEBLOCK.dwg

Share this post


Link to post
Share on other sites
dlanorh

This may be a silly question, but are you running on a Mac?

Share this post


Link to post
Share on other sites
tmelancon

Not a silly question at all. Not running on a mac though lol running Windows 7 Professional

  • Like 1

Share this post


Link to post
Share on other sites
dlanorh

Join the club:playing:

 

OK Try this, I've changed the lisp slightly. I have an upgraded version, if this works, that contains error and undo grouping. 

 

I've tested on your test drawing although I've renamed the "TESTER-TITLEBLOCK" to "TITLEBLOCK" to fit the in with the lisp. This works in my test.

 

(defun c:bpv ( / ss obj atts flg)

  (prompt "\nSelect a Titleblock to be replaced : ")
  (setq ss (ssget "_+.:E:S:L" '((0 . "INSERT") (66 . 1)))
        obj (vlax-ename->vla-object (ssname ss 0))
        atts (vlax-invoke obj 'getattributes)
  );end_setq
  
  (foreach att atts
   (if (= (strcase (vlax-get-property att 'tagstring)) "DIMENSION") (setq t_val (vlax-get-property att 'textstring)))
  );end_foreach
  
  (vla-delete obj)
  
  (setq ss nil)
  
  (command "-purge" "_A" "*" "_N")
  (command "-insert" "TITLEBLOCK.DWG" "9,0" "" "" "")
  
  (while (not flg)
    (command "explode" "last")
    (setq ss (ssget "_X" '((0 . "INSERT") (2 . "TBLOCK-NEW"))))
    (cond ( (and ss (= (sslength ss) 1))
            (setq obj (vlax-ename->vla-object (ssname ss 0))
                  atts (vlax-invoke obj 'getattributes)
            );end_setq
            (foreach att atts
              (if (= (strcase (vlax-get-property att 'tagstring)) "DIMENSION") (vlax-put-property att 'textstring t_val))
            );end_foreach
            (setq flg t ss nil)
          )
    );end_cond
  );end_while
  (princ)
);end_defun
(vl-load-com)
;end

 

  • Like 1

Share this post


Link to post
Share on other sites
tmelancon

Well aren't you just a magnificent creature you!!!! Brilliance! Amazing! I am forever in your debts! haha 🤗 *sips coffee, puts feet on desk, lays back, admires the CADTutor forum Gods*

 

Now would is be too hard to modify the code to accept new attributes in the future.. like say add the tag "DRAWDATE" if I want to get the drawing date from the old titleblock and insert it in the new titleblock?

Share this post


Link to post
Share on other sites
dlanorh

Not too difficult. It just involves collecting multiple tagstring-textstring combinations as a list of lists.

 

Attached is the upgraded lisp.

bpv2.lsp

Share this post


Link to post
Share on other sites
tmelancon

Got this error running the bpv2.lsp latest code

 

Oops an Error : bad function: CMDECHO occurred
 

Share this post


Link to post
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
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  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...