Author Topic: Detach unloaded xrefs  (Read 8059 times)

0 Members and 1 Guest are viewing this topic.

CADwoman

  • Guest
Detach unloaded xrefs
« on: February 18, 2005, 11:06:50 AM »
Hi,

Does anyone know of a lisp that can detach all unloaded xrefs? I'm not sure if this is possible at all.

Thanks

MP

  • Seagull
  • Posts: 17479
Detach unloaded xrefs
« Reply #1 on: February 18, 2005, 11:54:14 AM »
Written very quickly. Read "may require an edit or two".

Subsequently modified to sport behavior requested by CADwoman:

For every unloaded xref:
▪  Dump it if it's an overlay
▪  Otherwise reload it

I've no idea what to call it so that's up to you. :)

Code: [Select]
(defun c:YouNameIt

    (   /
        _SafeInvoke
        data
        flags
        blocks
        detachList
        reloadList
    )

    (defun _SafeInvoke ( object method )
        (null
            (vl-catch-all-error-p
                (vl-catch-all-apply
                    'vlax-invoke-method
                    (list
                        object
                        method
                    )
                )
            )
        )    
    )

    (while (setq data (tblnext "block" (null data)))
        (if
            (and
                (eq 4
                    (logand 4
                        (setq flags
                            (cdr (assoc 70 data))
                        )
                    )
                )
                (assoc 71
                    (entget
                        (tblobjname "block"
                            (cdr (assoc 2 data))
                        )
                    )
                )
            )
            (if (eq 8 (logand 8 flags))
                (setq detachList
                    (cons
                        (cdr (assoc 2 data))
                        detachList
                    )
                )
                (setq reloadList
                    (cons
                        (cdr (assoc 2 data))
                        reloadList
                    )
                )
            )    
        )
    )
   
    (if (or detachList reloadList)
        (setq blocks
            (vlax-get-property
                (vlax-get-property
                    (vlax-get-acad-object)
                   'ActiveDocument
                )
               'Blocks
            )
        )
    )    

    (foreach name detachList
        (princ
            (strcat
                "Unloading "
                name
                " ... "
                (if
                    (_SafeInvoke
                        (vlax-invoke-method
                            blocks
                           'Item
                            name
                        )
                       'Detach
                    )
                    "\n"
                    " <error>\n"
                )
            )    
        )    
    )
   
    (foreach name reloadList
        (princ
            (strcat
                "Reloading "
                name
                " ... "
                (if
                    (_SafeInvoke
                        (vlax-invoke-method
                            blocks
                           'Item
                            name
                        )
                       'Reload
                    )
                    "\n"
                    " <error>\n"
                )
            )    
        )    
    )

    (princ)
   
)

Edit1: Modified per Mr. Madsen's excellent tip later in this thread.
Edit2: Temporarilly remove function definition.
Edit3: Added abilities per CADwoman's request.
Edit4: Fixed up name of variable.
\|// Set goal. Experiment tirelessly until
|Oo| practice has become expertise.  Loop.
|- | LinkedIn | Dropbox

CADwoman

  • Guest
Detach unloaded xrefs
« Reply #2 on: February 18, 2005, 05:58:39 PM »
Thanks! You're amazing! This is exactly what I want. I wonder if we can add some intelligence to it so that it will detach only unloaded xrefs that are "overlayed" and reloaded the ones that are "attached".


Quote from: MP
Written very quickly. Read "may require an edit or two".

Code: [Select]
(defun c:DetachUnloadedXrefs ...

   <snipperage>
   
)

MP

  • Seagull
  • Posts: 17479
Detach unloaded xrefs
« Reply #3 on: February 18, 2005, 06:25:08 PM »
Please, you're making my wife laugh. But seriously, a little bit of study and you could pen little utilities like this yourself. Consider looking into Mr. Madsen's most excellent LISP course(s); highly recommended.

Forgive me, I find humour in the strangest places:

Quote
This is exactly what I want. <cough> I wonder if we can add ...

The overlay / attach status is bit coded in the dxf group 70 flags (value 8) so it would require nominal effort to add that functionality.

Have a great weekend,

Michael
\|// Set goal. Experiment tirelessly until
|Oo| practice has become expertise.  Loop.
|- | LinkedIn | Dropbox

SMadsen

  • Guest
Detach unloaded xrefs
« Reply #4 on: February 18, 2005, 10:02:24 PM »
Michael, you can find unloaded xrefs only by looking for code 71. If present, the xref is unloaded. Otherwise it'll be missing no matter if it's unresolved or not.

MP

  • Seagull
  • Posts: 17479
Detach unloaded xrefs
« Reply #5 on: February 18, 2005, 10:13:35 PM »
Ahhh, behavior as noted confirmed. Thank you Stig.

I don't note that in my 2004 DXF Guide, did you observe that empirically?

(Original program updated to reflect info Stig provided).
\|// Set goal. Experiment tirelessly until
|Oo| practice has become expertise.  Loop.
|- | LinkedIn | Dropbox

SMadsen

  • Guest
Detach unloaded xrefs
« Reply #6 on: February 19, 2005, 07:28:49 AM »
It's undocumented in the DXF reference but documented in the ObjectARX docs (for AcDbBlockTableRecord::isUnloaded method).

MP

  • Seagull
  • Posts: 17479
Detach unloaded xrefs
« Reply #7 on: February 19, 2005, 07:53:58 AM »
Thank you Stig, great info.

Function modified to reflect CADwoman's other wants.
\|// Set goal. Experiment tirelessly until
|Oo| practice has become expertise.  Loop.
|- | LinkedIn | Dropbox

MP

  • Seagull
  • Posts: 17479
Detach unloaded xrefs
« Reply #8 on: February 19, 2005, 08:58:22 AM »
Here's a variant that does the same thing by iterating the blocks collection instead of walking the block table (I like it better than the first Q&D) ...

Code: [Select]
(defun c:YouNameIt ( / name data modList method )

    (vlax-for block

        (vlax-get-property
            (vlax-get-property
                (vlax-get-acad-object)
               'ActiveDocument
            )
           'Blocks
        )
       
        (if
            (and
                (eq :vlax-true
                    (vlax-get-property
                        block
                       'IsXref
                    )
                )
                (assoc 71
                    (setq data
                        (entget
                            (tblobjname
                                "block"
                                (setq name
                                    (vlax-get-property
                                        block
                                       'Name
                                    )
                                )
                            )
                        )
                    )
                )    
            )    
            (setq modList
                (cons                  
                    (list
                        name
                        block
                        (if (eq 8
                                (logand 8
                                    (cdr (assoc 70 data))
                                )
                            )
                           'Detach
                           'Reload
                        )
                    )    
                    modList
                )
            )
        )    
    )    
   
    (if (null modList)
   
        (princ "No qualifying xrefs.\n")
       
        (foreach sublist
           
            (vl-sort
                modList
               '(lambda (a b) (< (car a) (car b)))
            )    
           
            (princ
                (strcat
                    (vl-princ-to-string
                        (setq method
                            (caddr subList)
                        )    
                    )
                    "ing "
                    (car sublist)
                    " ... "
                    (if
                        (null
                            (vl-catch-all-error-p
                                (vl-catch-all-apply
                                    'vlax-invoke-method
                                    (list
                                        (cadr sublist)
                                        method                                        
                                    )
                                )
                            )
                        )    
                        "<done>\n"
                        "<error>\n"
                    )
                )    
            )    
        )    
    )

    (princ)

)
\|// Set goal. Experiment tirelessly until
|Oo| practice has become expertise.  Loop.
|- | LinkedIn | Dropbox

CADwoman

  • Guest
Detach unloaded xrefs
« Reply #9 on: February 22, 2005, 10:33:05 AM »
Thank you! I'm just starting to write LISPs, so I have lots to learn. Thanks again. I'll look for Mr. Madsen's LISP course.

Quote from: MP
Please, you're making my wife laugh. But seriously, a little bit of study and you could pen little utilities like this yourself. Consider looking into Mr. Madsen's most excellent LISP course(s); highly recommended.

Forgive me, I find humour in the strangest places:

Quote
This is exactly what I want. <cough> I wonder if we can add ...

The overlay / attach status is bit coded in the dxf group 70 flags (value 8) so it would require nominal effort to add that functionality.

Have a great weekend,

Michael

CADaver

  • Guest
Re: Detach unloaded xrefs
« Reply #10 on: December 14, 2005, 05:07:09 PM »
i was playin with this a little, and as usual, i'm missin sumthin.

i'd like it to detach unloaded xrefs, whether they are attached or overlay'd, quietly.  no prompts, no muttering, no nuttin.  i was playin with removing some of the prompts, and it killed the function

T.Willey

  • Needs a day job
  • Posts: 5218
Re: Detach unloaded xrefs
« Reply #11 on: December 14, 2005, 05:36:24 PM »
You can see if this will work for you.
Code: [Select]
(defun XrefBindDetach (Doc / )
; Doc = document object that you want to preform the routine on
; Will detach xref's that are not loaded, and will bind (as block)
;  xref's that are loaded.

(vlax-for Blk (vla-get-Blocks Doc)
 (if (= (vla-get-IsXref Blk) :vlax-true)
  (if
   (vl-catch-all-error-p
    (vl-catch-all-apply 'vla-get-XrefDatabase (list Blk))
   )
   (vla-Detach Blk)
   (vla-Bind Blk T) ; Remove this line if you don't want to bind loaded ones.
  )
 )
)
(princ)
)
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

CADaver

  • Guest
Re: Detach unloaded xrefs
« Reply #12 on: December 14, 2005, 06:14:03 PM »
i needed it to work in the current file so i took a swing at modifying the code thusly:

 
Code: [Select]
(defun XrefDetach ()
(vlax-for Blk (vla-get-Blocks (vla-get-activedocument (vlax-get-acad-object)))
(if (= (vla-get-IsXref Blk) :vlax-true)
  (if
   (vl-catch-all-error-p
    (vl-catch-all-apply 'vla-get-XrefDatabase (list Blk))
   )
   (vla-Detach Blk)
  )
)
)
(princ)
)
 

it'll detach unloaded overlay'd, but blows up on unloaded attached and i get this message:
 
Quote
  Command: (XREFDETACH)
  ; error: Automation Error. Description was not provided.
 

so i've noodled something up somewhere   :cry:

T.Willey

  • Needs a day job
  • Posts: 5218
Re: Detach unloaded xrefs
« Reply #13 on: December 14, 2005, 06:25:37 PM »
Your code worked here with attached and overlay'ed.  Are the xref's nested?  That may be a problem.  Can you post a sample drawing?  That is weird.
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

CADaver

  • Guest
Re: Detach unloaded xrefs
« Reply #14 on: December 15, 2005, 08:43:27 AM »
that's it, it is nested in another xref and attached to this file on it's own.  that means it can't be detached until after it's parent xref is detached.

i'd post a sample, but the smallest file is over 25mb and all of it is propietary.  at lunch i'll see if i can't build a sample that is somewhat smaller.

thanks for the time.