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

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

В процессе разработки сложных интерфейсов на платформе 1С:Предприятие 8.3 часто возникает необходимость динамического изменения состава данных формы. Если создание реквизитов программным путем — задача привычная, то их корректное удаление вызывает ряд вопросов, связанных с производительностью системы и целостностью графического интерфейса. В этой статье мы подробно разберем, как правильно избавляться от ненужных программных реквизитов, избегая типичных ошибок начинающих разработчиков.

Основы механизма изменения состава реквизитов

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

Метод ИзменитьРеквизиты принимает два основных параметра:

  1. Массив добавляемых реквизитов: содержит объекты типа РеквизитФормы.
  2. Массив удаляемых реквизитов: содержит строки, представляющие собой пути к реквизитам.

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

Разбор типичной ошибки: удаление в цикле

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


// НЕПРАВИЛЬНО: Вызов ИзменитьРеквизиты внутри цикла
Для каждого Рек Из ЭтаФорма.ПолучитьРеквизиты() Цикл
    Если СтрНайти(Рек.Имя, "Смета") <> 0 Тогда
        МассивУдаляемых = Новый Массив;
        МассивУдаляемых.Добавить(Рек.Имя);
        ЭтаФорма.ИзменитьРеквизиты(, МассивУдаляемых); // Каждый вызов тормозит сервер
    КонецЕсли;
КонецЦикла;

В данном случае, если у нас 10 реквизитов, сервер 10 раз будет перестраивать всю структуру формы. Это приведет к заметным задержкам в интерфейсе (так называемым «фризам»). Выясним, как сделать это правильно.

Правильный подход: Пакетное удаление

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

Разберем по шагам реализацию этого подхода:


// ПОДХОДИТ ДЛЯ ПРОДАКШЕНА: Пакетное удаление
РеквизитыФормы = ЭтаФорма.ПолучитьРеквизиты(); 
МассивУдаляемых = Новый Массив;

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

// Выполняем удаление одним пакетом
Если МассивУдаляемых.Количество() > 0 Тогда
    ЭтаФорма.ИзменитьРеквизиты(, МассивУдаляемых);
КонецЕсли;

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

Работа с элементами формы: критическое дополнение

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

Поэтому порядок действий всегда должен быть следующим:

  1. Найти и удалить все элементы формы, связанные с удаляемыми реквизитами.
  2. Удалить сами реквизиты.

Пример комплексной очистки группы на форме:


// Очистка группы и удаление связанных данных
ИмяГруппы = "ГруппаДинамическихРеквизитов";
ГруппаЭлементов = ЭтаФорма.Элементы[ИмяГруппы];

МассивУдаляемыхДанных = Новый Массив;

// 1. Удаляем визуальные элементы
Для Каждого Элемент Из ГруппаЭлементов.ПодчиненныеЭлементы Цикл
    ПутьКДанным = Элемент.ПутьКДанным;
    МассивУдаляемыхДанных.Добавить(ПутьКДанным);
    ЭтаФорма.Элементы.Удалить(Элемент);
КонецЦикла;

// 2. Удаляем данные
Если МассивУдаляемыхДанных.Количество() > 0 Тогда
    ЭтаФорма.ИзменитьРеквизиты(, МассивУдаляемыхДанных);
КонецЕсли;

Удаление вложенных реквизитов (колонки таблиц)

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

Например, если у нас есть программная таблица ТаблицаРезультатов и мы хотим удалить колонку СуммаИтого, строка в массиве должна выглядеть так: "ТаблицаРезультатов.СуммаИтого".

Важно: Если вы удаляете родительский реквизит (всю таблицу целиком), то все вложенные в неё реквизиты (колонки) будут удалены автоматически. Отдельно перечислять их в массиве нет необходимости.

Оптимизация производительности в версии 8.3.16+

Начиная с версии платформы 8.3.16, механизмы работы с формой были оптимизированы. Однако общие рекомендации остаются прежними. Посмотрим на дополнительные советы по повышению быстродействия:

Итоги и рекомендации

Мы выяснили, что программное управление составом реквизитов — мощный инструмент, требующий аккуратности. Для успешного удаления придерживайтесь следующих правил:

  1. Всегда используйте пакетный режим (один вызов ИзменитьРеквизиты на одну логическую операцию).
  2. Не забывайте синхронно удалять элементы формы, иначе интерфейс станет неработоспособным.
  3. Используйте локальные переменные в циклах обхода коллекций для микро-оптимизации кода.
  4. При удалении вложенных структур указывайте полный путь через точку.

Следуя этим инструкциям, вы обеспечите стабильную и быструю работу ваших динамических форм в 1С.

← На главную