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