Author Topic: Delete not exist XREF ,Img from the drawing  (Read 1090 times)

0 Members and 1 Guest are viewing this topic.

PM

  • Guest
Delete not exist XREF ,Img from the drawing
« on: May 04, 2022, 05:52:12 AM »
Hi, I am using this code to purge (delete) my drawing from not exist images or XREF

I have a little problem with code. As you see in the attach image this code delete all files (with red x) , but can not delete the files with (yellow triangle). I have a lot of drawings with missing Xref files (most of them have this yellow triangle icon) , and this code can not delete them. Ia any way to update the code to delete them?


Code - Auto/Visual Lisp: [Select]
  1. ;;; Remove any unloaded (unreferenced) XREFs,IMAGE's,PDF's,DGN's and DWF's in a one click
  2. ;;; Combined from existing subroutines by Igal Averbuh 2016
  3. ;;; Based on https://www.theswamp.org/index.php?topic=51337.0
  4. ;;; With respect to T.Willey
  5.  
  6.                                         ; Detach any unloaded (unreferenced) XREFs
  7. (defun C:dux ()
  8.   (vlax-for BIND_xrefname
  9.             (vla-get-blocks
  10.             )
  11.     (if (= (vla-get-isxref BIND_xrefname) ':vlax-true)
  12.       (progn
  13.         (setq BIND_cont (entget (vlax-vla-object->ename BIND_xrefname))
  14.               BIND_cont (tblsearch "BLOCK" (cdr (assoc 2 BIND_cont)))
  15.         )
  16.         (if (or (= (cdr (assoc 70 BIND_cont)) 4)
  17.                 (= (cdr (assoc 70 BIND_cont)) 12)
  18.             )
  19.           (vla-Detach BIND_xrefname)
  20.         )
  21.       )
  22.     )
  23.   )
  24. )
  25.  
  26. (defun c:RID (/ isDefReferenced dict data name tData lst imName)
  27.                                         ; Remove image definition of unreferenced and unloaded definitions.
  28.   (defun isDefReferenced (aEname / cnt data)
  29.     (setq cnt 0)
  30.     (foreach i (entget aEname)
  31.       (if
  32.         (and
  33.           (equal (car i) 330)
  34.           (setq data (entget (cdr i)))
  35.           (= (cdr (assoc 0 data)) "IMAGEDEF_REACTOR")
  36.         )
  37.          (foreach j data
  38.            (if (and (equal (car j) 330) (entget (cdr j)))
  39.              (setq cnt (+ cnt 1))
  40.            )
  41.          )
  42.       )
  43.     )
  44.     (> cnt 0)
  45.   )
  46.  
  47.                                         ;-------------------------------------------------------
  48.  
  49.   (setq dict (namedobjdict))
  50.   (setq data (entget dict))
  51.   (setq name "ACAD_IMAGE_DICT")
  52.   (if (setq data (dictsearch dict name))
  53.     (foreach i data
  54.       (cond
  55.         ((and imName (equal (car i) 350))
  56.                                         ;check to see if unreferenced or unload
  57.          (setq tData (entget (cdr i)))
  58.          (if (or (equal (cdr (assoc 280 tData)) 0)
  59.                  (not (isDefReferenced (cdr i)))
  60.              )
  61.            (setq lst (cons (cons imName (cdr i)) lst))
  62.          )
  63.         )
  64.         ((equal (car i) 3) (setq imName (cdr i)))
  65.         (t (setq imName nil))
  66.       )
  67.     )
  68.   )
  69.   (if lst
  70.     (progn
  71.       (setq dict (cdr (assoc -1 data)))
  72.       (foreach i lst
  73.         (dictremove dict (car i))
  74.         (entdel (cdr i))
  75.       )
  76.       (prompt (strcat "\n Removed "
  77.                       (itoa (length lst))
  78.                       " image definition(s)."
  79.               )
  80.       )
  81.     )
  82.   )
  83.   (princ)
  84. )
  85.  
  86. (defun c:RPD (/ isDefReferenced dict data name tData lst imName)
  87.                                         ; Remove pdf definition of unreferenced and unloaded definitions.
  88.   (defun isDefReferenced (aEname / cnt data)
  89.     (setq cnt 0)
  90.     (foreach i (entget aEname)
  91.       (if
  92.         (and
  93.           (equal (car i) 330)
  94.           (setq data (entget (cdr i)))
  95.           (= (cdr (assoc 0 data)) "IMAGEDEF_REACTOR")
  96.         )
  97.          (foreach j data
  98.            (if (and (equal (car j) 330) (entget (cdr j)))
  99.              (setq cnt (+ cnt 1))
  100.            )
  101.          )
  102.       )
  103.     )
  104.     (> cnt 0)
  105.   )
  106.  
  107.                                         ;-------------------------------------------------------
  108.  
  109.   (setq dict (namedobjdict))
  110.   (setq data (entget dict))
  111.   (setq name "ACAD_PDFDEFINITIONS")
  112.   (if (setq data (dictsearch dict name))
  113.     (foreach i data
  114.       (cond
  115.         ((and imName (equal (car i) 350))
  116.                                         ;check to see if unreferenced or unload
  117.          (setq tData (entget (cdr i)))
  118.          (if (or (equal (cdr (assoc 280 tData)) 0)
  119.                  (not (isDefReferenced (cdr i)))
  120.              )
  121.            (setq lst (cons (cons imName (cdr i)) lst))
  122.          )
  123.         )
  124.         ((equal (car i) 3) (setq imName (cdr i)))
  125.         (t (setq imName nil))
  126.       )
  127.     )
  128.   )
  129.   (if lst
  130.     (progn
  131.       (setq dict (cdr (assoc -1 data)))
  132.       (foreach i lst
  133.         (dictremove dict (car i))
  134.         (entdel (cdr i))
  135.       )
  136.       (prompt (strcat "\n Removed "
  137.                       (itoa (length lst))
  138.                       " pdf definition(s)."
  139.               )
  140.       )
  141.     )
  142.   )
  143.   (princ)
  144. )
  145.  
  146. (defun c:RDD (/ isDefReferenced dict data name tData lst imName)
  147.                                         ; Remove dgn definition of unreferenced and unloaded definitions.
  148.   (defun isDefReferenced (aEname / cnt data)
  149.     (setq cnt 0)
  150.     (foreach i (entget aEname)
  151.       (if
  152.         (and
  153.           (equal (car i) 330)
  154.           (setq data (entget (cdr i)))
  155.           (= (cdr (assoc 0 data)) "IMAGEDEF_REACTOR")
  156.         )
  157.          (foreach j data
  158.            (if (and (equal (car j) 330) (entget (cdr j)))
  159.              (setq cnt (+ cnt 1))
  160.            )
  161.          )
  162.       )
  163.     )
  164.     (> cnt 0)
  165.   )
  166.  
  167.                                         ;-------------------------------------------------------
  168.  
  169.   (setq dict (namedobjdict))
  170.   (setq data (entget dict))
  171.   (setq name "ACAD_DGNDEFINITIONS")
  172.   (if (setq data (dictsearch dict name))
  173.     (foreach i data
  174.       (cond
  175.         ((and imName (equal (car i) 350))
  176.                                         ;check to see if unreferenced or unload
  177.          (setq tData (entget (cdr i)))
  178.          (if (or (equal (cdr (assoc 280 tData)) 0)
  179.                  (not (isDefReferenced (cdr i)))
  180.              )
  181.            (setq lst (cons (cons imName (cdr i)) lst))
  182.          )
  183.         )
  184.         ((equal (car i) 3) (setq imName (cdr i)))
  185.         (t (setq imName nil))
  186.       )
  187.     )
  188.   )
  189.   (if lst
  190.     (progn
  191.       (setq dict (cdr (assoc -1 data)))
  192.       (foreach i lst
  193.         (dictremove dict (car i))
  194.         (entdel (cdr i))
  195.       )
  196.       (prompt (strcat "\n Removed "
  197.                       (itoa (length lst))
  198.                       " dgn definition(s)."
  199.               )
  200.       )
  201.     )
  202.   )
  203.   (princ)
  204. )
  205.  
  206. (defun c:RWD (/ isDefReferenced dict data name tData lst imName)
  207.                                         ; Remove dwf definition of unreferenced and unloaded definitions.
  208.   (defun isDefReferenced (aEname / cnt data)
  209.     (setq cnt 0)
  210.     (foreach i (entget aEname)
  211.       (if
  212.         (and
  213.           (equal (car i) 330)
  214.           (setq data (entget (cdr i)))
  215.           (= (cdr (assoc 0 data)) "IMAGEDEF_REACTOR")
  216.         )
  217.          (foreach j data
  218.            (if (and (equal (car j) 330) (entget (cdr j)))
  219.              (setq cnt (+ cnt 1))
  220.            )
  221.          )
  222.       )
  223.     )
  224.     (> cnt 0)
  225.   )
  226.  
  227.                                         ;-------------------------------------------------------
  228.  
  229.   (setq dict (namedobjdict))
  230.   (setq data (entget dict))
  231.   (setq name "ACAD_DWFDEFINITIONS")
  232.   (if (setq data (dictsearch dict name))
  233.     (foreach i data
  234.       (cond
  235.         ((and imName (equal (car i) 350))
  236.                                         ;check to see if unreferenced or unload
  237.          (setq tData (entget (cdr i)))
  238.          (if (or (equal (cdr (assoc 280 tData)) 0)
  239.                  (not (isDefReferenced (cdr i)))
  240.              )
  241.            (setq lst (cons (cons imName (cdr i)) lst))
  242.          )
  243.         )
  244.         ((equal (car i) 3) (setq imName (cdr i)))
  245.         (t (setq imName nil))
  246.       )
  247.     )
  248.   )
  249.   (if lst
  250.     (progn
  251.       (setq dict (cdr (assoc -1 data)))
  252.       (foreach i lst
  253.         (dictremove dict (car i))
  254.         (entdel (cdr i))
  255.       )
  256.       (prompt (strcat "\n Removed "
  257.                       (itoa (length lst))
  258.                       " dwf definition(s)."
  259.               )
  260.       )
  261.     )
  262.   )
  263.  
  264.   (princ)
  265. )
  266.  
  267.  
  268. ; NoRecentBlist
  269.  
  270. (defun c:NoRecentBlist ( / reg-key n)
  271.         (setq reg-key (strcat "HKEY_CURRENT_USER\\" (vlax-product-key) "\\Profiles\\" (getvar "CPROFILE") "\\BlockContent\\Recent"))
  272.         (foreach n (vl-registry-descendents reg-key T)
  273.                 (vl-registry-delete reg-key n)
  274.         )
  275.         (princ)
  276. )
  277.  
  278.  
  279. (defun c:DXref ()
  280.   (c:NoRecentBlist)
  281.   (c:dux)
  282.   (c:rid)
  283.   (c:rpd)
  284.   (c:rdd)
  285.   (c:rwd)
  286.   (vl-cmdf "_.externalreferences")
  287.   (princ)
  288. )
  289.  
  290.  


Thanks

mhupp

  • Bull Frog
  • Posts: 250
Re: Delete not exist XREF ,Img from the drawing
« Reply #1 on: May 04, 2022, 10:50:44 AM »
might be a bit simplistic but im just checking to see if file exists. if not detach from drawing.

Code - Auto/Visual Lisp: [Select]
  1. (defun C:duxx ()
  2.   (vlax-for xref
  3.             (vla-get-blocks
  4.             )
  5.     (if (= (vla-get-isxref xref) ':vlax-true)
  6.       (if (findfile (vla-get-path xref))
  7.         (progn)
  8.         (vla-Detach BIND_xrefname)
  9.       )
  10.     )
  11.   )
  12. )

cmwade77

  • Swamp Rat
  • Posts: 1443
Re: Delete not exist XREF ,Img from the drawing
« Reply #2 on: May 04, 2022, 12:42:34 PM »
There are actually a few minor issues that I found with this routine originally, so I made my own update to it version using this as a base, it really did provide a good starting point.

You can see my thread on this at:
http://www.theswamp.org/index.php?topic=56734.msg604613#msg604613

I have also attached the latest version to this post.

Please note that this only works properly on the first run of the routine. Also, my purge routine is quite detailed, so it does slow things down slightly, but it makes sure to get rid of everything that can be purged and often takes a drawing down from 2+ MB to under 500 KB, making it run much faster as well, so a few extra seconds spent now will save 30+ minutes later.

In case you are wondering what some of the issues were, here are some of them:
  • Would not work properly, unless drawing was completely purged prior to running the command. So, I added my own purge routine to it.
  • Would not remove xrefs, etc. if the referenced file was missing, but the file was still loaded. (Yellow Triangles), my version corrected this.
  • Had issues with nested references, I was able to add in some code from some of my other routines that I had written in the past that deal with nested xRefs to handle this better.
  • Would return an error if there was a block with the same name as an xRef. In theory AutoCAD shouldn't allow this to happen, but there are circumstances where it does. I was able to add in a way to rename the block if this happens, which prevents the error.

As you will be able to see, my version is more of an evolution of what came before than a complete rewrite, so my hats off to Igal Averbuh and T.Willey, as I would never have been able to do this without their original code.

Please test and let me know what you think.

ETA: One key detail to note is that changes are not reflected in the XREF palette until you save and close the drawing and reopen it. The changes should be reflected in the classicxref dialog box right away, but sometimes they aren't. When in doubt, save the drawing, close it and reopen it.
« Last Edit: May 04, 2022, 07:07:06 PM by cmwade77 »

cmwade77

  • Swamp Rat
  • Posts: 1443
Re: Delete not exist XREF ,Img from the drawing
« Reply #3 on: May 04, 2022, 12:57:50 PM »
Also on a related note, you could add this code to the file:
Code: [Select]
(defun c:dx (/ Ent Obj); Detaches selected xref
  (vl-load-com)
  (while (not Ent)
    (setq Ent (entsel "\rSelect reference to detach: "))
  )
  (setq Obj (vlax-ename->vla-object (car Ent))       
  )
  (dx Obj)
  (princ)
)
(defun dx (Obj / Block Obj_Name SS Count SS_Length)
  (setq Obj_Name (vla-get-name Obj)
        SS (ssget "_X" (list (cons 0 "INSERT") (cons 2 Obj_Name)))
        Count 0
        SS_Length (sslength SS)
  )
  (if (> SS_Length 1);handle if more than one instance of xref is in drawing
    (progn
      (while (< Count SS_Length)
        (setq Obj2 (vlax-ename->vla-object (ssname SS Count)))
        (if (and (/= Obj2 nil) (not (vlax-erased-p Obj2)))
          (vla-delete Obj2)
        )
        (setq Count (+ Count 1))
      )
      (c:FixReferences)
    )
    (progn ;handle single instance of xref in drawing
      (vlax-for Block (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object)))
        (if (eq :vlax-true (vla-get-isxref Block))
          (progn
            (if (= (vla-get-name Block) Obj_Name)         
              (vla-detach Block)
            )
          )
        )
      )
    )
  ) 
)

Then if you want to detach an xref, you can use the command DX and select the xref you want to detach. This routine will detach the xref even if there is more than one instance of the xref in the drawing, which is something that AutoCAD can't normally do.

PM

  • Guest
Re: Delete not exist XREF ,Img from the drawing
« Reply #4 on: May 04, 2022, 06:14:43 PM »
Hi cmwade77 . I try your code but i see no difference . I try and dx code but ask me to select reference to detach. This images or xref are all ready deleted or missing from the drawing, that's why have the yellow triangle, so I have nothing to select.

Any other ideas?

cmwade77

  • Swamp Rat
  • Posts: 1443
Re: Delete not exist XREF ,Img from the drawing
« Reply #5 on: May 04, 2022, 07:05:41 PM »
Sorry, I got interrupted midthought when posting the original, I have edited the first post to reflect a key detail:

One key detail to note is that changes are not reflected in the XREF palette until you save and close the drawing and reopen it. The changes should be reflected in the classicxref dialog box right away, but sometimes they aren't. When in doubt, save the drawing, close it and reopen it.

This is a limitation in AutoCAD, there is nothing that can be done to refresh the tool palette despite my best efforts, it is one of the ways classicxref is still far superior.

This is using FixReferences as the command. The DX was just added here to give a quick way to be able to detach xrefs, especially when multiple instances exist in the drawing. But closing the drawings and reopening them is absolutely essential to see the changes in the xref palette.
« Last Edit: May 04, 2022, 07:09:16 PM by cmwade77 »

cmwade77

  • Swamp Rat
  • Posts: 1443
Re: Delete not exist XREF ,Img from the drawing
« Reply #6 on: May 04, 2022, 07:13:02 PM »
If it still isn't working, please try posting the drawing here if you can (or you can PM me with the drawing) and I will look and see, as I would want to remove whatever bug is causing this.

PM

  • Guest
Re: Delete not exist XREF ,Img from the drawing
« Reply #7 on: May 05, 2022, 02:52:35 AM »
Thanks

cmwade77

  • Swamp Rat
  • Posts: 1443
Re: Delete not exist XREF ,Img from the drawing
« Reply #8 on: May 05, 2022, 11:56:23 AM »
You are quite welcome, it took me forever to figure out that you had to close and reopen AutoCAD to refresh the xRef Palette when I was adjusting the routine.

And as I said before, I wouldn't have been able to get this much working without the work of those who came before, so my hats off to them.