ADN Open CIS
Сообщество программистов Autodesk в СНГ

19/07/2013

Поиск спецификаций на листе

Guy Robinson недавно рассказал нам о легком способе как получить доступ ко всем элементам спецификации.

Виктор Чекалин немного расширил возможности данного метода.

Ниже представлено его решение как получить все спецификации на листе и все элементы в спецификации.

В один прекрасный день мне понадобилось получить все Спецификации представленные на Листе.

Первым делом я посмотрел в документацию по Revit API, но к большому сожалению не обнаружил там метода типа GetSchedulesOnView в классе ViewSheet. Таким образом, не существует явного способа получить требуемые данные. После пары часов попыток достичь того что мне нужно, я наткнулся на решение Гая (Guy Robinson) как получить доступ ко всем элементам в спецификации. Решение было следующим: использовать FilteredElementCollector и в конструкторе передать идентификатор вида, на котором я хочу искать элементы, т.е. идентификатор вида Спецификации.

Я создал простое решение в виде метода-расширения, который возвращает список всех спецификаций, находящихся на листе.

Код - C#: [Выделить]
  1. public static class ViewSheetExtensions
  2.     {
  3.         public static IEnumerable<ViewSchedule>
  4.             GetSchedules(this ViewSheet viewSheet)
  5.         {
  6.             var doc = viewSheet.Document;
  7.  
  8.             FilteredElementCollector collector =
  9.                 new FilteredElementCollector(doc, viewSheet.Id);
  10.  
  11.             var scheduleSheetInstances =
  12.                 collector
  13.                     .OfClass(typeof(ScheduleSheetInstance))
  14.                     .ToElements()
  15.                     .OfType<ScheduleSheetInstance>();
  16.  
  17.             foreach (var scheduleSheetInstance in
  18.                 scheduleSheetInstances)
  19.             {
  20.                 var scheduleId =
  21.                     scheduleSheetInstance
  22.                         .ScheduleId;
  23.                 if (scheduleId == ElementId.InvalidElementId)
  24.                     continue;
  25.  
  26.                 var viewSchedule =
  27.                     doc.GetElement(scheduleId)
  28.                     as ViewSchedule;
  29.  
  30.                 if (viewSchedule != null)
  31.                     yield return viewSchedule;
  32.             }
  33.         }
  34.     }
  35.  

Использовать данный метод очень просто
Код - C#: [Выделить]
  1.  
  2.          var schedules =                
  3.                 viewSheet
  4.                     .GetSchedules()
  5.                     .ToList();
  6.             foreach (var viewSchedule in schedules)
  7.             {
  8.                 // Какие-либо действия со спецификациями                
  9.             }

Результат выполнения демонстрационной команды можно увидеть на скриншоте.

Но я решил не останавливаться на достигнутом и идти дальше. Следующим шагом будет являться метод, который позволит получить все элементы, так или иначе связанные со спецификацией. Используется тот же самый подход что и со спецификациями на листе. Используя FilteredElementCollector, только вместо идентификатора Листа, в качестве параметра я буду передавать идентификатор спецификации.

Метод-расширения похож на предыдущий:

Код - C#: [Выделить]
  1.  
  2.     public static class ViewScheduleExtensions
  3.     {
  4.         public static IEnumerable<ElementId>
  5.             GetElementIdsInSchedule(this ViewSchedule viewSchedule)
  6.         {
  7.             var doc = viewSchedule.Document;
  8.  
  9.             FilteredElementCollector collector =
  10.                 new FilteredElementCollector(doc, viewSchedule.Id);
  11.  
  12.             var elementIds =
  13.                 collector
  14.                     .WhereElementIsNotElementType()
  15.                     .ToElementIds();
  16.  
  17.             return elementIds;
  18.         }
  19.     }
  20.  

Но в случае с элементами на спецификации есть небольшой нюанс. Если я буду извлекать элементы со спецификации вида Расход материала, то в результате я получу также и список всех материалов проекта вместе с элементами, находящимися в спецификации. Решение этой проблемы простое – просто пропускать элементы с типом Material при итерации элементов:

Код - C#: [Выделить]
  1.             foreach (var elementId in elementIds)
  2.             {
  3.                 var element =
  4.                     doc.GetElement(elementId);
  5.  
  6.                 if (element is Material)
  7.                     continue;
  8.  
  9.                 // Какие-либо действия с элементами спецификации.
  10.  
  11.             }
  12.  

На скриншоте представлен результат выполнения тестовой команды.

Скачать архив проекта можно по ссылке или на GitHub

Источник: http://thebuildingcoder.typepad.com/blog/2013/02/retrieving-schedules-on-a-sheet.html

Обсуждениеhttp://adn-cis.org/forum/index.php?topic=117.0

Опубликовано 19.07.2013
Отредактировано 19.07.2013 в 13:55:35