Listing Schedules placed on Sheets in Revit

By Saikat Bhattacharya

When views are placed on a ViewSheet in Revit, we can access the views using the ViewSheet.GetAllViewports(). However, if a schedule is placed on a viewsheet, it does not get listed using GetAllViewports(). How can we list the Schedule views that are placed on Viewsheet.

One solution to this requirement seems to be is to fake a deletion process. When an element is deleted in Revit, it also returns a list of some other elements that are linked/related to this element and will get deleted as well. These elements are the ones that are linked to or share some relationship to the element that is being deleted. This helps establish a parent-child relationship between the element that is being deleted (parent) and all the elements that get deleted (child) as a consequence of the deletion of the parent. For example, if we delete a wall, all the doors and windows that were placed on the wall get deleted too. Infact, so does the Door and Window tags as well, since they are in turn linked to Door and Window instances, which were linked to the Wall they were placed on. Using the API, when we encapsulate this deletion step in a transaction and later roll back the transaction and thus not affect the model at all.

A standalone tool what was developed on this principle can be accessed from this blog post in Jeremy’s The Building Coder blog.

Using this same approach, when I tried to delete a ViewSheet instance, it deletes the views that were placed on it – including the ScheduleSheetInstance. On the API front, following the same principle, I access the ViewSheet in a model, encapsulate a deletion process of the ViewSheet using a transaction, get the Ids of elements that are returned from Document.Delete(). And then roll back the transaction so that the model remains unaffected. Once I have the Ids of the elements that get deleted on ViewSheet deletion, I can iterate through each of the elements to check which ones are of ScheduleSheetInstance type and those elements would be the Schedules that were placed on that specific ViewSheet.

The code snippet which shows the entire workflow is included here. Please note that if you end up using this approach, you have to ensure that the active view is not the ViewSheet itself – since deleting the active view is not permissible from the User Interface either. 

using System;

using System.Collections.Generic;

using System.Text;

using System.Linq;

 

using Autodesk.Revit.Attributes;

using Autodesk.Revit.DB;

using Autodesk.Revit.UI;

 

namespace Revit.SDK.Samples.HelloRevit.CS

{

 

  [Transaction(TransactionMode.Manual)]

  public class Command : IExternalCommand

  {

    public Result Execute(ExternalCommandData commandData,

      ref string message,

      ElementSet elements)

    {

      UIApplication uiApp = commandData.Application;

      Document doc = uiApp.ActiveUIDocument.Document;

      // Find view family type

      FilteredElementCollector vftCollector =

        new FilteredElementCollector(doc);

      vftCollector.OfClass(typeof(ViewSheet));

 

      //for simplicity, lets take one ViewSheet only

      ViewSheet vs =

        vftCollector.Cast<ViewSheet>().First();

 

      ICollection<ElementId> ids = null;

      String msg = String.Empty;

      using (Transaction trans =

        new Transaction(doc, "TempTransaction"))

      {

        trans.Start();

 

        // Ensure that ViewSheet is not the active view

        // before performing the delete task

        ids = doc.Delete(vs);

 

        trans.RollBack();

      }

 

      if (null != ids)

      {

        foreach (ElementId id in ids)

        {

          ScheduleSheetInstance schInstance =

            doc.GetElement(id) as ScheduleSheetInstance;

 

          if (null != schInstance)

          {

            msg = msg + vs.ViewName

              + " viewsheet contains "

              + schInstance.Name

              + " schedule with ID: "

              + schInstance.Id.ToString()

              + "\n";

          }

        }

      } 

      TaskDialog.Show("Results", msg);

 

      return Result.Succeeded;

    }

  }

}


Comments

4 responses to “Listing Schedules placed on Sheets in Revit”

  1. HI Saikat.
    I have done this a different way in my Project Browser App.
    Dim schCol As FilteredElementCollector = New FilteredElementCollector(doc, sheetView.Id).OfClass(GetType(DB.ScheduleSheetInstance))
    If schCol.Count > 0 Then
    ‘do you stuff in here
    End If
    The only issue that I have had with this is the creation of the FilteredElementCollector is slow as it looks to be opening the sheet view, which if you have 400 sheets in a project can take some time.
    Regards
    Phillip

  2. Thanks for sharing your approach Phillip.
    This looks like a better way of doing it – atleast for almost all cases, where there arent so many viewsheets to work with in a model. If you happen to see if the faking deletion approach is faster, please do share your findings. It will be good to learn from what you find..

  3. Other Workaround coul be just ask the ScheduleSheetInstance for its sheet through the property OwnerViewId;
    I have 500 sheets and only 7 schedules. Goes a lot faster:
    ScheduleSheetInstance vsch =
    viewSchedule as ScheduleSheetInstance;
    ElementId shid = vsch.OwnerViewId;

  4. Thanx this worked well.

Leave a Reply to Phillip MillerCancel reply

Discover more from Autodesk Developer Blog

Subscribe now to keep reading and get access to the full archive.

Continue reading