Visual LISP, AutoLISP and General Customization
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Field link to layout tab?

29 REPLIES 29
Reply
Message 1 of 30
Metron4
3503 Views, 29 Replies

Field link to layout tab?

Hi,

Is there any way to grab the ObjectID or name from a layout tab to use in a field? I wish to link the layout name to a callout block so that if the layout tab changes position and name (inserting a new tab), the callout block will update no matter what page it is on. Without using the Sheet Set manager.

Thanks,

Rob
29 REPLIES 29
Message 2 of 30
Anonymous
in reply to: Metron4

You can use %<\AcVar ctab>% for the name. The position # is not as easy.
Message 3 of 30
Metron4
in reply to: Metron4

Thanks, I knew about ctab. I understand it might not be possible to grab this data from the layout tab, but how about a workaround? I can get an object ID number from the attribute holding the layout tab name (using ctab). So it gives me a tag like %<\AcObjProp Object(%<\_ObjId 1859234416>%).TextString>

There's the ID: 1859234416. How can I cement the contents (TextString) of this object into my callout block, so that when I move it to another sheet, the link stays? Please bear in mind that I very likely have no idea what I'm talking about.

Thanks,

Rob
Message 4 of 30
Anonymous
in reply to: Metron4

This seems to work. I don't fully understand fields, and I'm not going to take the time right now since my work doesn't use them, but it looked like a fun challenge.

You need an object with a field already (I used one l ink to a piece of text). Then just copy/paste this to the command line, and select the field text you want to associate with the current layout. After it runs you need to regen to see it. I then changed the name of the layout, and then regened, and the field show the new name of the layout.

[code]
(progn
(setq Sel (entsel "\n Select object to change field value: "))
(setq Obj (vlax-ename->vla-object (car Sel)))
(if
(and
(equal (vla-get-HasExtensionDictionary Obj) :vlax-true)
(setq Dict (vla-GetExtensionDictionary Obj))
(not
(vl-catch-all-error-p
(setq FDict
(vl-catch-all-apply
'vla-Item
(list
Dict
"ACAD_FIELD"
)
)
)
)
)
)
(vlax-for tempObj FDict
(setq tempData (entget (vlax-vla-object->ename tempObj)))
;(setq tempData (subst (cons 1 "_layout") (assoc 1 tempData) tempData))
;(setq tempData (subst (cons 1 "_text") (assoc 1 tempData) tempData))
;(entmod tempData)
(setq tempData (entget (cdr (assoc 360 tempData))))
(setq tempData
(subst
'(2 . "\\AcObjProp Object(%<\\_ObjIdx 0>%).Name")
(assoc 2 tempData)
tempData
)
)
(setq tempData
(subst
(cons
330
(vlax-vla-object->ename
(setq ActLo
(vla-get-ActiveLayout
(vla-get-ActiveDocument
(vlax-get-Acad-Object)
)
)
)
)
)
(assoc 330 (reverse tempData))
tempData
)
)
(setq tempList
(vl-remove-if-not
'(lambda (x) (equal (car x) 1))
tempData
)
)
(setq tempData
(subst
'(1 . "Name")
(nth 1 tempList)
tempData
)
)
(setq tempData
(subst
(cons 1 (vla-get-Name ActLo))
(nth 2 tempList)
tempData
)
)
(setq tempData
(subst
(cons 301 (vla-get-Name ActLo))
(assoc 301 tempData)
tempData
)
)
(entmod tempData)
)
)
)
[/code]
Message 5 of 30
Metron4
in reply to: Metron4

Thanks for taking the time to create this lisp routine. This seems to work exactly like the ctab system variable. And just like ctab, once I copy my field to another sheet, it takes the name of the current layout tab, not the original tab I want the field to refer to. Any way to make this always point to the layout tab of my choice?
Message 6 of 30
Metron4
in reply to: Metron4

I have been trying to link the field of a text object to my callout block. The text object uses ctab to get the layout name. So it always updates if I change the layout name. Here's what I am noticing. When I link the callout block to the text object, it works fine. The minute I try to copy the callout block, so that I can paste it to another sheet that references the current one, the ObjId in the field sets to zero. So if my text object was %<\_ObjId 2020334456>%, it now says %<\_ObjId 0>%

Somehow, I've gotta get that ObjId to retain the number when the block gets copied. That would solve all my problems.
Message 7 of 30
Anonymous
in reply to: Metron4

Mine does not work the same as the ctab one will. Once you change tabs, the ctab variable changes, so the reference field would change, mine does not change when you switch tabs.

If you want to copy it to a different tab in the current drawing (have not tested it in other drawings) then you can make it a block within the drawing. Go to the other tab, insert it, then explode it, and it will keep the link to original layout. I just tested this and it works.
Message 8 of 30
Metron4
in reply to: Metron4

Ah! I see how it works differently now. I didn't even have to explode the block and it still retained the layout name after I changed it. Very cool. It doesn't seem to work with fields inside attributes though.
Message 9 of 30
Anonymous
in reply to: Metron4

Try changing the selection from 'entsel' to 'nentsel'. This will let you select nested items like attributes.

Just make sure that the item selected has a field already associated with it. I didn't take the time to see what all is needed to create one from code.

You're welcome. I learned somethings working on this also.
Message 10 of 30
Metron4
in reply to: Metron4

I've had a hell of a day. Earlier, I tried to duplicate the instructions you had, pasting in the same code you typed, and it wasn't working. I couldn't figure it out so I started looking at other answers. Getting nowhere, I tried your code again and it started working again. After pulling the last few hairs from my head, I finally realized what was causing the program to not work / work. If the "generic" field I selected was a system variable (ctab was the culprit), it caused ##### to happen. Some other fields also cause errors, but I was able to get what I want by using a generic object field (like for the length of an object). Go figure.

So now I have exactly what I was looking for, and I have you to thank. Message was edited by: Metron4
Message 11 of 30
msarqui
in reply to: Metron4

Hello guys,

 

I have the same problem of the topic. I am trying to link callouts blocks with layout pages for years!

I tried ctab and i tried lisp routines without succes.

I really tried to understand the explanations you have given here but I did not get.

First because my English is basic, and second because I'm new in fields and routines.

Anyone of you could send me the block callout with fields ready?

I think that this way I wil understand the explanations finaly.

 

Thank you very much!

 

My email: msarqui@gmail.com

 

Marcelo

 

 

Message 12 of 30
CADaSchtroumpf
in reply to: msarqui

Hi,

For my job, i have used this.
I must put a field at the same point for each layout. The 50 layouts have only 1 Viewport.

This can help you?

(defun make_field (obj / pt nw_obj)
	(setq
		pt (list 2.15031 103.032 0.0)
		nw_obj
		(vla-addMtext Space
			(vlax-3d-point pt)
			0.0
			(strcat
				"{\\fArial|b0|i0|c0|p34;"
				"%<\\AcVar ctab>%"
				" - Scale 1/"
				"%<\\AcExpr (1000/"
				"%<\\AcObjProp Object(%<\\_ObjId "
				(itoa (vla-get-ObjectID (vlax-ename->vla-object obj)))
				">%).CustomScale \\f \"%lu2%qf2816\">%"
				") \\f \"%lu2%pr0\">%"
			)
		)
	)
	(mapcar
		'(lambda (pr val)
			(vlax-put nw_obj pr val)
		)
		(list 'AttachmentPoint 'Height 'DrawingDirection 'InsertionPoint 'StyleName 'Layer 'Rotation 'BackgroundFill)
		(list 1 3.5 5 pt "Standard" "0" 0.0 -1)
	)
)
(defun c:Field_Layout_Scale ( / AcDoc Space js)
	(vl-load-com)
	(foreach n (layoutlist)
		(setvar "CTAB" n)
		(setq
			AcDoc (vla-get-ActiveDocument (vlax-get-acad-object))
			Space (vla-get-PaperSpace AcDoc)
		)
		(setq js
			(ssget "_X"
				(list
					'(0 . "VIEWPORT")
					'(67 . 1)
					(cons 410 n)
				)
			)
		)
		(cond (js (make_field (ssname js 0))))
	)
	(prin1)
)

 

 

Message 13 of 30
Lee_Mac
in reply to: msarqui

Since Field Expressions can be linked to the majority (if not all) VLA-Objects (even those which are not selectable), and display any available property of such VLA-Objects, the following function should create an MText Field displaying the name of the Layout in which the field is created. The field will consequently update should the Layout name be altered.

;; Layout Field  -  Lee Mac  -  2011  -  www.lee-mac.com
;; Creates an MText Field displaying the name of the Layout in which
;; the field is created.

(defun c:LayoutField ( / _ObjectID acdoc pt )

    (setq acdoc (vla-get-activedocument (vlax-get-acad-object)))
    (setq _ObjectID
        (eval
            (list 'lambda '( obj )
                (if
                    (and
                        (vl-string-search "64" (getenv "PROCESSOR_ARCHITECTURE"))
                        (vlax-method-applicable-p (vla-get-utility acdoc) 'getobjectidstring)
                    )
                    (list 'vla-getobjectidstring (vla-get-utility acdoc) 'obj ':vlax-false)
                   '(itoa (vla-get-objectid obj))
                )
            )
        )
    )

    (cond
        (   (/= 1 (getvar 'CVPORT))
            (princ "\nCommand not allowed in Modelspace.")
        )
        (   (setq pt (getpoint "\nPoint for MText Field: "))
            (vla-addmtext (vla-get-paperspace acdoc) (vlax-3D-point (trans pt 1 0)) 0.0
                (strcat
                    "%<\\AcObjProp Object(%<\\_ObjId "
                    (_ObjectID (vla-get-activelayout acdoc)) ">%).Name>%"
                )
            )
        )
    )
    (princ)
)
(vl-load-com) (princ)
Message 14 of 30
msarqui
in reply to: Lee_Mac

Thank Lee_Mac you for help but is not working. When I call the command it creates the field, but when I copy this field to another layout, the result is ####.
What am I doing wrong?

Marcelo

Message 15 of 30
alanjt_
in reply to: msarqui

Reference the CTAB system variable instead of the active layout's name:

 

eg.

(defun c:LayoutField (/ point)
  (cond ((/= (getvar 'CVPORT) 1) (princ "\nCommand not allowed in Modelspace."))
        ((setq point (getpoint "\nSpecify placement point for MText field: "))
         (vlax-invoke
           (vla-get-paperspace (vla-get-activedocument (vlax-get-acad-object)))
           'addmtext
           (trans point 1 0)
           0.
           "%<\\AcVar ctab>%"
         )
        )
  )
  (princ)
)

 

Message 16 of 30
Lee_Mac
in reply to: msarqui


@msarqui wrote:

Thank Lee_Mac you for help but is not working. When I call the command it creates the field, but when I copy this field to another layout, the result is ####.
What am I doing wrong?

Marcelo


Since the object being referenced is not part of the Field command, you would need to create the field using the program in each layout.

Message 17 of 30
alanjt_
in reply to: Lee_Mac

@Lee: Why go though all the trouble of extracting the name from the active layout when the CTAB variable is available and returns the same information?

Message 18 of 30
Lee_Mac
in reply to: alanjt_


@alanjt_ wrote:

@lee: Why go though all the trouble of extracting the name from the active layout when the CTAB variable is available and returns the same information?


The OP mentioned in a previous post that the CTAB link didn't work for them, so I offered an alternative - but I agree, CTAB is easier.

Message 19 of 30
alanjt_
in reply to: Lee_Mac


@Lee_Mac wrote:

@alanjt_ wrote:

@lee: Why go though all the trouble of extracting the name from the active layout when the CTAB variable is available and returns the same information?


The OP mentioned in a previous post that the CTAB link didn't work for them, so I offered an alternative - but I agree, CTAB is easier.


Ahh, right on.

Message 20 of 30
msarqui
in reply to: alanjt_

Ok friends, I'll try to explain better.

For example: I have two paper space layouts in one file. In "Layout1" I have a drawing with a tag indicating "See detail in Layout2." In "Layout2" I have the detail of the drawing cited in the "Layout1."
The problem is, if for some reason I have to change the name of "Layout2" to "Layout3" I have to go back to the "Layout1" and change my tag to say "See detail in Layout3." Imagine that if I have 50 layouts.
What I would like to have is a FIELD which is connected to the name of the layout in which it was created. So when I copy this FIELD in another layout, it will continue giving the name of the layout that was created. Thus, if for example I change the name of "Layout2" to "Layout3" the FIELD will update automatically.
In my example, I would create this FIELD in "Layout2" to record its name. Then, I copy / paste the FIED in "Layout1." Now, if I change the name of "Layout2", the FIELD in the "Layout1" will actualize automatically.
That's why CTAB does not work for me.
I tried the FIELD "hyperlink" - "view of this drawing" but when I change the name of the layout, the field does not change.

Thanks again

Marcelo

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

AutoCAD Inside the Factory


Autodesk Design & Make Report