Retrieving Schedules on a Sheet
Originally Published inGuy Robinson ↗ recently explained an easy way to access all elements in a schedule.
Victor Chekalin ↗ picked up and expanded on that.
Here is his solution to retrieve all schedules in a view and elements from a schedule. In his own words:
One wonderful day I had to retrieve schedules which are presented on a sheet:
At first I looked at the Revit API Help but unfortunately there is no method such as GetSchdulesOnView in the ViewSheet class. There is no explicit way to get it. After a couple of hours trying to achieve that I need I encountered Guy’s simple solution to access all elements in a schedule. The solution is use FilteredElementCollector and pass in the element id of the view in which you want to collect elements.
I created the following simple extension method GetSchedules to get schedules on view:
public static class ViewSheetExtensions
{
public static IEnumerable<ViewSchedule>
GetSchedules( this ViewSheet viewSheet )
{
var doc = viewSheet.Document;
FilteredElementCollector collector =
new FilteredElementCollector(
doc, viewSheet.Id );
var scheduleSheetInstances =
collector
.OfClass( typeof( ScheduleSheetInstance ) )
.ToElements()
.OfType<ScheduleSheetInstance>();
foreach( var scheduleSheetInstance in
scheduleSheetInstances )
{
var scheduleId =
scheduleSheetInstance
.ScheduleId;
if( scheduleId == ElementId.InvalidElementId )
continue;
var viewSchedule =
doc.GetElement( scheduleId )
as ViewSchedule;
if( viewSchedule != null )
yield return viewSchedule;
}
}
}
It can be used like this:
var schedules = viewSheet
.GetSchedules()
.ToList();
foreach( var viewSchedule in schedules )
{
// Do something
}
Here is the demo result:
But I decided not to stop and go deeper. The next step is to get all elements which are involved in a schedule. The approach is the same as with schedules. Using FiltereredElementCollector but instead of the ViewSheet element id we pass in the ViewSchedule id.
The extension method is similar:
public static class ViewScheduleExtensions
{
public static IEnumerable<ElementId>
GetElementIdsInSchedule(
this ViewSchedule viewSchedule )
{
var doc = viewSchedule.Document;
FilteredElementCollector collector =
new FilteredElementCollector(
doc, viewSchedule.Id );
var elementIds = collector
.WhereElementIsNotElementType()
.ToElementIds();
return elementIds;
}
}
But there is an additional little nuance. If I retrieve elements from a material takeoff schedule, the method will return all materials in the project together with other elements. The solution is to just skip all elements which are materials:
foreach( var id in elementIds )
{
var element = doc.GetElement( id );
if( element is Material )
continue;
// Do something
}
Here is the result of my demo project:
I attached the demo Visual Studio solution and Revit project.
I hope this information will useful for developers.
Have a nice day,
Victor.