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

moving an object from a layout to another programatically

11 REPLIES 11
Reply
Message 1 of 12
markruys2
771 Views, 11 Replies

moving an object from a layout to another programatically

any idea how to do this programatically and without modifying the handle of the object,

i am trying to do it programatically (entmod (cons 410 newname)(assoc 410 ... no luck.

(entmakex -ing will modify or create a new handle

ctrl-X and then ctrl-V recreates a new handle too ... stumped

 

TIA

11 REPLIES 11
Message 2 of 12
Kent1Cooper
in reply to: markruys2


@markruys2 wrote:

any idea how to do this programatically and without modifying the handle of the object,

i am trying to do it programatically (entmod (cons 410 newname)(assoc 410 ... no luck.

(entmakex -ing will modify or create a new handle

ctrl-X and then ctrl-V recreates a new handle too ... stumped

 

TIA


I haven't tried it out, but I think your "no luck" attempt is missing something essential:

 

(entmod (subst (cons 410 newname) (assoc 410 entitydata) entitydata))

 

Maybe that's what you really tried, but if not, give it a shot.

Kent Cooper, AIA
Message 3 of 12
markruys2
in reply to: Kent1Cooper

no luck, that was the first thing i tested

Message 4 of 12
Kent1Cooper
in reply to: markruys2


@markruys2 wrote:

no luck, that was the first thing i tested


Yeah, I got around to trying it myself, and it didn't work for me, either.  Nor does there seem to be any VLA Property for the Layout, that you can assign with some VLA "put"-variety function.

Kent Cooper, AIA
Message 5 of 12
markruys2
in reply to: Kent1Cooper

i found out that dropping the object into model, then pulling it back into another layout does the trick...

but then autocad/express removed the change space functions acet-ms-to-ps,

and the command option CHSPACE is too clumsy to use programatically

thanks

Message 6 of 12
Lee_Mac
in reply to: markruys2


markruys wrote:

any idea how to do this programatically and without modifying the handle of the object,

i am trying to do it programatically (entmod (cons 410 newname)(assoc 410 ... no luck.

(entmakex -ing will modify or create a new handle

ctrl-X and then ctrl-V recreates a new handle too ... stumped


Since the OwnerID property of a VLA-Object is read-only, this would imply that the Owner of the object is also read-only and hence cannot be altered, implying that an object cannot be moved from one owner to another (i.e. from one Block to another, whether the Block Object be ModelSpace / PaperSpace or an arbitrary Block).

 

Of course, the workaround is to copy the object between Blocks, which may be achieved using the deep-clone CopyObjects method, then delete the original objects. However, this will obviously alter the object handles.

;; Move to Layout  -  Lee Mac  -  2011  -  www.lee-mac.com
;; Moves selected objects to a selected layout.

(defun c:M2L ( / acdoc acsel actab err layouts lst obj )
    (if
        (and
            (ssget "_:L"
                (list
                    (cons 410
                        (setq actab
                            (if (= 1 (getvar 'CVPORT))
                                (getvar 'CTAB)
                                "Model"
                            )
                        )
                    )
                )
            )
            (setq obj
                (cdr
                    (assoc
                        (car
                            (LM:ListBox "Select Layout"
                                (mapcar 'car
                                    (setq layouts
                                        (vl-sort
                                            (vlax-for layout
                                                (vla-get-layouts
                                                    (setq acdoc
                                                        (vla-get-activedocument
                                                            (vlax-get-acad-object)
                                                        )
                                                    )
                                                )
                                                (if (not (eq actab (vla-get-name layout)))
                                                    (setq layouts
                                                        (cons
                                                            (cons
                                                                (vla-get-name layout)
                                                                layout
                                                            )
                                                            layouts
                                                        )
                                                    )
                                                    layouts
                                                )
                                            )
                                            (function
                                                (lambda ( a b )
                                                    (<
                                                        (vla-get-taborder (cdr a))
                                                        (vla-get-taborder (cdr b))
                                                    )
                                                )
                                            )
                                        )
                                    )
                                )
                                nil
                            )
                        )
                        layouts
                    )
                )
            )
        )
        (progn
            (vlax-for obj (setq acsel (vla-get-activeselectionset acdoc))
                (setq lst (cons obj lst))
            )
            (vla-delete acsel)
            (if
                (not
                    (vl-catch-all-error-p
                        (setq err
                            (vl-catch-all-apply 'vla-copyobjects
                                (list acdoc 
                                    (vlax-make-variant
                                        (vlax-safearray-fill
                                            (vlax-make-safearray
                                                vlax-vbobject
                                                (cons 0 (1- (length lst)))
                                            )
                                            lst
                                        )
                                    )
                                    (vla-get-block obj)
                                )
                            )
                        )
                    )
                )
                (foreach obj lst (vla-delete obj))
                (princ (strcat "\nError: " (vl-catch-all-error-message err)))
            )
        )
    )        
    (princ)
)

;;-----------------------=={ List Box }==---------------------;;
;;                                                            ;;
;;  Displays a List Box allowing the user to make a selection ;;
;;  from the supplied data.                                   ;;
;;------------------------------------------------------------;;
;;  Author: Lee Mac, Copyright © 2011 - www.lee-mac.com       ;;
;;------------------------------------------------------------;;
;;  Arguments:                                                ;;
;;  title    - List Box Dialog title                          ;;
;;  data     - List of Strings to display in the List Box     ;;
;;  multiple - Boolean flag to determine whether the user     ;;
;;             may select multiple items (T=Allow Multiple)   ;;
;;------------------------------------------------------------;;
;;  Returns:  List of selected items, else nil.               ;;
;;------------------------------------------------------------;;

(defun LM:ListBox ( title data multiple / file tmp dch return ) 
    (cond
        (
            (not
                (and
                    (setq file (open (setq tmp (vl-filename-mktemp nil nil ".dcl")) "w"))
                    (write-line
                        (strcat
                            "listbox : dialog { label = \"" title
                            "\"; spacer; : list_box { key = \"list\"; multiple_select = "
                            (if multiple "true" "false") "; } spacer; ok_cancel;}"
                        )
                        file
                    )
                    (not (close file))
                    (< 0 (setq dch (load_dialog tmp)))
                    (new_dialog "listbox" dch)
                )
            )
        )
        (
            t
            (start_list "list")
            (mapcar 'add_list data) (end_list)

            (setq return (set_tile "list" "0"))
            (action_tile "list" "(setq return $value)")

            (setq return
                (if (= 1 (start_dialog))
                    (mapcar '(lambda ( x ) (nth x data)) (read (strcat "(" return ")")))
                )
            )
        )
    )
    (if (< 0 dch) (unload_dialog dch))
    (if (setq tmp (findfile tmp)) (vl-file-delete tmp))
    return
)

(vl-load-com) (princ)
Message 7 of 12
markruys2
in reply to: Lee_Mac

wow, Lee, that is a handful ... thanks ... but as you mention, will kill the handle and assign a new one ... (entget (car (entsel))) then entmake or entmakex the same list with the modified dxf 410 can do the job with one line of code. i suspect there should be a way, since dropping to model then pulling to another layout, keeps the objectids and handles intact.

thank

m

 

Message 8 of 12
Lee_Mac
in reply to: markruys2


markruys wrote:
wow, Lee, that is a handful ... thanks ... but as you mention, will kill the handle and assign a new one ... (entget (car (entsel))) then entmake or entmakex the same list with the modified dxf 410 can do the job with one line of code. i suspect there should be a way, since dropping to model then pulling to another layout, keeps the objectids and handles intact.


The CopyObjects method itself could be accomplished with a single line, however, I was looking to create a more user-friendly program with regards to the Layout selection, and increased error trapping etc.

 

However, note that the entmake[x] method will require a little more work when dealing with entities for which subentities follow (DXF 66=1).

 

Personally I prefer the CopyObjects method since it will work for all entities (graphical / non-graphical), and, more importantly, it can be used in conjunction with ObjectDBX to deep-clone objects across drawing databases.

 

I don't quite follow what you mean by: "dropping to model then pulling to another layout".

 

Lee

Message 9 of 12
markruys2
in reply to: Lee_Mac

 

(setq en1 (car (entsel))

lof = layout from (has to have at least 1 viewport in it)

lot = layout to  (has to have at least 1 viewport in it)

 

             (command "LAYOUT" "S" lof "PSPACE" "ZOOM" "E" "CHSPACE" en1 "" "" "PSPACE"
                                  "LAYOUT" "S" lot "PSPACE" "ZOOM" "E" "MSPACE" "CHSPACE" en1 "" "")

 

not as elegant as the code you provide, but it keeps objectid which have objectid fields to other objects...

later scaling and moving can be done easily if necessary

thanks for your help

Message 10 of 12
Lee_Mac
in reply to: markruys2

This seems to work after some brief testing:

 

(defun c:test ( / c e l )

    (setq l (car (layoutlist))) ;; Just for the example
    
    (if (setq e (car (entsel)))
        (progn
            (setq e (entget e)
                  c (getvar 'CTAB)
            )
            (entmod (subst '(67 . 0) (assoc 67 e) e))
            (setvar 'CTAB l)
            (entmod e)
            (setvar 'CTAB c)
        )
    )
    (princ)
)

 

Message 11 of 12
markruys2
in reply to: Lee_Mac

it DOES work ... although ideally would have liked without the switching from tab to tab

thanks again

Message 12 of 12
Lee_Mac
in reply to: markruys2


markruys wrote:

it DOES work ... although ideally would have liked without the switching from tab to tab

thanks again


Me too, but modifying the DXF 410 Layout group code in conjunction with the DXF 67 Tilemode group code seemed to have no effect; it seems that you can only switch between Modelspace & Paperspace, where the Paperspace block is the last viewed Layout Tab.

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

Post to forums  

Autodesk Design & Make Report

”Boost