Accessing Data from Linked File using Revit API

Accessing Data from Linked File using Revit API

A_S_E_
Participant Participant
1,441 Views
2 Replies
Message 1 of 3

Accessing Data from Linked File using Revit API

A_S_E_
Participant
Participant

Hello Friends,

 

First of all, please dont judge me, I am trying to learn Api for over one year with no success. SO now I am learning checking out other people scripts that make any sense to me nd learn from it.

 

So I came upon this script from this link

https://adndevblog.typepad.com/aec/2012/10/accessing-data-from-linked-file-using-revit-api.html.

 

His explanantion was simple to follow as under

 

How can we access data from a Linked File. For example, for a certain requirement, how can we use the Revit API to access the Level information of all the Wall inside of a Linked file.

To meet this requirement, we can get a list of all the active documents loaded in the current Revit session using Application.Documents() collection. The linked Revit documents will also form a part of this collection. We can then use filters in Revit API to create a collection of Linked Revit documents. Comparing the name of the Linked File with that of the document object in the Documents() collection, we can get access to the required document object of the Linked file we are interested in working with.

Once we have the document object, all we need is to simply access each wall element using the FilteredElementCollector on this document object of the linked file. From each wall, we can access the Level information, as desired. The following code snippet illustrates the entire approach.

 

I made changes which wree not many to make it work. It just doesnt do anything in my Revit file. 

 

Here is my script with no errors.

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Collections.ObjectModel;
using System.Xml.Linq;
using System.Windows.Media.Imaging;
using Autodesk.Revit.DB;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.UI;
using Autodesk.Revit.ApplicationServices;


namespace Elements_from_Linked_files
{
[Transaction(TransactionMode.Manual)]

public class Class1 : IExternalCommand

{
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{

UIApplication uiapp = commandData.Application;
UIDocument uidoc = uiapp.ActiveUIDocument;
Application app = uiapp.Application;
Document doc = uidoc.Document;

FilteredElementCollector collector = new FilteredElementCollector(doc);

 

IList<Element> elems = collector

.OfCategory(BuiltInCategory.OST_RvtLinks)

.OfClass(typeof(RevitLinkType))

.ToElements();

 

foreach (Element e in elems)

{

RevitLinkType linkType = e as RevitLinkType;

String s = String.Empty;

 

foreach (Document linkedDoc in app.Documents)

{

if (linkedDoc.Title.Equals(linkType.Name))

{

FilteredElementCollector collLinked =

new FilteredElementCollector(linkedDoc);

IList<Element> linkedWalls =

collLinked.OfClass(typeof(Wall)).ToElements();

 

foreach (Element eleWall in linkedWalls)

{

Wall wall = eleWall as Wall;

s = s + "\n" + eleWall.LevelId;

}

 

TaskDialog.Show("Wall Level", linkedDoc.PathName + " : " + s);

}

}

}


return Result.Succeeded;
}
}
}

 

If you have any clue and just give me a hint, what am I doind wrong, that would make my day.

Thanks in advance

0 Likes
Accepted solutions (1)
1,442 Views
2 Replies
Replies (2)
Message 2 of 3

jeremy_tammik
Alumni
Alumni
Accepted solution

I would remove the call to TaskDialog from the processing code. Log the debug printout results to the debug console or an output log file instead. Mixing user interaction with database processing is always a bad idea and may be causing the iteration to fail.

  

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

A_S_E_
Participant
Participant

Thanks Jeremy, I used that advice, and added the test taskdialogs at the end of every loop and finally got the result i wanted to see. It displays no of links in the file, their names and individually elements in each link and at the end all of them together. 

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Collections.ObjectModel;
using System.Xml.Linq;
using System.Windows.Media.Imaging;
using Autodesk.Revit.DB;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.UI;
using Autodesk.Revit.ApplicationServices;


namespace Elements_from_Linked_files
{
[Transaction(TransactionMode.Manual)]

public class Class1 : IExternalCommand

{
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{

UIApplication uiapp = commandData.Application;
UIDocument uidoc = uiapp.ActiveUIDocument;
Application app = uiapp.Application;
Document doc = uidoc.Document;

FilteredElementCollector collector = new FilteredElementCollector(doc);

 

IList<Element> elems = collector

.OfCategory(BuiltInCategory.OST_RvtLinks)

.OfClass(typeof(RevitLinkType))

.ToElements();

string[] FilesProccesed = new string[elems.Count * 2];
int DocCounter = 0;
bool DocFound = false;

TaskDialog.Show("Elements", elems.Count.ToString());

foreach (Element e in elems)

{

RevitLinkType linkType = e as RevitLinkType;

String s = String.Empty;

TaskDialog.Show("Link", e.Name);
//TaskDialog.Show("LinkType", e.ToString());


foreach (Document linkedDoc in app.Documents)

{
for (int i = 0; i < DocCounter; i++)
{
if (linkedDoc.PathName.ToString() == FilesProccesed[i])
{
DocFound = true;
break;
}
else DocFound = false;

}

if (!DocFound)
{
TaskDialog.Show("Test3", message);
TaskDialog.Show("Document", linkedDoc.PathName.ToString());
//TaskDialog.Show("Title", linkedDoc.Title);
//TaskDialog.Show("Name", linkType.Name);
//TaskDialog.Show("Test4", message);
FilteredElementCollector collLinked =

new FilteredElementCollector(linkedDoc);

IList<Element> linkedWalls =

collLinked.OfClass(typeof(Wall)).ToElements();

 

foreach (Element eleWall in linkedWalls)

{
TaskDialog.Show("eleWall", eleWall.Name);
Wall wall = eleWall as Wall;

s = s + "\n" + eleWall.Name;

}


TaskDialog.Show("Test6", message);
TaskDialog.Show("Wall Level", linkedDoc.PathName + " : " + s);

FilesProccesed[DocCounter] = linkedDoc.PathName.ToString();
TaskDialog.Show("DocCounter", DocCounter.ToString());
DocCounter++;


}


}

}


return Result.Succeeded;
}
}
}

0 Likes