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