Параметры в спецификации

Автор Тема: Параметры в спецификации  (Прочитано 20567 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн AlexanderАвтор темы

  • ADN OPEN
  • Сообщений: 27
  • Карма: 0
Параметры в спецификации
« : 18-11-2013, 09:36:25 »
Доброго времени суток!

Возможно ли при создании спецификации самому задать параметры в столбцах?
Например, чтобы уровень был в отдельном столбце. 

Спасибо!

Оффлайн Виктор Чекалин

  • Administrator
  • *****
  • Сообщений: 694
  • Карма: 111
  • Skype: chekalin-v
Re: Параметры в спецификации
« Ответ #1 : 18-11-2013, 09:55:17 »
Александр, добрый день.

С помощью API вы сможете сделать не более чем пользователь может делать в интерфейсе.

Для ответа на ваш вопрос, нужно уточнить пару моментов:
1) Вы создаете спецификацию с помощью API с нуля или редактируете существующую?
2) Я правильно понимаю, что вы хотите добавить новое поле спецификации из произвольного параметра, при этом параметр вы хотите создать так же программно?


Оффлайн AlexanderАвтор темы

  • ADN OPEN
  • Сообщений: 27
  • Карма: 0
Re: Параметры в спецификации
« Ответ #2 : 18-11-2013, 10:39:54 »
Виктор,
я создаю спецификацию с нуля.
Да, параметр я хочу создать программно.

Насколько я понимаю, семейство вместо параметра вставить не получится. Например, какую-нибудь дверь засунуть не в саму таблицу, а в её шапку.
« Последнее редактирование: 18-11-2013, 11:16:32 от Alexander »

Оффлайн Виктор Чекалин

  • Administrator
  • *****
  • Сообщений: 694
  • Карма: 111
  • Skype: chekalin-v
Re: Параметры в спецификации
« Ответ #3 : 18-11-2013, 13:14:08 »
Александр,

Программно добавить новое поле в спецификацию можно с помощью метода ScheduleDefinition.AddField().

Чтобы добавить параметр, нужно воспользоваться одним из перегруженных методов и передать еще и идентификатор параметра, который вы хотите вывести.

Например, следующий код добавит в спецификацию поле Семейство и типоразмер в спецификацию.
definition.AddField(ScheduleFieldType.Instance, new ElementId(BuiltInParameter.ELEM_FAMILY_AND_TYPE_PARAM));
Если же вы хотите добавить в спецификацию значение собственного параметра, то вам нужно найти идентификатор вашего параметра. Чуть позже найду способ как его найти.

А создавать программно сам параметр вы уже научились?
Кстати не совсем ясно зачем вам создавать параметр при создании спецификцаии. Значение этого параметра ведь будет пустым.

Оффлайн AlexanderАвтор темы

  • ADN OPEN
  • Сообщений: 27
  • Карма: 0
Re: Параметры в спецификации
« Ответ #4 : 18-11-2013, 15:50:22 »
Виктор,

У меня есть несколько уровней, на каждом уровне объекты. Если я строю таблицу и использую AddField(schedulableField.instance), то он выдаёт определённый набор параметров. Я хочу чтобы каждый уровень был в шапке(например 1, 2, 3 и т.д. этаж).
Поэтому думал создать параметр в качестве уровня.

А параметр , насколько понимаю, создаётся с помощью sharedparameter.

Для наглядности таблица их excel(4, 0 это уровни):


Оффлайн Виктор Чекалин

  • Administrator
  • *****
  • Сообщений: 694
  • Карма: 111
  • Skype: chekalin-v
Re: Параметры в спецификации
« Ответ #5 : 18-11-2013, 16:22:24 »
Чтож, с шаблоном стало более понятно.
Если 0.0 и 4.0 - это шапка, соответствующая уровню, то что означают цифры 26,4 и 70,8?

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

Хотелось бы получить более детальное описание желаемой спецификации. Какое будет значение у общих параметров?

Оффлайн AlexanderАвтор темы

  • ADN OPEN
  • Сообщений: 27
  • Карма: 0
Re: Параметры в спецификации
« Ответ #6 : 18-11-2013, 16:42:26 »
Эти цифры - это площадь стен. Каждая строка в таблице это какая-то стена.

Оффлайн Виктор Чекалин

  • Administrator
  • *****
  • Сообщений: 694
  • Карма: 111
  • Skype: chekalin-v
Re: Параметры в спецификации
« Ответ #7 : 18-11-2013, 17:13:24 »
То есть вам нужно создать спецификацию площади каждой стены на каждом из уровней.

Подобную спецификацию создать программно можно.
Алгоритм следующий:
  • Для каждого уровня в проекте программно создаете новый общий параметр и привязываете его к категории Стена
  • Выбираете все стены в проекте
  • Для каждой стены производите расчет площади поверхности на каждом уровне
  • Записываете значение площади поверхности стены на определенном уровне в соответсвующий параметр
  • Создаете новую спецификацию
  • Добавляете туда поля с созданными общими параметрами

Самое трудное в этом алгоритме - это рассчитать площадь стен на каждом из уровней.
Второй момент - определение идентификатора параметра, который нужен при создании поля спецификации.
Его можно получить так. Выбираем первую попавшуюся стену в проекте. Находим параметр, содержащий значение площади поверхности стены на определенном уровне. Берем свойство Id этого параметра.
Код - C# [Выбрать]
  1.             FilteredElementCollector filteredElementCollector =
  2.                 new FilteredElementCollector(doc);
  3.  
  4.             var firstWall = filteredElementCollector.OfClass(typeof (Wall)).FirstElement() as Wall;
  5.  
  6.             if (firstWall == null)
  7.             {
  8.                 message = "В проекте нет стен";
  9.                 return Result.Failed;              
  10.             }
  11.  
  12.             var level0Param = firstWall.get_Parameter("Уровень 0.0");
  13.  
  14.             var level0ParamId = level0Param.Id;

Но для начала я бы рекомендовал создать сначала параметры и рассчитать площдь стен. Имея эти данные спецификацию можно попробовать и вручную создать.
« Последнее редактирование: 27-11-2013, 21:42:54 от Виктор Чекалин »

Оффлайн AlexanderАвтор темы

  • ADN OPEN
  • Сообщений: 27
  • Карма: 0
Re: Параметры в спецификации
« Ответ #8 : 18-11-2013, 17:25:14 »
Спасибо за ответ.

Мне нужно в разных столбцах выполнять подсчёт площадей стен расположенных на разных этажах, но имеющих один типоразмер. Первый столбец для 1 этажа, 2 для 2 и т.д. , а последний столбец - итого по всем этажам.
В Ревите можно сформировать подсчёт площадей по строкам, но не по столбцам.

Оффлайн Виктор Чекалин

  • Administrator
  • *****
  • Сообщений: 694
  • Карма: 111
  • Skype: chekalin-v
Re: Параметры в спецификации
« Ответ #9 : 18-11-2013, 17:37:38 »
То есть в вашем случае стена будет находиться только на одном уровне? Если так, то площадь посчитать проще. В любом случае если вы хотите по столбцам, то нужно создавать доп. параметры и сделать по приведенному алгоритму.

Оффлайн AlexanderАвтор темы

  • ADN OPEN
  • Сообщений: 27
  • Карма: 0
Re: Параметры в спецификации
« Ответ #10 : 19-11-2013, 09:13:07 »
Нет, несколько стен на разных уровнях.
Спасибо за предоставленное решение.

Оффлайн Виктор Чекалин

  • Administrator
  • *****
  • Сообщений: 694
  • Карма: 111
  • Skype: chekalin-v
Re: Параметры в спецификации
« Ответ #11 : 19-11-2013, 09:42:37 »
В дополнение хочу добавить. Так как для каждой стены будет множество параметров с площадью стен на каждом уровне, которые по сути нужны только для спецификации и пользователю не обязательно их видеть в свойствах стены, то программно можно создать скрытые параметры. Пользователь их не будет видеть окне свойств объекта, но для спецификации эти параметры можно будет использовать.

Ну и если уж совсем идти до конца и решить задачу полностью, то нужно еще отслеживать изменение размера стены и при изменении перезаписывать значение параметров, содержащих площадь поверхности стены.

Оффлайн AlexanderАвтор темы

  • ADN OPEN
  • Сообщений: 27
  • Карма: 0
Re: Параметры в спецификации
« Ответ #12 : 09-12-2013, 15:13:37 »
Добрый день.

Виктор, в продолжении темы хотел поинтересоваться расчётом площади.
Пытаюсь сделать подобным образом:
Код - C# [Выбрать]
  1. FilteredElementCollector filteredElementCollectorWall = new FilteredElementCollector(document);
  2. var wall = filteredElementCollectorWall.OfClass(typeof(Wall)).FirstElement() as Wall;
  3. Parameter widthParam = wall.get_Parameter("Ширина1");
  4. double widthValue = widthParam.AsDouble();
  5. Parameter heightParam = wall.get_Parameter("Длина1");
  6. double heightValue = heightParam.AsDouble();
  7. double areaValue = widthValue * heightValue;
  8. wall.get_Parameter("Площадь_стены").Set(areaValue);
                   

Площадь не считает, может где-то ошибка?

Оффлайн Виктор Чекалин

  • Administrator
  • *****
  • Сообщений: 694
  • Карма: 111
  • Skype: chekalin-v
Re: Параметры в спецификации
« Ответ #13 : 09-12-2013, 15:36:47 »
Александр,
для начала нужно посмотреть значения переменных widthValue и heightValue после того как вы получили их значения из параметров. Поставьте  точку остановки на 7 линии (7 по коду в вашем посте) и в дебагере посмотрите чему равны значения.

Параметры Ширина1 и Длина1 точно имеют тип Double? Проверьте чему равно свойство widthParam.StorageType и heightParam.StorageType

И естественно нужно убедиться что стена, возвращаемая с помощью метода
Код - C# [Выбрать]
  1. var wall = filteredElementCollectorWall.OfClass(typeof(Wall)).FirstElement() as Wall;
содержит не нулевые значение параметров Ширина1 и Длина1

Оффлайн AlexanderАвтор темы

  • ADN OPEN
  • Сообщений: 27
  • Карма: 0
Re: Параметры в спецификации
« Ответ #14 : 09-12-2013, 16:12:55 »
Виктор,
спасибо за быстрый ответ.

Проверил все действия, также пробовал менять double на int (и в коде и параметры проекта).
Всё равно не считает.

Оффлайн Виктор Чекалин

  • Administrator
  • *****
  • Сообщений: 694
  • Карма: 111
  • Skype: chekalin-v
Re: Параметры в спецификации
« Ответ #15 : 09-12-2013, 16:21:41 »
Давайте тогда определимся что значит "не считает". Посчитать площадь прямоугльника - это простая арифметическая операция умножения и ошибиться тут сложно. Если переменные не равны 0, то значение площади в любом случае посчитается.

Все же скажите мне чему равны переменные widthValue, heightValue и areaValue?

Или площадь же считается, но не происходит сохранение площади в параметр Площадь_стены?

Оффлайн AlexanderАвтор темы

  • ADN OPEN
  • Сообщений: 27
  • Карма: 0
Re: Параметры в спецификации
« Ответ #16 : 09-12-2013, 16:32:11 »
widthValue и  heightValue равны 5 и 6. В дебагере также отображается. areaValue - просто пустое поле(в дебагере 0)
Ширина1, Длина1 и Площадь_стены это общие параметры созданные вручную в revit

Оффлайн AlexanderАвтор темы

  • ADN OPEN
  • Сообщений: 27
  • Карма: 0
Re: Параметры в спецификации
« Ответ #17 : 09-12-2013, 16:40:40 »
Виктор,
areaValue считает в дебагере, но не записывает в Revit

Оффлайн Виктор Чекалин

  • Administrator
  • *****
  • Сообщений: 694
  • Карма: 111
  • Skype: chekalin-v
Re: Параметры в спецификации
« Ответ #18 : 09-12-2013, 16:44:48 »
Уже интереснее. Т.е. выходит что операции умножения не просходит.
Я как то сталкивался с таким, что дебагер показывает неверное значение. Скорее всего это глюк дебагера.

У меня есть подозрение что ошибка в записи результата в параметр (8 строка).
После выполнения вашего когда, чему равен параметр Площадь_стены в интерфейсе?

Попробуйте исправить код вот так:
Код - C# [Выбрать]
  1.             bool res = wall.get_Parameter("Площадь_стены").Set(areaValue);
  2.  
  3.             TaskDialog.Show("Тест", string.Format("Ширина: {0}\r\nДлина: {1}\r\nПлощадь: {2}\r\nРезультат: {3}",
  4.                 widthValue,
  5.                 heightValue,
  6.                 areaValue,
  7.                 res));
  8.  

Выполните и скажите что поулчилось.

Оффлайн AlexanderАвтор темы

  • ADN OPEN
  • Сообщений: 27
  • Карма: 0
Re: Параметры в спецификации
« Ответ #19 : 09-12-2013, 16:59:36 »
Дебагер считает, ваш код также возвращает правильное значение.
Не записывает значение в параметр Площадь_стены

Оффлайн Виктор Чекалин

  • Administrator
  • *****
  • Сообщений: 694
  • Карма: 111
  • Skype: chekalin-v
Re: Параметры в спецификации
« Ответ #20 : 09-12-2013, 17:18:17 »
Как я и думал. Подвох именно в записи параметра.
Проверьте тип параметра Площадь_стены. В интерфейсе вы в этот параметр можете записать значение?

Ради эксперимента попробуйте заменить .Set(areaValue); на .Set(areaValue.ToString()); и на .SetValueString(areaValue.ToString());

Транзакция как открывается: автоматически или вручную?


Оффлайн AlexanderАвтор темы

  • ADN OPEN
  • Сообщений: 27
  • Карма: 0
Re: Параметры в спецификации
« Ответ #21 : 09-12-2013, 17:23:13 »
В интерфейсе значения записываются, формулы считаются.
Приведение к строке также не помогло.

Транзакция вручную.

Оффлайн Виктор Чекалин

  • Administrator
  • *****
  • Сообщений: 694
  • Карма: 111
  • Skype: chekalin-v
Re: Параметры в спецификации
« Ответ #22 : 09-12-2013, 17:30:05 »
В таком случае хочется видеть весь код внешней команды, где вы записываете площадь в параметр.

Оффлайн AlexanderАвтор темы

  • ADN OPEN
  • Сообщений: 27
  • Карма: 0
Re: Параметры в спецификации
« Ответ #23 : 10-12-2013, 10:32:50 »
Помимо площади там создаётся таблица, но создание полей для неё я закомментил.
 

Оффлайн Виктор Чекалин

  • Administrator
  • *****
  • Сообщений: 694
  • Карма: 111
  • Skype: chekalin-v
Re: Параметры в спецификации
« Ответ #24 : 10-12-2013, 11:13:06 »
Попробовал выполнить. Вот такой код у меня сработал
Код - C# [Выбрать]
  1.             double heightValue = heightParam.AsDouble();
  2.             double areaValue = widthValue * heightValue;
  3.             var res = wall.get_Parameter("Площадь_стены2").Set(areaValue);

Результат равен true.
Тип параметров Длина2 и Ширина2 - Длина.
Тип параметра Площадь_стены2 - Площадь.

Заметил правда вот что. Если Длина2 = 6 и Ширина2 = 5, то площадь будет равна 0.

Все дело в том, что по умолчанию длина и ширина устанавливается в миллиметрах, а площадь - в квадратных метрах. Т.е. площадь просто очень маленькая.

Попробуйте код, что я привел выше. Чему равна переменная res? Чему равно значение параметра Площадь_стуны в интерфейсе после этого?

На всякий случай - какую версию Revit используете?

« Последнее редактирование: 10-12-2013, 11:41:36 от Виктор Чекалин »

Оффлайн AlexanderАвтор темы

  • ADN OPEN
  • Сообщений: 27
  • Карма: 0
Re: Параметры в спецификации
« Ответ #25 : 10-12-2013, 13:03:17 »
res выдаёт false,а revit 2014.
А компилятор считает площадь правильно, но переводит значения в дюймы.
« Последнее редактирование: 10-12-2013, 13:22:31 от Alexander »

Оффлайн Виктор Чекалин

  • Administrator
  • *****
  • Сообщений: 694
  • Карма: 111
  • Skype: chekalin-v
Re: Параметры в спецификации
« Ответ #26 : 10-12-2013, 13:25:51 »
Попробуйте на вот этом проекте.
Я также в 2014 Ревите пробовал.

Оффлайн AlexanderАвтор темы

  • ADN OPEN
  • Сообщений: 27
  • Карма: 0
Re: Параметры в спецификации
« Ответ #27 : 10-12-2013, 13:42:13 »
В вашем проекте считает
res - false

Оффлайн Виктор Чекалин

  • Administrator
  • *****
  • Сообщений: 694
  • Карма: 111
  • Skype: chekalin-v
Re: Параметры в спецификации
« Ответ #28 : 10-12-2013, 13:51:04 »
В этом случае становится ситуация становится еще более непонятной.

Попробуйте еще тогда с моей надстройкой.


Оффлайн AlexanderАвтор темы

  • ADN OPEN
  • Сообщений: 27
  • Карма: 0
Re: Параметры в спецификации
« Ответ #29 : 10-12-2013, 14:14:36 »
Ваш так же считает правильно, но res по-прежнему false.

Оффлайн Виктор Чекалин

  • Administrator
  • *****
  • Сообщений: 694
  • Карма: 111
  • Skype: chekalin-v
Re: Параметры в спецификации
« Ответ #30 : 10-12-2013, 14:28:34 »
Прямо мистика какая то.

Последнее что еще могу предложить, выполните простую команду, в которой не производится больше никаких действий, кроме как обновление параметра:
Код - C# [Выбрать]
  1.         public Result Execute(
  2.           ExternalCommandData commandData,
  3.           ref string message,
  4.           ElementSet elements)
  5.         {
  6.             UIApplication uiapp = commandData.Application;
  7.             UIDocument uidoc = uiapp.ActiveUIDocument;
  8.             Application app = uiapp.Application;
  9.             Document doc = uidoc.Document;
  10.  
  11.             FilteredElementCollector filteredElementCollectorWall = new FilteredElementCollector(doc);
  12.             var wall = filteredElementCollectorWall.OfClass(typeof(Wall)).FirstElement() as Wall;
  13.             Parameter widthParam = wall.get_Parameter("Ширина2");
  14.             double widthValue = widthParam.AsDouble();
  15.             Parameter heightParam = wall.get_Parameter("Длина2");
  16.             double heightValue = heightParam.AsDouble();
  17.             double areaValue = widthValue * heightValue;
  18.             using (Transaction t = new Transaction(doc, "Обновление параметра"))
  19.             {
  20.                 t.Start();
  21.                 var res = wall.get_Parameter("Площадь_стены2").Set(areaValue);
  22.                 t.Commit();
  23.  
  24.                 TaskDialog.Show("Запись значения в параметр", res.ToString());
  25.             }
  26.            
  27.  
  28.             return Result.Succeeded;
  29.         }

Также после выполнения команды вышлите мне файл журнала.
Он находится в папке C:\Users\<username>\AppData\Local\Autodesk\Revit\<Ваша версия ревит>\Journals. Мне нужен текстовый файл вида journal.XXXX.txt, где XXXX самый последний порядковый номер.

Есть ли у вас возможность проверить выполнение команды на другой версии Revit или еще лучше на другом компьютере?

Оффлайн AlexanderАвтор темы

  • ADN OPEN
  • Сообщений: 27
  • Карма: 0
Re: Параметры в спецификации
« Ответ #31 : 10-12-2013, 15:08:23 »
Код возвратил true.
Также я вставил TaskDialog в свой проект и он тоже возвратил true. Но в параметр ответ не записывает(в моём проекте).

Оффлайн Виктор Чекалин

  • Administrator
  • *****
  • Сообщений: 694
  • Карма: 111
  • Skype: chekalin-v
Re: Параметры в спецификации
« Ответ #32 : 10-12-2013, 15:21:55 »
Код возвратил true.
Параметр при этом изменился в интерфейсе? Если в вашем не изменился, то изменился ли в моем простеньком проекте?

Оффлайн AlexanderАвтор темы

  • ADN OPEN
  • Сообщений: 27
  • Карма: 0
Re: Параметры в спецификации
« Ответ #33 : 10-12-2013, 15:28:52 »
В моём нет,пустое поле.
В вашем да. 0 или больше, если увеличить ширину и длину.

В моём проекте несколько стен,у каждой Ширина2 = 5, Длина2= 6.

Так же , если я открываю другие проекты(примеры Ревит), и присваиваю такие же параметры для стен, то и там параметр не меняется в интерфейсе.

Оффлайн Виктор Чекалин

  • Administrator
  • *****
  • Сообщений: 694
  • Карма: 111
  • Skype: chekalin-v
Re: Параметры в спецификации
« Ответ #34 : 10-12-2013, 15:38:55 »
В моём проекте несколько стен,у каждой Ширина2 = 5, Длина2= 6.

Так же , если я открываю другие проекты(примеры Ревит), и присваиваю такие же параметры для стен, то и там параметр не меняется в интерфейсе.

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

Чтобы изменить параметр у всех стен вам нужен вот такой код:
Код - C# [Выбрать]
  1.  
  2.             FilteredElementCollector filteredElementCollectorWall = new FilteredElementCollector(doc);
  3.             var walls = filteredElementCollectorWall.OfClass(typeof(Wall));
  4.             using (Transaction t = new Transaction(doc, "Обновление параметра"))
  5.             {
  6.                 t.Start();
  7.  
  8.                 foreach (Wall wall in walls)
  9.                 {
  10.                     Parameter widthParam = wall.get_Parameter("Ширина2");
  11.                     double widthValue = widthParam.AsDouble();
  12.                     Parameter heightParam = wall.get_Parameter("Длина2");
  13.                     double heightValue = heightParam.AsDouble();
  14.                     double areaValue = widthValue * heightValue;
  15.                    
  16.                     var res = wall.get_Parameter("Площадь_стены2").Set(areaValue);
  17.                    
  18.                     Debug.Print("Стена: {0}; Результат: {1}", wall.Id, res);
  19.                 }
  20.  
  21.                 t.Commit();
  22.             }

Оффлайн AlexanderАвтор темы

  • ADN OPEN
  • Сообщений: 27
  • Карма: 0
Re: Параметры в спецификации
« Ответ #35 : 10-12-2013, 15:47:33 »
Да, в таком случае всё работает.
Спасибо!