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

04/12/2013

Группировка заголовков спецификации

Вопрос: Я пытаюсь сгруппировать заголовки спецификации с помощью метода ViewSchedule.GroupHeaders, но все время выскакивает ошибка: "Headers could not be grouped. Parameter name: right" (Заголовки не могут быть сгруппированы. Имя параметра: right)

Ответ: Действительно. Такая проблема существует. Мы уже обсуждали ее в прошлом и предлагали некоторые решения.

Первый случай

Метод ViewSchedule.GroupHeaders падает с ошибкой приведенной выше.

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

Я сделал небольшое расследование проблемы и нашел парочку способов обойти эту ошибку:

  1. Активировать вид со спецификацией и уже затем только сгруппировать заголовки
  2. Обновить данные спецификации, когда спецификация содержит не актуальные данные, потом сгруппировать заголовки.

Мне кажется, что второй способ является довольно правильным и можно сказать что таким образом можно «исправить» ошибку. Нужно всего лишь вручную обновить данные.

Второй случай

С помощью API нельзя получить обновленное значение из спецификации, если спецификация неактивна.

Чтобы воспроизвести проблему можете выполнить следующие действия:

  1. Закройте спецификацию
  2. Вызовите метод IsCellOverridden. Метод вернет True.
  3. Вызовите метод ResetCellOverride
  4. Вызовите метод IsCellOverridden. Метод вернет True (т.е. нет реакции на ResetCellOverride)
  5. Откройте спецификацию.
  6. Вызовите метод IsCellOverridden. Метод вернет True.
  7. Вызовите метод ResetCellOverride
  8. Вызовите метод IsCellOverridden. Метод вернет False (как и ожидалось)

В качестве решения нужно заново вызвать метод viewSchedule.GetTableData.

Таким образом, API для работы с телом спецификации работают некорректно, когда спецификация закрыта.

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

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

Ответ: Я вас понял. Решил проблему с помощью метода, описанного в первом случае.

Я создал спецификацию, закрыл транзакцию, активировал вид с только что созданной транзакцией и затем сгруппировал заголовки.

Я также заметил интересную особенность. Индекс с номером столбца не учитывает скрытые столбцы.

Вот пример команды, демонстрирующей использование метода ViewSchedule.GroupHeaders.

Код - C#: [Выделить]
  1.         public Result Execute(
  2.                   ExternalCommandData commandData,
  3.                   ref string message,
  4.                   ElementSet elements)
  5.         {
  6.           
  7.             try
  8.             {
  9.                 UIDocument uidoc = commandData.Application
  10.                   .ActiveUIDocument;
  11.  
  12.                 Document doc = uidoc.Document;
  13.  
  14.                 // Создание спецификации
  15.  
  16.                 Transaction tran = new Transaction(doc);
  17.                 tran.Start("Создание спецификации");
  18.  
  19.                 ViewSchedule sampleSchedule
  20.                   = ViewSchedule.CreateSchedule(doc, new
  21.                     ElementId(BuiltInCategory.OST_Windows));
  22.  
  23.                 foreach (ElementId id in
  24.                   ViewSchedule.GetAvailableParameters(doc, new
  25.                     ElementId(BuiltInCategory.OST_Windows)))
  26.                 {
  27.                     try
  28.                     {
  29.                         sampleSchedule.Definition.AddField(
  30.                           new SchedulableField(
  31.                             ScheduleFieldType.Instance, id));
  32.                     }
  33.                     catch (Exception)
  34.                     {
  35.                     }
  36.                 }
  37.                 ScheduleDefinition sampleDefinition
  38.                   = sampleSchedule.Definition;
  39.  
  40.                 // Скроем два первых столбца
  41.  
  42.                 sampleDefinition.GetField(0).IsHidden = true;
  43.                 sampleDefinition.GetField(1).IsHidden = true;
  44.  
  45.                 // Зафиксируем транзакцию с созданием спецификации
  46.                 // Это важно, так как только после этого можно будет активировать вид
  47.  
  48.                 tran.Commit();
  49.  
  50.                 // Активирем спецификацию
  51.                 // Это действие нужно для корректной работы
  52.                 // метод группировки столбцов
  53.  
  54.                 uidoc.ActiveView = sampleSchedule;
  55.  
  56.                 // Сгруппируем последние три столбца
  57.                 // Скрытые столбцы не учитываются при использвании индексов столбцов
  58.                
  59.  
  60.                 tran.Start("Группировка заголовков");
  61.  
  62.                 int iFieldCount = sampleDefinition
  63.                   .GetFieldCount();
  64.  
  65.                 sampleSchedule.GroupHeaders(0,
  66.                   iFieldCount - 5, 0,
  67.                   iFieldCount - 3, "Сгруппированный заголовок");
  68.  
  69.                 tran.Commit();
  70.  
  71.                 return Result.Succeeded;
  72.             }
  73.             catch (Exception ex)
  74.             {
  75.                 MessageBox.Show(ex.ToString(),
  76.                   "Пример группировки столбцов");
  77.  
  78.                 return Result.Failed;
  79.             }           
  80.         }

Два важных момента, которые я для себя уяснил:

  1. Нужно активировать вид со спецификаций перед группировкой заголовков.
  2. Скрытые столбцы не индексируются, нужно об этом помнить и быть внимательней при задании индексов столбцов для группировки.

Для логического завершения не хватает только ссылки на архив с исходным кодом и проектом для Visual Studio. Вот и она.

Большое спасибо Дэвиду Робисону (David Robison) за предоставленное решение. Надеюсь пример окажется кому-то полезным.

Источник: http://thebuildingcoder.typepad.com/blog/2013/04/grouping-schedule-headers-and-how-to-do-something.html

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

Опубликовано 04.12.2013