See the top rated post in this thread. Click here

Results 1 to 9 of 9

Thread: Detach Unloaded/Un-referenced XREF

  1. #1
    Member
    Join Date
    2012-06
    Posts
    12
    Login to Give a bone
    0

    Default Detach Unloaded/Un-referenced XREF

    Hi all,

    I have found many lisp routines to detach unloaded/un-referenced xrefs and all work when there is one instance of the xref. The issue i am having is I am trying to remove a loaded xref that has multiple references. I have a drawing with 6 paper space tabs and the xref I am trying to remove is title block that was inserted on all six paper space tabs, since it exists in multiple paper spaces it will not remove the xref. Is there a way to force this?

    Thanks in advance.

  2. #2
    Administrator BlackBox's Avatar
    Join Date
    2009-11
    Posts
    5,719
    Login to Give a bone
    0

    Default Re: Detach Unloaded/Un-referenced XREF

    I work with single Layout drawings, but thought your post was interesting, and I can imagine how frustrating that must be.

    So, I wrote this quickly; seem to work in limited testing here, where each XREF in each Layout (of multiple Layouts) was on the same, unlocked Layer:

    Code:
    (vl-load-com)
    
    (defun c:XDM () (c:XrefDetachMultiple))
    (defun c:XrefDetachMultiple
           (/ *error* ss acDoc oBlocks e v xrefName oXref objectId i oSs)
    
      (defun *error* (msg)
        ;;<-- restore locked layers here (if any)
        (if oSs (vla-delete oSs))
        (if acDoc (vla-endundomark acDoc))
        (cond ((not msg))                                                   ; Normal exit
              ((member msg '("Function cancelled" "quit / exit abort")))    ; <esc> or (quit)
              ((princ (strcat "\n** Error: " msg " ** ")))                  ; Fatal error, display it
        )
        (princ)
      )
    
      (if (setq ss (ssget ":S:E:L" '((0 . "INSERT"))))
        (progn
          (setq oBlocks (vla-get-blocks
                          (setq acDoc (vla-get-activedocument
                                        (vlax-get-acad-object)
                                      )
                          )
                        )
          )
          (setq e (ssname ss 0))
          (setq v (vlax-ename->vla-object e))
          (setq xrefName (vla-get-name v))
          (if
            (= :vlax-true
               (vla-get-isxref (setq oXref (vla-item oBlocks xrefName)))
            )
             (progn
               (vla-startundomark acDoc)
               (if
                 (and
                   (setq ss
                          (ssget "_x" (list '(0 . "INSERT") (cons 2 xrefName)))
                   )
                   (setq objectId (vla-get-objectid v))
                   (setq i 0)
                 )
                  (progn
                    (vlax-for x
                              (setq oSs (vla-get-activeselectionset acDoc))
                      (if (/= objectId (vla-get-objectid x))
                        (progn
                          ;;<-- check for locked layers here
                          (vla-delete x)
                          (setq i (1+ i))
                        )
                      )
                    )
                    (prompt
                      (strcat "\n  >>  "
                              (itoa i)
                              " duplicate XREF"
                              (if (= 1 i)
                                ""
                                "s"
                              )
                              " deleted. "
                      )
                    )
                  )
               )
               (progn
                 (vla-detach oXref)
                 (prompt
                   (strcat "\n  >>  XREF \"" xrefName "\" detached. \n")
                 )
               )
             )
             (prompt "\n** Selected block is not an XREF ** \n")
          )
        )
      )
    
      (*error* nil)
    )

    Example from Command Line:
    Code:
    Command: XDM
    Select objects:
      >>  3 duplicate XREFs deleted.
      >>  XREF "TITLEBLOCK" detached.
    Command:

    Cheers
    "How we think determines what we do, and what we do determines what we get."

    Sincpac C3D ~ Autodesk Exchange Apps

    Computer Specs:
    Dell Precision 3660, Core i9-12900K 5.2GHz, 64GB DDR5 RAM, PCIe 4.0 M.2 SSD (RAID 0), 16GB NVIDIA RTX A4000

  3. #3
    Member
    Join Date
    2012-06
    Posts
    12
    Login to Give a bone
    0

    Default Re: Detach Unloaded/Un-referenced XREF

    Thank you for the routine, but it is asking me to select the XREF. I need it to look for any unloaded ones and remove them. I cant select it because it does not exist.

    I have been playing with this and it work at removing the xref from as many tabs as there are but i have to specify the name of the XREF as you can see. I am trying to figure out how to GET the name of the XREF and plug it in as a variable.

    Code:
    (defun c:test6 ()
    
    (vl-load-com) 
    
    (defun delblk (bn)
    
    (if (ssget "_x" (list '(0 . "INSERT")(cons 2 bn)))
    (vlax-for n (vla-get-activeselectionset(vla-get-activedocument(vlax-get-acad-object)))(vla-delete n))
    )
    
    (repeat 4 (vla-purgeall (vla-get-activedocument (vlax-get-acad-object))))
    
    (princ)
    
    )
    
    (delblk "Border - 15944170A Pikesville")
    
    )
    How do i search for an unloaded XREF's name and plug into the code above?

    Thank you!

  4. #4
    Member
    Join Date
    2012-06
    Posts
    12
    Login to Give a bone
    0

    Default Re: Detach Unloaded/Un-referenced XREF

    So after some testing and searching and testing and searching I have come to this point. I have the below code removing ALL xrefs regardless of state. Which is a good step forward. What i need is for the code to run on only unloaded XREF's. If the XREF status is unloaded or not found run the code below. It's almost like i need a another if statement but i cant seem to find the code to check if unloaded or not found.

    Code:
    (defun c:test6 ()
    
    (vl-load-com)
    
    ;retrieve a reference to the Active Document
     (setq activedocument (vla-get-activedocument (vlax-get-Acad-Object)))
    
     ;retrieve a reference to the blocks
     (setq theblocks (vla-get-blocks activedocument))
    
    ;process each block
     (vlax-for item theblocks
    
    ;check if it's an Xref
     (setq yesxref (vlax-get-property item 'isXref))
    
    ;if it is
     (if (= yesxref :vlax-true)
    
    ;do the following
     (progn
    
     ;get the Xref name
     (setq ablock (vlax-get-property item 'Name))
    
     ;remove all instances of block to allow removal of xref__________________________________________________________________________________
    
    (if (ssget "_x" (list '(0 . "INSERT")(cons 2 ablock)))
    (vlax-for n (vla-get-activeselectionset(vla-get-activedocument(vlax-get-acad-object)))(vla-delete n))
    )
    
    (repeat 4 (vla-purgeall (vla-get-activedocument (vlax-get-acad-object))))
    
    ;_______________________________________________________________________________________________________
    
    );progn
    
    );if
    
    );vlax-for
    
    (princ)
    )

  5. #5
    Administrator BlackBox's Avatar
    Join Date
    2009-11
    Posts
    5,719
    Login to Give a bone
    0

    Default Re: Detach Unloaded/Un-referenced XREF

    Quote Originally Posted by David Prontnicki View Post
    ... it is asking me to select the XREF. I need it to look for any unloaded ones and remove them. I cant select it because it does not exist.
    That is not what you requested in the OP above:

    Quote Originally Posted by David Prontnicki View Post
    The issue i am having is I am trying to remove a loaded xref that has multiple references. I have a drawing with 6 paper space tabs and the xref I am trying to remove is title block that was inserted on all six paper space tabs, since it exists in multiple paper spaces it will not remove the xref. Is there a way to force this?
    These are two entirely different scenarios; the code I posted above merely forces a detach despite multiple instances.

    Please try to be a bit more clear about what you want help with, so as to be respectful of other's time.

    This seems to work for your second request, in some limited testing here:
    Code:
    (defun c:DUX () (c:DetachUnloadedXrefs))
    (defun c:DetachUnloadedXrefs ( / *error* e xrefs acDoc oBlocks ss v objectId i oSs)
    
      (defun *error* (msg)
        ;;<-- restore locked layers here (if any)
        (if oSs (vla-delete oSs))
        (if acDoc (vla-endundomark acDoc))
        (cond ((not msg))                                                   ; Normal exit
              ((member msg '("Function cancelled" "quit / exit abort")))    ; <esc> or (quit)
              ((princ (strcat "\n** Error: " msg " ** ")))                  ; Fatal error, display it
        )
        (princ)
      )
      
      (while
        (setq e (tblnext "block" (not e)))
         (if (cdr (assoc 1 e))
           (if (zerop (logand (cdr (assoc 70 e)) 32))
             (setq xrefs (cons (cdr (assoc 2 e)) xrefs))
           )
         )
      )
      (if xrefs
        (progn
          (vla-startundomark
            (setq acDoc (vla-get-activedocument (vlax-get-acad-object)))
          )
          (setq oBlocks (vla-get-blocks acDoc))
          (foreach xref xrefs
            (if
              (and
                (setq ss (ssget "_x" (list '(0 . "INSERT") (cons 2 xref))))
                (setq e (ssname ss 0))
                (setq v (vlax-ename->vla-object e))
                (setq objectId (vla-get-objectid v))
                (setq i 0)
              )
               (progn
                 (vlax-for x (setq oSs (vla-get-activeselectionset acDoc))
                   (if (/= objectId (vla-get-objectid x))
                     (progn
                       ;;<-- check for locked layers here
                       (vla-delete x)
                       (setq i (1+ i))
                     )
                   )
                 )
                 (prompt
                   (strcat "\n  >>  "
                           (itoa i)
                           " duplicate XREF"
                           (if (= 1 i)
                             ""
                             "s"
                           )
                           " deleted, "
                   )
                 )
               )
            )
            (vla-detach (vla-item oBlocks xref))
            (prompt
              (strcat " \"" xref "\" detached. \n")
            )
          )
        )
      )
      (*error* nil)
    )

    Cheers
    "How we think determines what we do, and what we do determines what we get."

    Sincpac C3D ~ Autodesk Exchange Apps

    Computer Specs:
    Dell Precision 3660, Core i9-12900K 5.2GHz, 64GB DDR5 RAM, PCIe 4.0 M.2 SSD (RAID 0), 16GB NVIDIA RTX A4000

  6. #6
    Member
    Join Date
    2012-06
    Posts
    12
    Login to Give a bone
    0

    Default Re: Detach Unloaded/Un-referenced XREF

    I apologize for the misunderstanding, it was a typo. I meant to say unloaded. The updated code you sent does not seem to work. I get the following error:

    Command: DUX

    >> 17 duplicate XREFs deleted,
    ** Error: Automation Error. Duplicate key **

    And I still can not detach the unloaded XREF, it still states: Xref Border - 15944170A Pikesville has multiple references. Not detached.

    I have attached a zip file containing the drawing example. When you open, 10124702_MD3695DeepCrek_CDs_Rev 1.dwg you will see that there is an unloaded XREF, Border - 15944170A Pikesville. What I am trying to achieve is to remove this unloaded XREF. But because it has multiple references; one for each paper space tab It will not remove. If I use the code below it will remove all the references from each tab and allow me to detach the XREF. The problem with the code below right now is it deletes ALL reference to ALL XREFs. I want to modify the code to only do this to unloaded and not found XREFs. The ultimate end goal here to create a lisp that will bind all xref's but when a drawing has an unloaded and/or not found xref, the bind all command does not work.

    I hope I explained this well and someone can help.

    Code:
    (defun c:test6 ()
    
    (vl-load-com)
    
    ;retrieve a reference to the Active Document
     (setq activedocument (vla-get-activedocument (vlax-get-Acad-Object)))
    
     ;retrieve a reference to the blocks
     (setq theblocks (vla-get-blocks activedocument))
    
    ;process each block
     (vlax-for item theblocks
    
    ;check if it's an Xref
     (setq yesxref (vlax-get-property item 'isXref))
    
    ;if it is
     (if (= yesxref :vlax-true)
      
    ;do the following
     (progn
    
     ;get the Xref name
     (setq ablock (vlax-get-property item 'Name))
     
     ;remove all instances of xref from each tab__________________________________________________________________________________
    
    (if (ssget "_x" (list '(0 . "INSERT")(cons 2 ablock)))
    (vlax-for n (vla-get-activeselectionset(vla-get-activedocument(vlax-get-acad-object)))(vla-delete n))
    )
    
    (repeat 4 (vla-purgeall (vla-get-activedocument (vlax-get-acad-object))))
    
    ;_______________________________________________________________________________________________________
    
    );progn
    
    );if
    
    );vlax-for
    
    (princ)
    )
    Thank you in advance

  7. #7
    Certifiable AUGI Addict
    Join Date
    2001-03
    Location
    Tallahassee, FL USA
    Posts
    3,667
    Login to Give a bone
    0

    Default Re: Detach Unloaded/Un-referenced XREF

    This one removes all the xrefs from your drawing:
    Code:
    : https://autocadtips1.com/2011/09/01/autolisp-detach-all-xrefs/ author unknown
    ; (load "Detachall") Detachall ;
    (defun C:Detachall (/ *error* mip:layer-status-restore mip:layer-status-save delete-xref-img-underlay delete-all-dict)
    
      (defun *error* (msg)
    	(mip:layer-status-restore)
    	(princ msg)
    	(princ)
      ) ;_ end of defun
    
      (defun mip:layer-status-restore ()
    	(foreach item *PD_LAYER_LST*
    	  (if (not (vlax-erased-p (car item)))
    		(vl-catch-all-apply
    		  '(lambda ()
    			(vla-put-lock (car item) (cdr (assoc "lock" (cdr item))))
    			(vla-put-freeze
    			  (car item)
    			  (cdr (assoc "freeze" (cdr item)))
    			)
    		  )
    		)
    	  )
    	)
    	(setq *PD_LAYER_LST* nil)
      ) ;_ end of defun
    
      (defun mip:layer-status-save ()
    	(setq *PD_LAYER_LST* nil)
    	(vlax-for item (vla-get-layers(vla-get-activedocument (vlax-get-acad-object)))
    	  (setq *PD_LAYER_LST*
    		(cons
    		  (list item (cons "freeze" (vla-get-freeze item))(cons "lock" (vla-get-lock item)))
    		  *PD_LAYER_LST*
    		)
    	  )
    	  (vla-put-lock item :vlax-false)
    	  (if (= (vla-get-freeze item) :vlax-true)
    		(vl-catch-all-apply '(lambda () (vla-put-freeze item :vlax-false)))
    	  )
    	)
      ) ;_ end of defun
    
      (defun delete-xref-img-underlay (/ count txt BlkList)
    	(mip:layer-status-save)
    
    	(vlax-for Blk (vla-get-Blocks(vla-get-activedocument (vlax-get-acad-object)))
    	  (setq BlkList (entget(vlax-vla-object->ename Blk)))
    	  (if(and
    		  (= (vla-get-IsXref Blk) :vlax-false)
    		  (not (wcmatch (vla-get-name Blk) "*|*")
    ;		  (logand(assoc 70 BlkList)32)
    ;		  (not(logand(assoc 70 BlkList)32))
    		))
    		(progn
    		  (setq
    			count 0
    			txt (strcat " Erase Xref and Underlay in " (vla-get-name Blk))
    		  )
    		  (grtext -1 txt)
    		  (vlax-for Obj Blk
    			(setq count (1+ count))
    			(if (zerop (rem count 10))(grtext -1 (strcat txt " : " (itoa count))))
    			(if
    			  (and (vlax-write-enabled-p Obj)
    				(or
    				  (and ;_ XREF
    					(= (vla-get-ObjectName obj) "AcDbBlockReference")
    					(vlax-property-available-p Obj "Path")
    ;		  (logand(assoc 70 BlkList)32)
    ;		  (not(logand(assoc 70 BlkList)32))
    				  ) ;_ end of and
    				  (and ;_ UNDERLAY
    					(wcmatch (vla-get-ObjectName obj) "*Reference")
    					(vlax-property-available-p Obj "UnderlayName")
    				  ) ;_ end of and
    				  (= (vla-get-ObjectName obj) "AcDbRasterImage") ;_ IMAGE
    				) ;_ end of or
    			  ) ;_ end of and
    			  (VL-CATCH-ALL-APPLY 'vla-Delete (list Obj))
    			) ;_ end of if
    		  ) ;_ end of vlax-for
    		) ;_ end of progn
    	  ) ;_ end of if
    	) ;_ end of vlax-for
    	(mip:layer-status-restore)
      ) ;_ end of defun
    
      (defun delete-all-dict (dict)
    	;;; dict - dict name (like "ACAD_IMAGE_DICT", "ACAD_PDFDEFINITIONS" ... )
    	(vl-catch-all-apply
    	  '(lambda ()
    		(vlax-map-Collection
    		  (vla-item(vla-get-dictionaries(vla-get-activedocument (vlax-get-acad-object)))dict)
    		  'vla-delete
    		) ;_ end of vlax-map-Collection
    	  ) ;_ end of lambda
    	) ;_ end of vl-catch-all-apply
      ) ;_ end of defun
    
      (delete-xref-img-underlay)
      (command "_-xref" "_d" "*")
      (while (> (getvar "CMDACTIVE") 0) (command))
      (mapcar 'delete-all-dict (list "ACAD_IMAGE_DICT" "ACAD_PDFDEFINITIONS" "ACAD_DWFDEFINITIONS" "ACAD_DGNDEFINITIONS"))
      (command "_.regenall")
      (command "_.externalreferences")
      (princ)
    ) ;_ end of defun
    This may be a better solution: https://forums.autodesk.com/t5/autoc...d/td-p/2772422

  8. #8
    Member
    Join Date
    2012-06
    Posts
    12
    Login to Give a bone
    1

    Default Re: Detach Unloaded/Un-referenced XREF

    Thank you everyone for your help, I was able to figure it out by stitching a couple different LiSP's together. I used the code below if anyone is interested:

    Code:
    (defun detatchunloadedxref (/ XREF_CHK WORK first DET_XREF)
    
    (setq first t)
    (while (setq XREF_CHK (tblnext "block" first)); while there are still blocks to check
    (setq first nil)
    (if (and (= 4 (logand 4 (cdr (assoc 70 XREF_CHK))))
    (/= 32 (logand 32 (cdr (assoc 70 XREF_CHK))))); look to see if any are unloaded xrefs
    (setq WORK (cons (cdr (assoc 2 XREF_CHK)) WORK)) ; if so, add them to the list
    )
    )
    
    (setq C 0)
    (if WORK
    (progn
    (while WORK
    (setq C (+ 1 C))
    (setq DET_XREF (car WORK)
    WORK (cdr WORK)
    )
    (if DET_XREF
    (progn
    
    
    (if (ssget "_x" (list '(0 . "INSERT")(cons 2 DET_XREF)))
    (vlax-for n (vla-get-activeselectionset(vla-get-activedocument(vlax-get-acad-object)))(vla-delete n))
    )
    
    (repeat 4 (vla-purgeall (vla-get-activedocument (vlax-get-acad-object))))
    
    (command "-xref" "d" DET_XREF)
    )
    )
    )
    )
    )
    )

  9. #9
    Certifiable AUGI Addict
    Join Date
    2001-03
    Location
    Tallahassee, FL USA
    Posts
    3,667
    Login to Give a bone
    0

    Default Re: Detach Unloaded/Un-referenced XREF

    Quote Originally Posted by David Prontnicki View Post
    Thank you everyone for your help, I was able to figure it out by stitching a couple different LiSP's together. I used the code below if anyone is interested:
    Thanks for sharing, glad you got it worked out.

Similar Threads

  1. 2014: XREF WILL NOT DETACH
    By remi678731 in forum AutoCAD Civil 3D - General
    Replies: 3
    Last Post: 2017-02-22, 01:29 PM
  2. Etransmit - Detach any unloaded or unreferenced references
    By Wish List System in forum AutoCAD Wish List
    Replies: 0
    Last Post: 2012-11-13, 03:53 PM
  3. Lisp to freeze all layers in an nested unloaded xref?
    By ilovemyjeep88 in forum AutoLISP
    Replies: 3
    Last Post: 2007-08-16, 08:00 PM
  4. Detach Xref by Selecting
    By wommack in forum AutoLISP
    Replies: 3
    Last Post: 2006-05-17, 10:55 PM
  5. Cannot detach a xref
    By kleenhippie in forum AutoCAD General
    Replies: 2
    Last Post: 2005-08-24, 04:03 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •