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

29/11/2015

Запись данных в ключевую спецификацию

Андрей Фазлеев поделился интересным решением по записи данных в ключевую спецификацию.

Далее с его слов:

Не так давно я писал о способе создания пользовательской таблицы

Задумался о том, как же теперь наполнить её через API.

Оказалось что здесь всё прозрачно и методы работы описаны в документации:

Код - C#: [Выделить]
  1.  
  2. //Code Region: Inserting a row
  3. public void CreateSubtitle(ViewSchedule schedule)
  4. {
  5.     TableData colTableData = schedule.GetTableData();
  6.  
  7.     TableSectionData tsd = colTableData.GetSectionData(SectionType.Header);
  8.     tsd.InsertRow(tsd.FirstRowNumber + 1);
  9.     tsd.SetCellText(tsd.FirstRowNumber + 1, tsd.FirstColumnNumber, "Schedule of column top and base levels with offsets");
  10. }
  11.  

Получаю объект TableSectionData, далее создаются строчки, столбцы, пишутся/читаются данные из ячеек, задаю форматирование.

Можно сделать таблицу с расширенными возможностями форматирования, записывать туда данные. То что возможности есть - хорошо, при необходимости применю, на некоторое время даже забыл про эту тему.

До сегодняшнего дня был ещё один интересный нерешённый вопрос: как заполнять программным способом ключевую спецификацию?

В первый раз он возник месяцев восемь назад, как ни бился над ним - не нашёл подхода.

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

Обратите внимание на строчку:

Код - C#: [Выделить]
  1.  
  2. TableSectionData tsd = colTableData.GetSectionData(SectionType.Header);
  3.  

Тэкс, Header, Header. Если есть Header, может есть и сама таблица?

Набираю SectionType и Intellisense предложил первой строчкой интересный вариант:

 

Пишу код как в справке, заменил Header на Body.

Строки данных добавляются/удаляются методами InsertRow и RemoveRow. Уже хорошо.

А вот с записью данных возникла проблема. На методе  SetCellText возникает ошибка, записать текст не удаётся таким же образом как это делается в заголовке таблицы.

Всё, приехали? Как бы не так!

Выручил Revit Lookup:

выбрал спецификацию, покопался в данных, но не нашёл ничего, что могло бы помочь в записи данных.

 

Делал несколько подходов, в последний из них забыл выбрать спецификацию в диспетчере проектов и получил совершенно другую картинку:

 

Что случилось? А случилось вот что: при снятом выделении вида в диспетчере проектов в Revit Lookup попадают все элементы текущего вида.

То есть каждая строчка ключевой спецификации - это объект класса Element. Его нет в модели и у него нет категории.

Зато есть параметры, соответствующие полям спецификации.

 

Через FilteredElementCollector получаем элементы ключевой спецификации, перебираем их и задаём требуемые значения.

Пример кода:

Код - C#: [Выделить]
  1.  
  2. private void WriteToKeySchedule(View view)
  3.     {
  4.    // Получение элементов вида
  5.    FilteredElementCollector collector = new FilteredElementCollector(view.Document, view.Id);
  6.  
  7.         // Для примера взят параметр "Комментарии", который есть у большинства элементов
  8.         // перед запуском примера добавьте его в ключевую спецификацию
  9.             string s = "test";
  10.             foreach (Element element in collector)
  11.             {
  12.                 element.LookupParameter("Комментарии").Set(s);
  13.             }       
  14.     }
  15.  

Поля спецификации заполнены:

 

Далее дело техники - прикрутить модуль связи с Excel/CSV/XML... да с чем угодно, всё зависит от конкретных задач, и писать данные в ключевые спецификации

Пример использования см. макросы в прикреплённом файле

Удачи!

--

Мое внимание привлек код извлечения элементов на виде. Извлекать элементы с помощью FilteredElementCollector, без дополнительной фильтрации – опасное занятие. Действительно стоит ограничение по виду, но было бы неплохо сделать дополнительную проверку. Иначе, даже во время тестирования возможно случайно выполнить код не на виде со спецификацией, а на 3D, или плане этажа. В этом случае, приложение может на долго подвиснуть.

Код - C#: [Выделить]
  1. if (view.ViewType != ViewType.Schedule)
  2. throw new ArgumentException("Вид не является спецификацией")

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

Опубликовано 29.11.2015
Отредактировано 29.11.2015 в 10:20:34