Разработка и Конфигурация · 12 мин
Как программно удалить реквизит формы в 1С
Как удалить реквизит формы программно в 1С: метод ИзменитьРеквизиты, удаление связанных элементов, типичные ошибки и проверка результата с примерами кода.
Реквизиты формы часто создаются динамически — например, при построении отчёта произвольной структуры, при отображении данных из внешнего источника или при генерации таблицы значений с переменным набором колонок. Когда такие реквизиты больше не нужны или структуру формы требуется перестроить, возникает задача удалить их программно, без вмешательства в конфигуратор.
В управляемых формах для этого используется метод ИзменитьРеквизиты(), который принимает два массива: добавляемые и удаляемые реквизиты. В обычных формах (обычное приложение) действуют другие механизмы, и их нужно учитывать отдельно. Ниже разобраны оба сценария, ограничения платформы, работа со связанными элементами формы и типичные ошибки, из-за которых удаление завершается исключением.
Когда реквизит формы можно удалить, а когда нельзя
Платформа позволяет программно удалять только те реквизиты, которые были созданы программно — методом ИзменитьРеквизиты() в том же сеансе работы формы. Реквизиты, добавленные в конфигураторе (в дереве реквизитов формы), удалить программно невозможно: попытка передать их имя в массив удаляемых вызовет ошибку «Реквизит не может быть удалён» или подобное исключение.
Это ограничение логично: статические реквизиты — часть метаданных формы, и их состав фиксируется при разработке. Если нужно скрыть статический реквизит от пользователя, используют свойство Видимость связанного элемента формы, а не удаление реквизита. Удаление — инструмент исключительно для динамически созданных данных.
Второе важное ограничение: метод ИзменитьРеквизиты() доступен только на сервере в контексте формы. Вызов должен выполняться в серверной процедуре с директивой &НаСервере, иначе метод будет недоступен, и код завершится ошибкой компиляции или выполнения.
Базовый синтаксис метода ИзменитьРеквизиты
Метод имеет два параметра: ДобавляемыеРеквизиты и УдаляемыеРеквизиты. Оба — массивы. Для удаления первый массив оставляют пустым, а во второй помещают строки с путями к реквизитам. Путь для реквизита верхнего уровня — просто его имя, для колонки таблицы — «ИмяТаблицы.ИмяКолонки».
&НаСервере
Процедура УдалитьРеквизитНаСервере()
Удаляемые = Новый Массив;
Удаляемые.Добавить("ВременноеПоле");
ИзменитьРеквизиты(Новый Массив, Удаляемые);
КонецПроцедуры
Удаление колонки динамической таблицы значений выглядит аналогично, но путь составной. При этом сама таблица остаётся на форме — удаляется только указанная колонка. Если нужно удалить таблицу целиком, в массив передают её имя без уточнения колонок.
&НаСервере
Процедура УдалитьКолонкуТаблицы()
Удаляемые = Новый Массив;
Удаляемые.Добавить("ДинамическаяТаблица.КолонкаСумма");
ИзменитьРеквизиты(Новый Массив, Удаляемые);
КонецПроцедуры
Один вызов метода может одновременно добавлять и удалять реквизиты — это удобно при полной перестройке структуры формы: старые колонки удаляются, новые добавляются за одну серверную транзакцию изменения формы.
- 1Убедитесь, что реквизит создан программно, а не в конфигураторе
- 2Удалите связанные элементы формы через Элементы.Удалить(Элементы.ИмяЭлемента)
- 3Сформируйте массив с полным путём к реквизиту
- 4Вызовите ИзменитьРеквизиты(Новый Массив, Удаляемые) на сервере
- 5Проверьте, что форма открывается без ошибок и данные не потеряны
Удаление связанных элементов формы
Реквизит сам по себе — только данные. На форме его обычно отображает элемент: поле ввода, колонка таблицы, надпись. Платформа не удаляет такие элементы автоматически, и если сначала удалить реквизит, элемент останется «битым» — со ссылкой на несуществующий путь к данным. При обращении к форме это приведёт к ошибке отображения.
Правильный порядок — сначала удалить элементы, потом реквизиты. Элемент удаляется методом Элементы.Удалить(), в который передаётся сам объект элемента, полученный по имени через коллекцию Элементы.
&НаСервере
Процедура УдалитьРеквизитИЭлемент()
// Сначала удаляем элемент формы
Элемент = Элементы.Найти("ПолеВременноеПоле");
Если Элемент <> Неопределено Тогда
Элементы.Удалить(Элемент);
КонецЕсли;
// Затем удаляем сам реквизит
Удаляемые = Новый Массив;
Удаляемые.Добавить("ВременноеПоле");
ИзменитьРеквизиты(Новый Массив, Удаляемые);
КонецПроцедуры
Для таблиц с динамическими колонками перебирайте коллекцию Элементы.ИмяТаблицы.ПодчиненныеЭлементы и удаляйте те колонки-элементы, чьи пути к данным совпадают с удаляемыми реквизитами. Метод Элементы.Найти() предпочтительнее прямого обращения по имени, потому что не вызывает исключение, если элемента уже нет.
Полная перестройка динамической структуры формы
Частый сценарий — форма с таблицей, состав колонок которой зависит от выбранных настроек: пользователь меняет параметр, и таблицу нужно пересоздать с другим набором колонок. Здесь удаление идёт «пакетно»: сначала собираются все существующие динамические элементы и реквизиты, затем они удаляются, после чего структура строится заново.
Чтобы отличить динамические колонки от статических, удобно при создании давать им префикс, например «Дин_». Тогда при очистке достаточно перебрать реквизиты таблицы и удалить те, чьи имена начинаются с этого префикса. Получить текущий состав реквизитов формы можно методом ПолучитьРеквизиты() — он возвращает массив объектов РеквизитФормы с именами, путями и типами.
&НаСервере
Процедура ОчиститьДинамическиеКолонки()
Удаляемые = Новый Массив;
Для Каждого Реквизит Из ПолучитьРеквизиты() Цикл
Если СтрНачинаетсяС(Реквизит.Имя, "Дин_") Тогда
Удаляемые.Добавить(Реквизит.Имя);
КонецЕсли;
КонецЦикла;
// Удаляем элементы с тем же префиксом
Для Каждого Элемент Из Элементы Цикл
Если СтрНачинаетсяС(Элемент.Имя, "Дин_") Тогда
Элементы.Удалить(Элемент);
КонецЕсли;
КонецЦикла;
Если Удаляемые.Количество() > 0 Тогда
ИзменитьРеквизиты(Новый Массив, Удаляемые);
КонецЕсли;
КонецПроцедуры
Обратите внимание на порядок перебора: коллекцию Элементы нельзя модифицировать во время обхода по ней в некоторых сценариях — надёжнее сначала собрать удаляемые элементы в отдельный массив, а затем удалять их в цикле по этому массиву. То же относится и к реквизитам: массив для ИзменитьРеквизиты() формируется заранее.
// Удаление реквизита и его элемента
Удаляемые = Новый Массив;
Удаляемые.Добавить("ВременноеПоле");
Элементы.Удалить(Элементы.ПолеВременноеПоле);
ИзменитьРеквизиты(Новый Массив, Удаляемые);Особенности для обычных форм и внешних обработок
В обычном приложении (толстый клиент, обычные формы) механизм другой: там нет метода ИзменитьРеквизиты(), потому что реквизиты формы в обычном приложении статичны по своей природе. Динамические данные в обычных формах хранят в переменных модуля формы или в табличных полях, привязанных к объектам ТаблицаЗначений, созданным в памяти. «Удаление» сводится к очистке колонок таблицы значений методом Колонки.Удалить() и обновлению элемента формы.
Во внешних обработках и отчётах на управляемых формах методика полностью совпадает с описанной выше: ИзменитьРеквизиты() работает так же, как в формах объектов конфигурации. Ограничение то же — удалять можно только то, что создали программно в текущем экземпляре формы.
Отдельный случай — динамические списки и реквизиты типа ДинамическийСписок. Их состав полей определяется запросом, а не структурой реквизитов, поэтому «удалить колонку» здесь означает изменить текст запроса или настройки компоновки, а не вызывать ИзменитьРеквизиты().
Способы убрать данные с формы
Полное удаление динамического реквизита. Подходит при перестройке структуры формы. Не работает для статических реквизитов.
Реквизит остаётся, но не отображается. Единственный вариант для статических реквизитов из конфигуратора.
Данные обнуляются, структура сохраняется. Подходит, когда реквизит понадобится снова в том же сеансе.
Проверка результата и типичные ошибки
После вызова ИзменитьРеквизиты() убедитесь, что реквизит действительно исчез: переберите ПолучитьРеквизиты() и проверьте отсутствие имени в списке. Дополнительно проверьте, что форма открывается и перерисовывается без сообщений об ошибках, а связанные элементы не остались «висячими».
Самая частая ошибка — попытка удалить реквизит, созданный в конфигураторе. Платформа выдаёт исключение, и выполнение процедуры прерывается. Вторая по частоте — неверный путь: для колонки таблицы указано просто имя колонки без имени таблицы, либо наоборот. Третья — вызов метода в клиентской процедуре, где он недоступен.
Ещё одна ловушка — повторное открытие формы. Динамически созданные реквизиты живут только в текущем экземпляре формы: после закрытия они исчезают сами. Поэтому логика создания и удаления должна корректно отрабатывать при каждом открытии, не предполагая, что реквизит «уже есть» или «уже удалён» из прошлого сеанса.
Как проверить результат
ПолучитьРеквизиты() не содержит удалённое имя
Реквизит остался в списке — путь был указан неверно
Нет элементов с ПутьКДанным на удалённый реквизит
При открытии формы ошибка отображения элемента
Форма открывается без сообщений об ошибках
Исключение при создании формы на сервере
Когда удаление не нужно: альтернативные подходы
Не всякая задача требует физического удаления реквизита. Если состав данных фиксирован, а меняется только их видимость для пользователя, достаточно управлять свойством Видимость элементов — это дешевле по ресурсам и не требует серверного вызова при каждом переключении.
Если динамическая структура пересоздаётся часто, иногда проще не удалять реквизиты по одному, а пересоздавать форму целиком или использовать одну универсальную таблицу значений с фиксированным набором служебных колонок, заполняя её по-разному. Выбор зависит от того, насколько сильно меняется структура и как часто это происходит в течение сеанса работы пользователя.
Для отчётов на СКД динамический состав полей вообще не требует ручной работы с реквизитами: настройки компоновщика сами управляют выводимыми полями, и вмешательство в структуру формы не нужно.
Что важно запомнить
Динамические реквизиты удаляются методом ИзменитьРеквизиты с массивом путей во втором параметре, только на сервере и только если реквизит создан программно. Сначала удаляйте связанные элементы формы, затем реквизиты. Статические реквизиты конфигуратора удалить нельзя — их скрывают через видимость элементов.
Частые вопросы
Можно ли удалить реквизит, добавленный в конфигураторе?
Нет. Метод ИзменитьРеквизиты работает только с реквизитами, созданными программно в текущем экземпляре формы. Статический реквизит можно лишь скрыть от пользователя, установив Видимость = Ложь у связанного элемента формы.
Что произойдёт с данными в реквизите после удаления?
Данные удаляются вместе с реквизитом безвозвратно. Если значения понадобятся позже, сохраните их заранее — в переменную модуля, параметр формы, хранилище настроек или во временное хранилище через ПоместитьВоВременноеХранилище.
Почему возникает ошибка «Реквизит не найден» при удалении?
Чаще всего указан неверный путь. Для реквизита верхнего уровня передаётся его имя, для колонки таблицы — «ИмяТаблицы.ИмяКолонки». Также проверьте, что реквизит не был уже удалён ранее в этом же сеансе формы.
Нужно ли удалять реквизиты перед закрытием формы?
Нет. Динамические реквизиты существуют только в памяти текущего экземпляра формы и уничтожаются автоматически при её закрытии. Явное удаление требуется только тогда, когда структура формы перестраивается в процессе её работы.
Как удалить все динамические реквизиты сразу?
Переберите результат ПолучитьРеквизиты(), отберите реквизиты по заранее известному признаку (например, префиксу имени), соберите их пути в массив и передайте одним вызовом ИзменитьРеквизиты. Предварительно удалите связанные элементы формы тем же способом.
Работает ли ИзменитьРеквизиты в мобильном клиенте и веб-клиенте?
Да, метод доступен во всех клиентах управляемого приложения, поскольку выполняется на сервере. Важно лишь, чтобы вызов происходил из серверной процедуры формы, а тонкий, веб- или мобильный клиент здесь роли не играет.