Группировка заголовков спецификации
Вопрос: Я пытаюсь сгруппировать заголовки спецификации с помощью метода ViewSchedule.GroupHeaders, но все время выскакивает ошибка: "Headers could not be grouped. Parameter name: right" (Заголовки не могут быть сгруппированы. Имя параметра: right)
Ответ: Действительно. Такая проблема существует. Мы уже обсуждали ее в прошлом и предлагали некоторые решения.
Первый случай
Метод ViewSchedule.GroupHeaders падает с ошибкой приведенной выше.
Однако, после того как спецификация уже создана и заново вызывается тот же самый метод с теми же самыми параметрами, то он выполняется без ошибок. Т.е. можно сделать вывод, что причина не в параметрах.
Я сделал небольшое расследование проблемы и нашел парочку способов обойти эту ошибку:
- Активировать вид со спецификацией и уже затем только сгруппировать заголовки
- Обновить данные спецификации, когда спецификация содержит не актуальные данные, потом сгруппировать заголовки.
Мне кажется, что второй способ является довольно правильным и можно сказать что таким образом можно «исправить» ошибку. Нужно всего лишь вручную обновить данные.
Второй случай
С помощью API нельзя получить обновленное значение из спецификации, если спецификация неактивна.
Чтобы воспроизвести проблему можете выполнить следующие действия:
- Закройте спецификацию
- Вызовите метод IsCellOverridden. Метод вернет True.
- Вызовите метод ResetCellOverride
- Вызовите метод IsCellOverridden. Метод вернет True (т.е. нет реакции на ResetCellOverride)
- Откройте спецификацию.
- Вызовите метод IsCellOverridden. Метод вернет True.
- Вызовите метод ResetCellOverride
- Вызовите метод IsCellOverridden. Метод вернет False (как и ожидалось)
В качестве решения нужно заново вызвать метод viewSchedule.GetTableData.
Таким образом, API для работы с телом спецификации работают некорректно, когда спецификация закрыта.
Основная причина такого поведения в том, что данные в спецификации обновляются только при ее открытии.
Для пользователя это не проблема, так как он видит данные только когда спецификация открыта. А обновление данных только при открытии спецификации улучшает производительность, по сравнению с тем, если бы данные спецификации обновлялись в фоновом режиме.
Ответ: Я вас понял. Решил проблему с помощью метода, описанного в первом случае.
Я создал спецификацию, закрыл транзакцию, активировал вид с только что созданной транзакцией и затем сгруппировал заголовки.
Я также заметил интересную особенность. Индекс с номером столбца не учитывает скрытые столбцы.
Вот пример команды, демонстрирующей использование метода ViewSchedule.GroupHeaders.
- public Result Execute(
- ExternalCommandData commandData,
- ref string message,
- ElementSet elements)
- {
- try
- {
- UIDocument uidoc = commandData.Application
- .ActiveUIDocument;
- Document doc = uidoc.Document;
- // Создание спецификации
- Transaction tran = new Transaction(doc);
- tran.Start("Создание спецификации");
- ViewSchedule sampleSchedule
- = ViewSchedule.CreateSchedule(doc, new
- ElementId(BuiltInCategory.OST_Windows));
- foreach (ElementId id in
- ViewSchedule.GetAvailableParameters(doc, new
- ElementId(BuiltInCategory.OST_Windows)))
- {
- try
- {
- sampleSchedule.Definition.AddField(
- new SchedulableField(
- ScheduleFieldType.Instance, id));
- }
- catch (Exception)
- {
- }
- }
- ScheduleDefinition sampleDefinition
- = sampleSchedule.Definition;
- // Скроем два первых столбца
- sampleDefinition.GetField(0).IsHidden = true;
- sampleDefinition.GetField(1).IsHidden = true;
- // Зафиксируем транзакцию с созданием спецификации
- // Это важно, так как только после этого можно будет активировать вид
- tran.Commit();
- // Активирем спецификацию
- // Это действие нужно для корректной работы
- // метод группировки столбцов
- uidoc.ActiveView = sampleSchedule;
- // Сгруппируем последние три столбца
- // Скрытые столбцы не учитываются при использвании индексов столбцов
- tran.Start("Группировка заголовков");
- int iFieldCount = sampleDefinition
- .GetFieldCount();
- sampleSchedule.GroupHeaders(0,
- iFieldCount - 5, 0,
- iFieldCount - 3, "Сгруппированный заголовок");
- tran.Commit();
- return Result.Succeeded;
- }
- catch (Exception ex)
- {
- MessageBox.Show(ex.ToString(),
- "Пример группировки столбцов");
- return Result.Failed;
- }
- }
Два важных момента, которые я для себя уяснил:
- Нужно активировать вид со спецификаций перед группировкой заголовков.
- Скрытые столбцы не индексируются, нужно об этом помнить и быть внимательней при задании индексов столбцов для группировки.
Для логического завершения не хватает только ссылки на архив с исходным кодом и проектом для Visual Studio. Вот и она.
Большое спасибо Дэвиду Робисону (David Robison) за предоставленное решение. Надеюсь пример окажется кому-то полезным.
Обсуждение: http://adn-cis.org/forum/index.php?topic=374
Опубликовано 04.12.2013