Revit API Forum
Welcome to Autodesk’s Revit API Forums. Share your knowledge, ask questions, and explore popular Revit API topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Change active document

19 REPLIES 19
SOLVED
Reply
Message 1 of 20
Anonymous
12377 Views, 19 Replies

Change active document

When you have 2 revit projects open and want to switch between them it can be done with:

application.OpenAndActivateDocument(file).

 

In order to get the filename I used the get it with Document.PathName.

 

Now I come accross problems with files on Revit Server and BIm 360 docs. Their Document.Pathname stays empty.

 

 

So, my questions is, how do I switch between those documents (when Document.Pathname is empty) ?

 

Is there a way to switch between documents without having to specify the file name ?

 

 

19 REPLIES 19
Message 2 of 20
RPTHOMAS108
in reply to: Anonymous

The only way I have found is indirectly via UIDocument.ShowElements. You pick an element from the DB document you want to change to, create a UIDocument object from a DB document and use UIDocument.ShowElements. You have to handle the occasional “No good view found” dialogue but it seems to always switch the active document regardless of what is found. Helps if it is a View specific element.

 

Not sure if there is a better way, also wondering when future implementation of .ActiveUIDocument is coming (as noted in RevitAPI.chm file). Odd that there seems to be no way to do this directly.

 

https://forums.autodesk.com/t5/revit-api-forum/how-to-open-and-active-a-new-document-that-is-not-sav...

 

 "External API commands can access this property in read-only mode only! The ability to modify the property is reserved for future implementations."

Message 3 of 20
Anonymous
in reply to: RPTHOMAS108

Haha, never thought of this approach 🙂 thanks. "Odd that there seems to be no way to do this directly" Yeah, and even stranger they make an "OpenAndActivate", while the file is already openend. A simple "SetActiveDocument" would be enough.

 

 

Message 4 of 20
jeremytammik
in reply to: Anonymous

Many thanks to @RPTHOMAS108 for the solution!

 

Also documented here:

 

http://thebuildingcoder.typepad.com/blog/2010/11/mirroring-in-a-new-family-and-changing-active-view....

 

"The first issue that arises is that the mirror command requires a current active view, which is not automatically present in the family document. Joe discovers a workaround for that issue using the ShowElements method. It generates an unwanted warning message, so a second step is required to deal with eliminating that as well.

 

As you can see on reading the final solution carefully, you can use the ShowElements method to change the active view and even switch it between the family and project documents. The official Revit 2011 API does not provide any method to switch the active view, but using ShowElements can be used to create a workaround for that."

 

Cheers,

 

Jeremy



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Message 5 of 20
Anonymous
in reply to: jeremytammik

Thanks Jeremy, 

 

It's the same conclusion as RPTHOMAS108 posted 🙂

 

Well, I gave it a shot on the Revit Ideas site: Revit Idea

 

So, everyone who reads this post, please vote, so AutoDesk will notice and maybe put this functionality in the next Revit 🙂 

 

Message 6 of 20
Anonymous
in reply to: Anonymous

Hmm, close but no sigar 😞

 

I start with document A. Later I open Document B which becomes the active document. I use the showelements to open a view from Document B, so it becomes the active document. Then I use DOcB.Close(false) and revit keeps telling me it can't do that because of some subtransaction being active??? No idea what transaction Revit means 😞

 

Message 7 of 20
jeremytammik
in reply to: Anonymous

Dear Remy,

 

I never heard of that problem before.

 

Here are two exploration of closing documents... don't know whether they will be of any use in your case:

 

 

Cheers,

 

Jeremy



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Message 8 of 20
Anonymous
in reply to: jeremytammik

The exact message reads: Revit encountered a Autdesk.Revit.Exceptions.InvalidOperationException: Close is not allowed when there is any open sub-transaction, transaction or transaction group.

 

 

What I do is:

In a project, open family, do some actions within a transaction which I commit and afterwards dispose. Then save the family. Use the showelements option to get a view of the project active and then try to close the family. That is when this errors comes.

 

 

Message 9 of 20
jeremytammik
in reply to: Anonymous

Dear Remy,

 

Sounds weird.

 

If you want the development team (or anyone else, for that matter) to be able to take a look, please provide a complete minimal reproducible case including sample model, macro and exact steps to reproduce:

 

http://thebuildingcoder.typepad.com/blog/about-the-author.html#1b

 

Cheers,

 

Jeremy



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Message 10 of 20
Anonymous
in reply to: jeremytammik

It is pretty easy to reproduce:

 

[Transaction(TransactionMode.Manual)]
[Regeneration(RegenerationOption.Manual)]
[Journaling(JournalingMode.NoCommandData)]
public class DrieBToolTest : IExternalCommand
{

public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{
UIApplication uiapp = commandData.Application;
UIDocument uidoc = uiapp.ActiveUIDocument;
Document doc = uidoc.Document;

// select some elements in the first document

FilteredElementCollector notElemTypeCtor = (new FilteredElementCollector(doc, uidoc.ActiveGraphicalView.Id)).WhereElementIsNotElementType();
List<ElementId> theelems = notElemTypeCtor.ToList().Select(theelem => theelem.Id).ToList();

 

// open the second file and do some actions

string fam = @"d:\test\fam\31_3B_vo bu deur met weerszijde 2 zijlichten.rfa";
UIDocument famDoc = commandData.Application.OpenAndActivateDocument(fam);

Transaction transac = new Transaction(famDoc.Document);
transac.Start("change scale");
famDoc.ActiveView.get_Parameter(BuiltInParameter.VIEW_SCALE_PULLDOWN_METRIC).Set(20);
transac.Commit();
SaveAsOptions opt = new SaveAsOptions { OverwriteExistingFile = true };
famDoc.Document.SaveAs(fam, opt);

 

// On a new file the doc,PathName is empty

if (!string.IsNullOrEmpty(doc.PathName))
{
commandData.Application.OpenAndActivateDocument(doc.PathName);
famDoc.Document.Close(false); // no problem here
}
else
{

// this is the way to go when to avoid using OpenAndActivateDocument
uidoc.ShowElements(theelems);
uidoc.RefreshActiveView();
famDoc.Document.Close(false); //here revit throws the exception and doesn't close the file
}

return Result.Succeeded;

}

 

Message 11 of 20
jeremytammik
in reply to: Anonymous

Please also describe the exact steps to reproduce the problem. Thx!



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Message 12 of 20
Anonymous
in reply to: jeremytammik

 

Start revit

Start with a new project

Run the code

 

Message 13 of 20
RPTHOMAS108
in reply to: Anonymous

Sorry to hear this doesn't work.

 

To be honest I don't think I've actually needed to save after using this trick since I'm usually either opening and activating (in the case of a add-in that processes multiple files) or just working in the current file within an IExternalCommand context.

 

I do get this same exception for something unrelated, where I open detached. Hard to diagnose these things when you have other add-ins running which may be opening transactions during events etc.

Message 14 of 20
jeremytammik
in reply to: Anonymous

Dear Remy,

 

I have not yet submitted this to the development team.

 

I did take a closer look at your code now, at least, and have some minor improvement suggestions as follows:

 

    /// <summary>
    /// Toggle back and forth between two different documents
    /// </summary>
    void ToggleViews( 
      View view1, 
      string filepath2 )
    {
      Document doc = view1.Document;
      UIDocument uidoc = new UIDocument( doc );
      Application app = doc.Application;
      UIApplication uiapp = new UIApplication( app );

      // Select some elements in the first document

      ICollection<ElementId> idsView1
        = new FilteredElementCollector( doc, view1.Id )
          .WhereElementIsNotElementType()
          .ToElementIds();

      // Open the second file

      UIDocument uidoc2 = uiapp
        .OpenAndActivateDocument( filepath2 );

      Document doc2 = uidoc2.Document;

      // Do something in second file

      using( Transaction tx = new Transaction( doc2 ) )
      {
        tx.Start( "Change Scale" );
        doc2.ActiveView.get_Parameter(
          BuiltInParameter.VIEW_SCALE_PULLDOWN_METRIC )
            .Set( 20 );
        tx.Commit();
      }

      // Save modified second file

      SaveAsOptions opt = new SaveAsOptions
      {
        OverwriteExistingFile = true
      };

      doc2.SaveAs( filepath2, opt );

      // Switch back to original file;
      // in a new file, doc.PathName is empty

      if( !string.IsNullOrEmpty( doc.PathName ) )
      {
        uiapp.OpenAndActivateDocument(
          doc.PathName );

        doc2.Close( false ); // no problem here, says Remy
      }
      else
      {
        // Avoid using OpenAndActivateDocument

        uidoc.ShowElements( idsView1 );
        uidoc.RefreshActiveView();

        //doc2.Close( false ); // Remy says: Revit throws the exception and doesn't close the file
      }
    }

 

The things I care about here are:

 

  • Avoid using unnecessary `ToList` calls all over the place.
  • Encapsulate all transactions in a `using` statement.

 

It probably won't change the problem of closing the family, though.

 

Cheers,

 

Jeremy



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Message 15 of 20
jeremytammik
in reply to: Anonymous

Edited and saved for posterity here:

 

http://thebuildingcoder.typepad.com/blog/2018/03/switch-view-or-document-by-showing-elements.html

 

Cheers,

 

Jeremy



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Message 16 of 20
Kisli89
in reply to: jeremytammik

I had such problems with transaction when I after changeng ActiveDocument close document.
I solve this through external event.

//After all logic i call external event
//Glob is static clase where i store some constant and use for easy Glob.GeneralEventWithParams.RunFunc(CloseDoc, Glob.GeneralExternalEventWithParams, famDoc); ui_doc.ShowElements(new List<ElementId> { ins.Id }); ui_doc.RefreshActiveView();

 

 

 //Method that i use for closing and call inside event
public static bool CloseDoc(UIDocument ui_doc, params object [ ] obk) { var doc = obk [ 0 ] as Document; doc.Close(false); return true;



  //External event that i use
public class GeneralExternalEventWithParams :IExternalEventHandler { private Func<UIDocument, object [ ], bool> Function { get; set; } public void Execute(UIApplication app) { try { var ui_doc = app.ActiveUIDocument; var doc = ui_doc.Document; if ( Function != null ) { Function?.Invoke(ui_doc, Params); } } catch ( Exception e ) { e.WriteEx(); } } public void RunFunc(Func<UIDocument, object [ ], bool> function, ExternalEvent runningEvent, params object [ ] parameters) { try { Function = function; Params = parameters; runningEvent.Raise(); } catch ( Exception e ) { } } public object [ ] Params { get; set; } public string GetName() { return "GeneralExternalEventWithParams"; } }




 

 

Message 17 of 20

Hi, coming from the future 🙂

 

I personally use UIDocument.RefreshActiveView() and it seem work for me.

Message 18 of 20
tamas.deri
in reply to: Anonymous

From the even more distant future: I've found, that after changing the active document with uiDoc.ShowElements() I'm not able to close the previous document with oldUiDoc.SaveAndClose(), it does nothing, no exceptions thrown, but instead of returning the expected boolean it jumps right into my IdlingEventHandler.

Seems similar to https://forums.autodesk.com/t5/revit-api-forum/closing-active-family-document/m-p/11471099/highlight... but the alternate method is not always available...

 

Message 19 of 20
tamas.deri
in reply to: tamas.deri

I did some further investigation, and found the connection between the issue mentioned in the linked topic.

While my code did not throw any exceptions in Visual Studio (silly me had no try-catch around the specific code), I've found an exception in the Journal:

' 0:< External event handler <RevitExternalEventHandler> failed with an exception {Close is not allowed when there is any open sub-transaction, transaction or transaction group.}. The event was registered by an AddIn ...(a guid) 

So it seems that it is not possible to close a document (neither using doc.Close() nor uiDoc.SaveAndClose()) after activating another document via uidoc.ShowElements() if we are in a valid API context (ExternalCommand or ExternalEvent). However there are no issues at all when whe are "outside of valid API context", and I execute my code on a cached UIApplication. I've tried to do everything by the book, and only interact with the Revit API in valid API context, but this case looks like an exception from the general rule, where it should be avoided.

 

@jeremytammikcould you please put up this issue to the development team for further investigation?

 

Message 20 of 20
jeremy_tammik
in reply to: tamas.deri

Well, the exception to the general rule probably means that you found a loophole that the development team will be happy to close, and then what you are after will not work in that form any more at all. Maybe you can work around the issue by combining the external event with a one-off Idling event? Afaik, there are no restrictions at all on what you can do in an Idling event handler, whereas, according to the journal entry you share, certain restrictions do apply to external events.

   

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open

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

Post to forums  

Rail Community


Autodesk Design & Make Report