PDA

View Full Version : Get Layout Name of Blocks?



stusic
2015-05-27, 08:33 PM
Related to my previous post, done some searching, but can't find what I'm looking for.

Trying to fiure how to determine which layout blocks are on. I just want to apply the layout name to an attribute in a block on that layout... Tried using CTAB, but I'd have to go through each tab and using a field is messing up my other code (doesn't update correctly).

Something like this, but without the CTAB:


(foreach layout (layoutlist)
(setq fld (getvar ctab))
)

peter
2015-05-28, 02:53 AM
This seems to work given the vla-object of the entity

(ObjectLayout (vlax-ename->vla-object (car (entsel))))




(defun ObjectLayout (objItem / objBlock objLayout objThisDrawing strBlock strReturn )
(if (and
(setq objThisDrawing (vla-get-activedocument (vlax-get-acad-object)))
(setq objBlock (vla-objectidtoobject objThisDrawing (vla-get-ownerID objItem)))
(setq strBlock (vla-get-name objBlock))
)
(vlax-for objLayout (vla-get-layouts objThisDrawing)
(if (= strBlock (vla-get-name (vla-get-block objLayout)))
(setq strReturn (vla-get-name objLayout))
)
)
)
strReturn
)
(vl-load-com)

Tharwat
2015-05-28, 08:49 AM
I just want to apply the layout name to an attribute in a block on that layout...



This (http://www.cadtutor.net/forum/showthread.php?92486-Lisp-for-Layout-name-to-block-attribute&p=632781&viewfull=1#post632781)should help and just change the tag name "LAYOUT" and name of the block "TITLEBLOCK" to suit your needs .

stusic
2015-05-28, 12:36 PM
This (http://www.cadtutor.net/forum/showthread.php?92486-Lisp-for-Layout-name-to-block-attribute&p=632781&viewfull=1#post632781)should help and just change the tag name "LAYOUT" and name of the block "TITLEBLOCK" to suit your needs .

Is there supposed to be code? lol ;)

Tharwat
2015-05-28, 12:42 PM
Is there supposed to be code? lol ;)

There is a link , just take a close look :)

stusic
2015-05-28, 12:54 PM
This seems to work given the vla-object of the entity

(ObjectLayout (vlax-ename->vla-object (car (entsel))))


(defun ObjectLayout ...


?



Select object:

Disconnecting from the database
; error: bad DXF group: (1)


Btw, I'm just *barely* following this. Additionally, I didn't know you could put the vl-load-com wherever you want; I thought it had to be at te top - cool.

stusic
2015-05-28, 12:58 PM
There is a link , just take a close look :)

There it is!

Tharwat
2015-05-28, 01:04 PM
This (http://www.cadtutor.net/forum/showthread.php?92486-Lisp-for-Layout-name-to-block-attribute&p=632781&viewfull=1#post632781)should help and just change the tag name "LAYOUT" and name of the block "TITLEBLOCK" to suit your needs .


There it is!

Move your mouse on the first word ( This ) .

stusic
2015-05-28, 01:33 PM
There is a link , just take a close look :)

This works really well, thanks :)

I'm tried to modify it to accept wildcards for the block name, but I can't quite figure it out. Here's what I've done:



(defun c:Test nil
;;------------------------------------;;
;; Tharwat 20.05.2015 ;;
;; Modify Title Blocks that have ;;
;; Tag name "LAYOUT" wiht its ;;
;; location is each Layout's Name ;;
;;------------------------------------;;
(vlax-for x (vla-get-layouts (vla-get-ActiveDocument (vlax-get-acad-object)))
(if (/= (vla-get-name x) "Model")
(vlax-for b (vla-get-block x)
(and (eq (vla-get-objectname b) "AcDbBlockReference")
;;; (eq (vla-get-effectivename b) "*BORDER*")
(eq (wcmatch (strcase (vla-get-effectivename b)) (strcase "*BORDER*")))
(vl-some
'(lambda (a)
(if
(eq "PAGE_NO" (strcase (vla-get-tagstring a)))
(vla-put-textstring a (vla-get-name x))
)
)
(vlax-invoke b 'getattributes)
)
)
)
(prompt "Please assure all sheets in ModelSpace have correct Page Numbers.")
)
)
(princ)
)(vl-load-com)

Tharwat
2015-05-28, 01:40 PM
Replace the eq function with wcmatch to Obtain/Read the wildcard Symbols/Characters .

Is it good idea to remove my signature from my codes above ?

stusic
2015-05-28, 01:50 PM
Replace the eq function with wcmatch to Obtain/Read the wildcard Symbols/Characters .

Thank you, I see now they do the same thing.


Is it good idea to remove my signature from my codes above ?
I'm sorry, I had cut out all the top and bottom to make it a sub function for testing and forgot to leave your sig in. It's still there in my big code though. Sorry again.

stusic
2015-05-28, 01:55 PM
; error: bad DXF group: (1)


I don't even see where you're referencing any DXF codes... Still works though.

Nevermind, another part of my code (referencing the PAGE_NO atrtribute) was causing that.

Great work, Tharwat, thanks for your help :)

Tharwat
2015-05-28, 03:16 PM
Great work, Tharwat, thanks for your help :)

Nice, You're most welcome ;)

peter
2015-05-28, 04:02 PM
What version of AutoCAD are you using?

Without iterating through all of the objects in all of the layouts...

You should be able to match the *paperspace block collection between the ownerid and the block collection of a layout.

This function worked perfect for me, and I was wondering why it didn't work for you.

Are you using an earlier version of AutoCAD?

stusic
2015-05-28, 04:48 PM
What version of AutoCAD are you using?

Without iterating through all of the objects in all of the layouts...

You should be able to match the *paperspace block collection between the ownerid and the block collection of a layout.

This function worked perfect for me, and I was wondering why it didn't work for you.

Are you using an earlier version of AutoCAD?

No, it actually works just fine; i was thinking the bad dxf code was originating from the code you provided, but it was actually coming from another part of my code that referenced it. I've never seen bad code from you :)

peter
2015-05-28, 04:57 PM
Go check out the code I posted on your "Update Title Block Lisp Problem" thread...

A general solution for getting and changing attributes in a drawing.

Wildcard filters for BlockName, LayoutName, TagString and TextString.

It is like a sql query for attributes of an AutoCAD database.

P=

stusic
2015-05-28, 05:00 PM
Tharwat, I do have one other related request. I've used a piece of code you provided here (http://forums.augi.com/showthread.php?141491-Auto-Numbering-Layout-Tabs&p=1183238&viewfull=1#post1183238), which works great, but if I run the code again, it errors out with "Automation Error. Layout already exists". Is there an easy way to tell it to overwrite whatever's already there? I was going to just put an IF statement in, but I'm not sure it would work if someone added a sheet to the end and re-ran the program. I appreciate the help you provide all over the place.



(setq i 0)
(foreach x (layoutlist)
(if
(vla-put-name
(vla-item (vla-get-layouts
(vla-get-activedocument (vlax-get-acad-object))
)
x
)
(itoa (setq i (1+ i))) ; changed slightly from original code
)
)
)
(princ)


Edit: Doesn't seem to keep them in order when I force it to run again...

stusic
2015-05-28, 05:38 PM
Go check out the code I posted on your "Update Title Block Lisp Problem" thread...

A general solution for getting and changing attributes in a drawing.

Wildcard filters for BlockName, LayoutName, TagString and TextString.

It is like a sql query for attributes of an AutoCAD database.

P=

I totally missed this post. I need to digest it, but it looks very useful.

Tharwat
2015-05-28, 05:59 PM
Tharwat, I do have one other related request. I've used a piece of code you provided here (http://forums.augi.com/showthread.php?141491-Auto-Numbering-Layout-Tabs&p=1183238&viewfull=1#post1183238), which works great, but if I run the code again, it errors out with "Automation Error. Layout already exists". Is there an easy way to tell it to overwrite whatever's already there? I was going to just put an IF statement in, but I'm not sure it would work if someone added a sheet to the end and re-ran the program. I appreciate the help you provide all over the place.



(setq i 0)
(foreach x (layoutlist)
(if
(vla-put-name
(vla-item (vla-get-layouts
(vla-get-activedocument (vlax-get-acad-object))
)
x
)
(itoa (setq i (1+ i))) ; changed slightly from original code
)
)
)
(princ)


Edit: Doesn't seem to keep them in order when I force it to run again...

You need to reorder them once again when you add any new layout if it is not adjusted at creating .

Anyway , check this out .



(setq i 0
n 1
doc (vla-get-activedocument (vlax-get-acad-object))
)
(foreach x (layoutlist)
(vla-put-name
(vla-item (vla-get-layouts doc) x)
(itoa (setq i (1+ i)))
)
)

(foreach lay (acad_strlsort (layoutlist))
(vla-put-taborder (vla-item (vla-get-layouts doc) lay) n)
(setq n (1+ n))
)

stusic
2015-05-28, 06:16 PM
Hmm. I still get the "Automation Error. Layout already exists" error when I run it concurrently. I also see that (if the tabs are named something else) it renames and reorders the tabs, not just renumbering them in sequence, but actually moving the sheet to a different position. I'd just like the first layout (far left) to be "1", the second sheet to be "2", the last sheet to be "10", etc. Then if I run it again, the layouts will renumber (in the event a sheet is added), but stay in the same position.

I'm sorry to be picky, but this seems like something fairly elementary and something I should be able to do, but I can't figure it out for the life of me and I'm getting really frustrated. vla-put-taborder won't work because not only does it reorder the sheets, but it also puts Layout 10 before layout 2 (I understand why, but only computers count this way). I'd have thrown my laptop through the window by now if it weren't for the help I've been getting from you. :banghead: Blargh.

Tharwat
2015-05-28, 06:42 PM
You are getting that automation error due to recreating the same layout name since that it is already existed , so to work around this and to work around the order of numbering layouts as long as them are numbers ONLY .



(setq i 0
n 1
doc (vla-get-activedocument (vlax-get-acad-object))
)
(foreach x (layoutlist)
(while (member (itoa (setq i (1+ i))) (layoutlist)))
(vla-put-name
(vla-item (vla-get-layouts doc) x)
i
)
)

(foreach lay
(vl-sort (layoutlist) '(lambda (j k) (< (atoi j) (atoi k))))
(vla-put-taborder (vla-item (vla-get-layouts doc) lay) n)
(setq n (1+ n))
)

stusic
2015-05-28, 07:11 PM
Trying something like this, but I get all sorts of errors. It would probably help if I knew a little VL...



(setq i 0
n 1
doc (vla-get-activedocument (vlax-get-acad-object))
)
(foreach x (layoutlist)
(vla-put-name
(vla-item (vl-sort '(vla-get-layouts doc) '<) x)
(itoa (setq i (1+ i)))
)
)

stusic
2015-05-28, 07:20 PM
You are getting that automation error due to recreating the same layout name since that it is already existed , so to work around this and to work around the order of numbering layouts as long as them are numbers ONLY .



(setq i 0
n 1
doc (vla-get-activedocument (vlax-get-acad-object))
)
(foreach x (layoutlist)
(while (member (itoa (setq i (1+ i))) (layoutlist)))
(vla-put-name
(vla-item (vla-get-layouts doc) x)
i
)
)

(foreach lay
(vl-sort (layoutlist) '(lambda (j k) (< (atoi j) (atoi k))))
(vla-put-taborder (vla-item (vla-get-layouts doc) lay) n)
(setq n (1+ n))
)


This continues the numbering, so layouts 1-10 become 11-20. And it reorders the sheets - the old sheet "10" (the last sheet) became sheet "12" in the second layout position...

On an up note, I have been messing with vl-sort, so I don't think I'm too far off base :neutral:

Tharwat
2015-05-28, 07:25 PM
Read about functions to know what each function returns , so you would know how to deal with them.

VLA-GET-LAYOUTS
VL-SORT

stusic
2015-05-28, 07:26 PM
Would it make sense programatically to overwrite the layouts with placeholder names (a, b, c, d, etc.) to prevent "Layout exists" errors, then sort the layoutlist, then rename with the numbers? We would never have more than 26 sheets in a drawing.

stusic
2015-05-28, 07:32 PM
Read about functions to know what each function returns , so you would know how to deal with them.

VLA-GET-LAYOUTS
VL-SORT

I can't find any documentation for VLA-GET-LAYOUTS

BlackBox
2015-05-28, 07:39 PM
I can't find any documentation for VLA-GET-LAYOUTS

Few different ways....

Highlight the function in VLIDE and hit Help button, which should launch the ActiveX Help.

Go here (http://help.autodesk.com/view/ACD/2015/ENU/?guid=GUID-A809CD71-4655-44E2-B674-1FE200B9FE30), and click on Layouts.

Or one of my favorites for some years (before the new Help system included such), was to go here (http://entercad.ru/acadauto.en/), and click on Layouts.



HTH