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

LISP to reload xrefs in all open drawings

14 REPLIES 14
Reply
Message 1 of 15
scmallory
3033 Views, 14 Replies

LISP to reload xrefs in all open drawings

Hi,

Is there a lisp routine that reloads xrefs in all open drawings?

 

Thanks,

Tags (1)
14 REPLIES 14
Message 2 of 15
LDShaw
in reply to: scmallory

Quote from one of the masters. Old but I believe it still holds up.

Not using LISP, since when another document namespace is made active, the LISP function will lose focus and will hence cease evaluation. The only way I see that this could be done is by writing a temporary Script to iterate over the drawings and evaluate the LISP function on each drawing, though, this is less than ideal.

Lee Mac.
https://www.cadtutor.net/forum/topic/39458-lisp-to-reload-xrefs-in-all-open-drawings/

 

Message 3 of 15
CodeDing
in reply to: scmallory

@scmallory ,

 

I have a few questions so I numbered them:

1) Since you are opening all of the drawings (at some point) anyways, why not just use the XREF Tool Palette to reload them?

2) How many drawings need their XREFs reloaded.. 10? 100?

3) Is reloading them the only task you are performing on them? If so, then why is this necessary if XREFs are already updated automatically when the drawing is opened?

4) Do your XREf'd drawings change very often to require this procedure?

5) A lisp could be created so that it would automatically (or on command) reload the xrefs when you open a dwg. But that seems excessive and slow.

 

Best,

~DD

~DD
Senior CAD Tech & AI Specialist
Need AutoLisp help? Try my custom GPT 'AutoLISP Ace':
https://chat.openai.com/g/g-Zt0xFNpOH-autolisp-ace
Message 4 of 15
scmallory
in reply to: LDShaw

Yes I read this too 😣

Message 5 of 15
LDShaw
in reply to: scmallory

What are you trying to do?
could you get away with a 
(COMMAND "-xref" "r" "*") redefine in  your qsave. Would something like that work? save.JPG

Message 6 of 15
Kent1Cooper
in reply to: scmallory

I haven't tried it, but >here< is an example of something purporting to do things in all open drawings.  Presumably you can replace its operations with  (command "_.xref" "_reload" "*") , or the (vlax-invoke-method...) equivalent, or something.

Kent Cooper, AIA
Message 7 of 15
CodeDing
in reply to: Kent1Cooper

@Kent1Cooper ,

 

I was looking into your suggestion a bit today but I do not believe it would be what OP wants.

Here's (what appears to be) the best possible solution that could come from iterating through open drawings, but please note that I personally would not want to use this code.

(defun c:XRU ( / )
  ;; XRefs Update
  (vlax-for doc (vlax-get (vlax-get-acad-object) 'Documents)
    (vla-postcommand doc "-XREF r *\n")
  );vlax-for doc
  (prompt "\nXRU Complete.")
  (princ)
);defun

 

What happens is that when the postcommand is applied to each document, we can see in the documentation that:

If the document is not active, the document is made activate and the string is executed when the document has focus.

Which is nice, because we do not have to activate the document, we can merely let the command do that part for us (IF we were to activate it anyway, with (vla-activate ...) then our Lisp routine would not execute fully).

 

However, we can also see that the latter portion of that sentence states that the string is executed when the document has focus... which, if we are iterating through many documents, will never maintain focus long enough for the command to fully execute.

 

So what ultimately happens when running that routine, is that the command is INITIATED in each drawing, however it never fully finishes UNTIL the user returns to that document, making it active again.

 

So, good in theory, but the execution remains bad. 

 

I've tried looking into other methods or approaches in Lisp, either with (eval ..) or blackboard symbols or other (vl ...) functions, but no luck. I think for OP's particular problem, an "acaddoc.lsp" solution or some type of reactor might work best. But without further input, all we can answer was the original question posed.

 

Best,

~DD

~DD
Senior CAD Tech & AI Specialist
Need AutoLisp help? Try my custom GPT 'AutoLISP Ace':
https://chat.openai.com/g/g-Zt0xFNpOH-autolisp-ace
Message 8 of 15
john.uhden
in reply to: CodeDing

It sounds to me as though our lady works in a multi-user environment and herself has several drawings opened at the same time.  She would probably like to know that when she switches drawings that the one being activated is showing updated xrefs.  So I was thinking that since all her open documents are in the documents collection, then a vla-sendcommand to each should work just fine.

She could define one command function, vl-propagate it, and vla-send it to each document in the collection.  No?

Hmm, except that the reload method has to call the document object which I think is always only the activedocument.  Nope, the object is the block itself, but getting to the block object of a non-active drawing requires getting to the document object of that drawing, and I don't know if that object is the same as in the documents collection.  Gotta do a little trial and error there.  Plus, if you can get at the blocks collection in a non-active drawing, and you are running C3D, then as @dbroad pointed out, there is no available IsXref property, but I think I recently posted an IsXref function that might work.

John F. Uhden

Message 9 of 15
dbroad
in reply to: scmallory

First, I think the idea of reloading xrefs in all open drawings is bonkers.  If you can't see the drawing, why would you care if the xrefs were up-to-date?  It is very possible to set up a document reactor that triggers a reload on the :VLR-documentBecameCurrent event.  I think it's a bad idea though.  AutoCAD already triggers a notification on the status line if any xrefs in the current drawing are not up-to-date.  If working with the most critical state of an xref is really important, right click on that status bar icon and choose reload all xrefs. The drafter merely needs to be aware of the notifications.

Regarding the is-xref property and such:

  • Parsing the block collection in a drawing with xrefs can be tricky.  Blocks definitions nested into xrefs will return an is-xref of :vlax-false unless it is also an xref.  But parsing the block collection is exactly what would be necessary to reload nested xrefs unless you just use (vl-cmdf "_.-xref" " "_r" "*").   
  • The names of Blocks nested into xrefs will have names with at least one "|" character. 
  • For block references, only external references will have a path property.

Since AutoLISP works only in the active document, as opposed to VBA and .NET which are hosted in the application rather than the document, sending commands and making other documents cause a number of other problems including:

  • Current program becomes inactive.
  • Delayed actions in other documents.

It is possible to send a command but when that command actually runs is indeterminate.

Architect, Registered NC, VA, SC, & GA.
Message 10 of 15
CodeDing
in reply to: dbroad

@dbroad ,

 

I think you bring up some good points, but I'd just like to remind everyone that UPDATING an XREF and RELOADING one are two different things. If OPs drawings all have many UNLOADED (yet still attached) XREFs, then I can see why it might be desirable to want to reload all XREFs. Just food for thought.

 

Best,

~DD

~DD
Senior CAD Tech & AI Specialist
Need AutoLisp help? Try my custom GPT 'AutoLISP Ace':
https://chat.openai.com/g/g-Zt0xFNpOH-autolisp-ace
Message 11 of 15
dbroad
in reply to: CodeDing

@CodeDing  Good point.  But that need hasn't been explained yet.  I'm also not sure that reloading unloaded xrefs indiscriminately is a good idea, if they've been deliberately unloaded.  If that is the case, however, I would think that limiting the reload to the open documents only as opposed to the entire project would be a mistake.  I think we need to know more from the OP. In any case, LISP is the wrong language to use, period.  It is a single document language and was never updated to work at the application level.  For those who want application level languages, .NET is probably the best choice.  I don't have the time or inclination to start using that at this stage in my life but here is a working vba example.  Again, I strongly discourage its use.  There are no error features built in and if any of the xrefs aren't found, it will break.

'This is a demonstration of how to use VBA to manage the document _
collection.  This will not reload the xrefs in an entire project _
but just the open documents.  It will also only reload the block _
type documents, not pdf documents.  This is an illustrative example _
only.  Feel free to modify. _
Written by D. C. Broad, Jr.  2-27-2021
Sub reloadall()
On Error GoTo ERRORHANDLER

Dim acad As AcadApplication
Dim docs As AcadDocuments
Dim doc As AcadDocument
Dim doc1 As AcadDocument

Dim blks As AcadBlocks
Dim blk As AcadBlock

Set acad = Application
Set docs = acad.Documents
Set doc1 = Application.ActiveDocument

For Each doc In docs
doc.Activate
Set blks = doc.Blocks
    For Each blk In blks
    If (blk.IsXRef = True) Then
    blk.Reload
    End If
    Next blk
    Next doc
doc1.Activate

Exit Sub

ERRORHANDLER:
MsgBox Err.Description

End Sub
Architect, Registered NC, VA, SC, & GA.
Message 12 of 15
1wildwes
in reply to: dbroad

Need to reload xrefs in all open drawings at once -  working on a project and you have several plan sheets open. You modify an xref(s) and you need to reload the modified xref in all open drawings so you may make an up to date plan set plot. Making every drawing current and reloading each xref is time consuming. I find my self having to do this quite a bit.

Message 13 of 15
john.uhden
in reply to: 1wildwes

I adapted this from a post by Tim Willey, 2006.

You do the testing.

It was slightly special because the OP didn't want to reload xrefs that had been purposefully unloaded.

(defun c:ReloadLoadedXrefs (/ Ent)
  (VL-LOAD-COM)
  (vlax-for doc (vla-get-documents (vlax-get-acad-object)))
    (vlax-for i (vla-get-Blocks doc)
      (and
        (= (vla-get-IsXref i) :vlax-true)
        (setq Ent (entget (tblobjname "block" (vla-get-Name i))))
        (= (logand 32 (cdr (assoc 70 Ent))) 32)
        (vla-Reload i)
      )
    )
  )
  (princ)
)

 

John F. Uhden

Message 14 of 15
4co2op0
in reply to: dbroad

Nothing like having to skim through a bunch of responses saying "This is a bonkers request, etc." from people who misunderstand the question, or just want to be difficult and show how much they know by saying you don't know what the OP is asking.

 

The OP's original question is valid and would be extremely helpful (but perhaps could have used a little more explanation for those who rightfully get lost in it with the technicalities.)

 

Yes, RELOADING and UPDATING an XREF are different (if one was previously UNLOADED, I would assume you wouldn't want to RELOAD that one with the command) However, when you go to the "External References" window, and you want to UPDATE the Xref that has changes, you RIGHT CLICK it then click "RELOAD". So technically, the question from OP was accurate, but I understand the need to clarify that as well.

 

If an Xref was modified by you, or someone else on the team, and you have 10+ sheets open which all reference that modified XREF, then it would be very beneficial to have some type of command that would RELOAD (er, *UPDATE) all "LOADED" Xrefs that require Reloading/updating in all Open drawings. (Think along the lines of the "SAVEALL" command, which saves all open drawings, without having to go to each open tab and save... which saves a ton of time when working with a large team working on a large set of drawings/xrefs)

 

my time would greatly benefit from some type of .NET program or LISP routine that could reload all modified xrefs that are actually loaded in all open drawings.

 

It looks like it is not possible through a lisp routine which makes sense. but if someone has another option for accomplishing this, I am certain there is a large amount of people who would benefit from it.

Message 15 of 15
dbroad
in reply to: 4co2op0

@4co2op0 Apologies if I offend but that was quite a rambling, hypercritical reply to a thread that was almost a year old.  Did the code examples already posted not work for you? If not, why not? If so, why post?

Architect, Registered NC, VA, SC, & GA.

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

Post to forums  

Autodesk Design & Make Report

”Boost