Как автоматически заполнить параметры в Revit
Общие, типовые и параметры экземпляра: чем отличаются при записи. Скрипт Dynamo для массового заполнения, проверка результата и список того, что записать нельзя.
Перед выдачей раздела кто-то замечает, что у 340 элементов пустой параметр «Обозначение». Заполнять руками через свойства - это вечер. Через спецификацию с группировкой - часа полтора и высокий шанс промахнуться строкой.
Скрипт закрывает то же самое за минуту. Но перед тем как его писать, надо разобраться, куда именно вы собираетесь писать. Половина неудач с автозаполнением случается не в скрипте, а в непонимании устройства параметров.
Три вида параметров и почему это важно
В Revit параметр живёт в одном из мест, и от этого зависит, что произойдёт при записи.
Параметр экземпляра. Своё значение у каждого элемента. Комментарий у конкретной двери, номер помещения, отметка низа балки. Пишете в один элемент - меняется один элемент. Самый безопасный для массовых операций.
Параметр типа. Значение общее для всех элементов этого типа. Модель двери, материал сердцевины, огнестойкость. Записали значение через один экземпляр - изменились все двери этого типа в проекте. На объекте, где типов 12, а дверей 400, промах в одну строчку правит треть модели. Это самая дорогая ошибка в теме автозаполнения.
Общий параметр (shared). Хранится не в файле, а в отдельном текстовом файле ФОП с уникальными GUID. Только общие параметры попадают в спецификации, марки и IFC-выгрузку корректно. Ключевое свойство: два параметра с одинаковым именем, но из разных ФОП, для Revit разные. Именно поэтому в проекте иногда живут «Обозначение» и «Обозначение», и заполняется не то.
Проектный параметр (project) занимает промежуточную позицию: живёт в файле, привязан к категориям, в марку не попадёт.
Перед первым скриптом ответьте на два вопроса: параметр экземпляра или типа, и общий или проектный. Ответ смотрится в «Управление» → «Параметры проекта».
Что заполняется автоматически хорошо
Не всё стоит автоматизировать. Годятся случаи, где значение выводится из чего-то, что уже есть в модели:
- обозначение по шаблону из марки типа, уровня и порядкового номера;
- «Помещение» у оборудования, вычисленное по геометрии (в какой комнате стоит точка вставки);
- код по классификатору, подставленный из соответствия «семейство → код»;
- этажность, секция, стадия, подсистема: всё, что определяется положением элемента;
- зачистка мусора: убрать двойные пробелы, привести регистр, обрезать лишние символы.
Плохо автоматизируется то, что требует решения человека. Категория качества отделки, обоснование отступа от норматива, комментарий проверяющего. Скрипт заполнит поле, ответственность останется на вас, а поле будет выглядеть заполненным. Так рождается недостоверная модель.
Скрипт: сбор, вычисление, запись
Структура любого графа автозаполнения одинакова. Три части.
Сбор. Categories → All Elements of Category. Если нужны элементы только с активного вида, берите All Elements of Category in View: на большой модели разница во времени в разы.
Вычисление. Читаем исходные параметры через Element.GetParameterValueByName, склеиваем в Code Block. Пример формулы обозначения:
марка + "-" + этаж + "-" + String.PadLeft(number, 3, "0");
Дальше это уходит в один вход, а список элементов в другой.
Запись. Element.SetParameterByName. Три входа: элемент, имя параметра строкой, значение. Порядок и длина списков должны совпадать. Если элементов 340, а значений 339, лейсинг Shortest тихо обработает 339, и вы этого не заметите.
Полезный кусок на Python внутри Dynamo, когда нужно писать только в пустые поля и не трогать заполненные:
import clr
clr.AddReference("RevitAPI")
clr.AddReference("RevitServices")
from Autodesk.Revit.DB import *
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument
elems = UnwrapElement(IN[0])
pname = IN[1]
values = IN[2]
TransactionManager.Instance.EnsureInTransaction(doc)
tronuli = 0
for e, v in zip(elems, values):
p = e.LookupParameter(pname)
if p is None or p.IsReadOnly:
continue
if p.AsString(): # уже заполнено - пропускаем
continue
p.Set(str(v))
tronuli += 1
TransactionManager.Instance.TransactionTaskDone()
OUT = tronuli
Возврат количества обработанных элементов - привычка, которая экономит нервы. Запустили, увидели «307», сравнили с ожидаемыми 340, пошли искать разницу. Без счётчика скрипт молчит, и вы верите, что всё прошло.
Единицы, типы и прочие мелочи
Строковый параметр принимает строку, числовой число, длина хранится во внутренних футах. Запись 1000 в параметр длины через API даёт 1000 футов, то есть 304 метра. Революции в модели не будет, но геометрия уедет.
Проверяйте на одном элементе. Всегда. Записали, открыли свойства, посмотрели глазами. Только после этого пускайте на все 340.
Параметр Yes/No ждёт 0 или 1. Параметр-материал ждёт ElementId материала, а не его название. Параметр типа «Текст» проглотит что угодно, включая случайно попавший null, который превратится в строку «null» и потом всплывёт в спецификации.
Проверка результата
Скрипт отработал. Дальше три уровня контроля, по возрастанию надёжности.
Первый: спецификация с фильтром «параметр не заполнен». Ставится один раз, живёт в шаблоне, показывает пустые поля моментально. Держите такую в каждом проекте.
Второй: фильтр вида, красящий элементы с незаполненным полем. Работает нагляднее таблицы, особенно на планах, где сразу видно осиротевшую зону.
Третий: обратный прогон. Собрать значения тем же графом и проверить List.UniqueItems и List.Count. Обозначения должны быть уникальны, коды - принадлежать заранее известному множеству. Расхождение говорит о том, что скрипт где-то ошибся или кто-то поправил руками.
Отдельно проверьте пять случайных элементов вручную. Автоматика проверяет автоматику, а глаз ловит то, чего в проверках не заложено.
Где это не работает
Read-only параметры. Площадь, объём, периметр, длина стены, отметки. Их считает Revit по геометрии, запись невозможна. Скрипт либо упадёт, либо пропустит, в зависимости от того, как написан.
Параметры семейства, не выведенные в проект. Если внутри семейства значение зашито формулой или помечено как параметр семейства, из проекта его не поменять. Нужна правка самого семейства и перезагрузка во все проекты, где оно используется.
Связанные модели. Чужой файл открыт на чтение, запись невозможна в принципе. Данные из связи можно только читать, для этого есть отдельный набор нод.
Модель в общей работе. Элемент, занятый другим пользователем, не изменится. Скрипт выдаст ошибку доступа, и он будет прав. Массовые операции делаются, когда все синхронизировались, а лучше на отдельной копии с последующей проверкой.
И ещё одно. Автозаполнение не чинит бардак в данных, оно его масштабирует. Пустой параметр видно сразу, а неверно заполненный выглядит как рабочий и доживает до экспертизы. Первый запуск на боевом файле делайте в режиме «только показать, что запишем»: выведите таблицу «элемент → новое значение» и посмотрите её глазами, прежде чем разрешать запись.
Три ошибки записи, разобранные по шагам
«Warning: Element.SetParameterByName operation failed. The parameter is read-only.»
Самая безобидная. Скрипт честно сказал, что писать сюда нельзя. Проверьте, не пытаетесь ли вы заполнить вычисляемое поле: площадь, объём, длину, отметку. Второй вариант этой же ошибки хитрее: параметр записываемый, но конкретно у этого элемента он приходит из семейства и заблокирован формулой. Тогда правится семейство, а не проект.
«Warning: Element.SetParameterByName operation failed. The parameter storage type is not a string.»
Тип значения не совпал с типом параметра. Пытаетесь записать текст в числовое поле или наоборот. В Dynamo это лечится нодами String.ToNumber и String from Object, в python - явным str() или float(). Отдельный случай: параметр Yes/No ждёт 1 или 0, а не «Да».
Записалось, а в спецификации пусто.
Ошибок нет, значения в свойствах элемента видны, спецификация показывает пустую колонку. Почти всегда причина одна: в проекте два параметра с одинаковым именем. Один проектный, другой общий из ФОП, и спецификация выводит не тот, в который вы записали. Проверяется в «Управление» → «Параметры проекта»: если в списке два «Обозначения», вы нашли виновника. Чинится удалением лишнего и повторным прогоном, но сначала убедитесь, что удаляемый параметр нигде не выводится в марках.
Четвёртая по счёту, но первая по ущербу ситуация: скрипт отработал на 400 элементах вместо 40. Фильтр собрал не ту категорию, лейсинг растянул значение на весь список, вложенные семейства попали в выборку. Отсюда правило про счётчик обработанных элементов и первый прогон в режиме отчёта.
Куда писать: сравнение
| Вид параметра | Когда брать | Чем платишь |
|---|---|---|
| Экземпляра, проектный | значение у каждого элемента своё, в марки не идёт | не попадёт в IFC-выгрузку корректно |
| Экземпляра, общий | нужен в спецификациях, марках, обмене | нужен порядок в ФОП и его хранение |
| Типа | одинаково у всех элементов типа | правка одного меняет все, ошибка дорогая |
| Глобальный | одно значение на проект (стадия, шифр) | не выводится в спецификацию по элементам |
Что проверить перед массовым прогоном
- Копия файла сделана. Не «синхронизирую и откачу», а именно копия.
- Параметр найден в «Параметрах проекта» и вы точно знаете, экземпляра он или типа.
- Скрипт вернул счётчик обработанных элементов, и число совпало с ожидаемым.
- На пяти случайных элементах значение проверено глазами в свойствах, а не в превью Dynamo.
- Спецификация с фильтром «поле не заполнено» построена заранее, до прогона. После прогона сравнивать будет не с чем.
- Коллеги в общей работе синхронизировались, иначе половина элементов окажется занята.
Короткие ответы на частые вопросы
Можно ли заполнить параметр без скриптов вообще? Да, и это недооценённый путь. Ключевая спецификация (Key Schedule) заполняет пачку параметров по одному ключевому полю: выбрали в выпадающем списке «Тип отделки 3», и три параметра проставились сами. Настраивается за полчаса, не ломается при обновлении Revit, работает у всех без Dynamo. Логику вычислений она не потянет, но для справочников подходит лучше скрипта.
Как заполнить параметры у элементов связанной модели? Никак. Чужой файл открыт на чтение. Работать можно только с копией связи, вставленной в свой проект, или запрашивать правку у автора модели.
Отменяется ли массовая запись? Ctrl+Z откатывает весь прогон одним шагом, пока вы не сделали в Revit других действий. После синхронизации откат превращается в отдельную работу с архивом.
Что быстрее на 3000 элементов: Dynamo или python внутри него? Python. Ноды тратят время на обёртки и превью, чистый цикл через Revit API проходит те же элементы в несколько раз быстрее. На тысяче элементов разница незаметна, на десятках тысяч ощутима.
Что делать дальше
Возьмите один параметр, который в вашей команде заполняют руками каждую неделю. Соберите граф на копии файла. Прогоните, проверьте, посчитайте сэкономленное время: у нас на обозначениях получилось 40 минут против 4, и это на средней по размеру модели.
Не собирали графов раньше - начните с пошагового разбора первого скрипта, там подробно про ноды, порты и уровни списков. Если значения приходят из внешней таблицы, посмотрите разбор обмена с Excel. Когда скрипт готов и им хочет пользоваться вся команда, дальше по маршруту Dynamo Player.
Не уверены, куда именно писать в вашей схеме параметров, или в проекте уже два «Обозначения» из разных ФОП? Напишите в Telegram или через форму на странице контактов, разберём структуру. Наведение порядка в параметрах и шаблонах есть в списке услуг.
Нужен похожий BIM/AI процесс?
Напишите в Telegram или на email — разберём задачу и предложим архитектуру решения.
Telegram Оставить заявку