Как правильно программно добавлять и удалять реквизиты на управляемой форме 1С

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

В практике разработчика 1С часто возникают задачи, когда состав полей на форме должен меняться динамически в зависимости от действий пользователя или настроек системы. Управляемые формы предоставляют мощный механизм ИзменитьРеквизиты, однако его неправильное использование может привести к серьезным проблемам с производительностью и стабильностью интерфейса. В данной статье мы подробно разберем, как грамотно добавлять и удалять программные реквизиты, как управлять связанными с ними элементами формы и какие архитектурные подходы считаются наиболее правильными.

Основы работы с методом ИзменитьРеквизиты

Для начала проанализируем базовый механизм. Изменение состава реквизитов формы возможно только в серверном контексте. Основной метод для этого — ЭтаФорма.ИзменитьРеквизиты(МассивДобавляемых, МассивУдаляемых). Важно понимать, что этот метод принимает два массива объектов или строк. Рассмотрим ситуацию, когда нам нужно создать новые поля «на лету».

Разберем типичный сценарий добавления строковых реквизитов в цикле:


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

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

Как правильно удалять программные реквизиты

Удаление реквизитов — это процесс, обратный созданию. Однако здесь часто возникает вопрос: как узнать, какие именно реквизиты были созданы ранее, чтобы не удалить лишнего и не вызвать ошибку при обращении к несуществующим объектам?

Рассмотрим несколько способов идентификации реквизитов для удаления:

  1. Хранение списка имен: Мы можем заранее знать префикс наших динамических реквизитов (например, мп_) или сохранять их имена в скрытом реквизите формы типа СписокЗначений.
  2. Поиск по коллекции элементов: Если каждому реквизиту соответствует элемент формы, мы можем найти путь к данным через коллекцию ЭтаФорма.Элементы.
  3. Метод ПолучитьРеквизиты: Мы можем программно перебрать все реквизиты формы и отобрать нужные по маске имени.

Посмотрим на пример удаления реквизитов, основываясь на именах элементов формы:


&НаСервере
Процедура УдалитьДинамическиеРеквизиты()
    
    МассивУдаляемых = Новый Массив;
    
    Для Сч = 0 По 5 Цикл
        ИмяПоля = "ДинамическоеПоле_" + Сч;
        Элемент = ЭтаФорма.Элементы.Найти(ИмяПоля);
        
        Если Элемент <> Неопределено Тогда
            // Сначала добавляем путь к данным в массив на удаление
            МассивУдаляемых.Добавить(Элемент.ПутьКДанным);
            // Удаляем сам визуальный элемент
            ЭтаФорма.Элементы.Удалить(Элемент);
        КонецЕсли;
    КонецЦикла;
    
    // Удаляем реквизиты из памяти формы
    Если МассивУдаляемых.Количество() > 0 Тогда
        ЭтаФорма.ИзменитьРеквизиты(, МассивУдаляемых);
    КонецЕсли;
    
КонецПроцедуры

Обратите внимание, что при удалении реквизитов данные, введенные в них пользователем, будут безвозвратно утеряны. Если вам нужно просто скрыть поля, сохранив данные, используйте свойство Видимость элементов формы вместо удаления самих реквизитов.

Продвинутый подход: пример из типовых решений (ЗУП)

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


// Пример логики универсальной процедуры
МассивДобавляемых = Новый Массив;
МассивУдаляемых = Новый Массив;

// Проверяем, существует ли уже реквизит, прежде чем его добавлять
ТекущиеРеквизиты = ЭтаФорма.ПолучитьРеквизиты();
Для Каждого Реквизит Из ТекущиеРеквизиты Цикл
    Если Реквизит.Имя = "НужноеИмя" Тогда
        // Реквизит уже есть, добавлять не нужно
        Продолжить;
    КонецЕсли;
КонецЦикла;

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

Технические нюансы и рекомендации по производительности

Выясним причины, по которым работа с динамическими реквизитами требует осторожности:

Подводя итог, можно сказать, что правильное удаление и добавление реквизитов — это баланс между функциональностью и производительностью. Мы рекомендуем минимизировать количество вызовов ИзменитьРеквизиты, использовать групповые операции с массивами и всегда проверять существование объектов перед манипуляциями с ними. Такой подход обеспечит стабильную работу вашего интерфейса и удобство для конечного пользователя.

← На главную