Как удалить элемент управляемой формы, созданный не программно, и что делать, если метод Удалить() не работает

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке расширений или модификации типовых конфигураций программисты часто сталкиваются с необходимостью избавиться от лишнего элемента на форме. Казалось бы, платформа предоставляет стандартный метод Удалить() для коллекции Элементы, но при попытке применить его к полю, созданному в конфигураторе, возникает ошибка. В этой статье мы подробно разберем, почему так происходит, и рассмотрим проверенные способы «нейтрализации» мешающих элементов.

Выясним причину: почему нельзя просто удалить элемент?

Для начала проанализируем ситуацию с точки зрения архитектуры платформы 1С:Предприятие. Все элементы управляемой формы можно разделить на две группы: созданные в визуальном редакторе (статические) и добавленные программно с помощью метода Элементы.Добавить(). Согласно официальной документации и справке к методу Удалить(), система позволяет удалять только те объекты, которые были ранее добавлены программно.

Важный нюанс: Элементы, заимствованные в расширение, считаются частью структуры метаданных формы. Платформа должна гарантировать, что типовой код, который может обращаться к этому элементу по имени (например, для изменения цвета или доступности), не вызовет критическую ошибку «Поле объекта не обнаружено». Именно поэтому прямое удаление заблокировано на уровне ядра системы.

Решение 1: Программное управление видимостью

Самый простой и логичный путь — скрыть элемент. Рассмотрим, как это сделать правильно в процедуре ПриСозданииНаСервере. Установка свойства Видимость в значение Ложь полностью исключает элемент из визуального пространства формы, и он не занимает место в интерфейсе.

Проанализируем пример кода:


&НаСервере
Процедура ПриСозданииНаСервереПосле(Отказ, СтандартнаяОбработка)
    // Скрываем элемент по его имени
    ЭлементДляСкрытия = Элементы.Найти("ИмяВашегоПоля");
    Если ЭлементДляСкрытия <> Неопределено Тогда
        ЭлементДляСкрытия.Видимость = Ложь;
    КонецЕсли;
КонецПроцедуры

Однако здесь есть подводный камень: пользовательская видимость. Если пользователь ранее изменил настройки формы («Изменить форму»), его индивидуальные настройки могут перекрыть программную установку видимости. Чтобы гарантированно скрыть элемент для всех, рекомендуется использовать настройку прав или программно очищать настройки формы.

Решение 2: Метод «Невидимой группы» (Перемещение)

Иногда простого скрытия недостаточно, особенно если типовой код постоянно «включает» видимость элемента обратно в процессе работы. В таком случае мы можем применить более радикальный метод: переместить элемент в группу, которая никогда не будет показана пользователю.

Разберем этот процесс по шагам:

  1. Создадим программно новую группу на форме.
  2. Установим для этой группы свойство Видимость = Ложь.
  3. Переместим мешающий элемент в эту группу с помощью метода Переместить().

Рассмотрим пример реализации:


&НаСервере
Процедура ПереместитьНенужныйЭлемент()
    // Создаем скрытую группу-контейнер
    ИмяГруппы = "ГруппаТехническаяСкрытая";
    НоваяГруппа = Элементы.Добавить(ИмяГруппы, Тип("ГруппаФормы"), ЭтаФорма);
    НоваяГруппа.Вид = ГруппаФормыВид.ОбычнаяГруппа;
    НоваяГруппа.Видимость = Ложь;
    
    // Перемещаем элемент
    ЭлементКПеремещению = Элементы.ИмяСтандартногоПоля;
    Элементы.Переместить(ЭлементКПеремещению, НоваяГруппа);
КонецПроцедуры

Этот способ хорош тем, что даже если типовой код установит Видимость = Истина для самого поля, оно все равно останется невидимым, так как находится внутри скрытого родительского контейнера.

Решение 3: Подмена пути к данным (DataPath)

Бывают ситуации, когда элемент должен остаться на форме (например, из-за жестких привязок в типовом коде), но его содержимое не должно влиять на объект. В этом случае мы можем программно изменить свойство ПутьКДанным. Мы «отвязываем» поле от реквизита объекта и привязываем его к временной переменной или реквизиту формы.

Выясним, как это реализовать:


&НаСервере
Процедура ПодменитьДанныеПоля()
    // Создаем новый реквизит формы для "заглушки"
    МассивРеквизитов = Новый Массив;
    МассивРеквизитов.Добавить(Новый РеквизитФормы("БуфернаяПеременная", Новый ОписаниеТипов("Строка")));
    ИзменитьРеквизиты(МассивРеквизитов);
    
    // Перенаправляем элемент на новый путь
    Элементы.СтандартноеПолеВвода.ПутьКДанным = "БуфернаяПеременная";
КонецПроцедуры

Таким образом, любые изменения, вносимые в поле пользователем или программно, будут попадать в БуфернаяПеременная, не затрагивая реальные данные в базе.

Решение 4: Использование функциональных опций

Рассмотрим наиболее «красивый» с точки зрения архитектуры способ. Если элемент привязан к функциональной опции, его видимость и доступность управляются на уровне метаданных. В расширении мы можем создать свою функциональную опцию, которая всегда возвращает Ложь, и привязать к ней заимствованный элемент. Это исключит элемент из интерфейса еще на этапе компоновки формы сервером.

Решение 5: Условное оформление формы

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

Пример программного добавления условия:


ЭлементОформления = УсловноеОформление.Элементы.Добавить();
ЭлементОформления.Оформление.УстановитьЗначениеПараметра("Видимость", Ложь);

ПолеОформления = ЭлементОформления.Поля.Элементы.Добавить();
ПолеОформления.Поле = Новый ПолеКомпоновкиДанных("ИмяСтандартногоПоля");

// Условие, которое всегда Истина
ЭлементУсловия = ЭлементОформления.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементУсловия.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Объект.Ссылка");
ЭлементУсловия.ВидСравнения = ВидСравненияКомпоновкиДанных.Заполнено;

Подведем итоги

Мы выяснили, что удалить статический элемент формы невозможно из-за ограничений платформы 8.2/8.3, направленных на сохранение стабильности кода. Однако, используя комбинацию методов скрытия, перемещения в невидимые контейнеры и подмены путей к данным, мы можем добиться того же результата. Выбор конкретного метода зависит от того, насколько агрессивно типовой код пытается управлять этим элементом. В большинстве случаев достаточно простого управления свойством Видимость или перемещения элемента в скрытую группу.

← На главную