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

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

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

Проблема стандартного добавления элементов

Обычно для динамического создания элементов разработчики используют метод Добавить() коллекции элементов формы. Давайте посмотрим на типичный пример кода:


НоваяГруппа = Элементы.Добавить("МояНоваяГруппа", Тип("ГруппаФормы"), ЭтаФорма);
НоваяГруппа.Вид = ВидГруппыФормы.ОбычнаяГруппа;
НоваяГруппа.Заголовок = "Важная информация";

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

Решение с помощью метода Вставить()

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

Вставить(<Имя>, <ТипЭлемента>, <Родитель>, <Элемент>)

Наибольший интерес для нас представляет четвертый параметр — <Элемент>. Он указывает на уже существующий элемент формы, перед которым должен быть вставлен наш новый элемент. Если мы хотим поместить группу в самое начало, логично предположить, что в качестве этого параметра нужно передать самый первый элемент формы.

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


// Получаем первый элемент формы
ПервыйЭлемент = Элементы.Получить(0);

// Вставляем новую группу на самый верх перед первым элементом
НоваяГруппа = Элементы.Вставить("МояНоваяГруппа", Тип("ГруппаФормы"), ЭтаФорма, ПервыйЭлемент);
НоваяГруппа.Вид = ВидГруппыФормы.ОбычнаяГруппа;
НоваяГруппа.Заголовок = "Динамическая группа в начале формы";

Благодаря этому несложному приему наша группа мгновенно займет нужную позицию на самом верху интерфейса.

Защита от ошибок: безопасный код для пустых форм

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

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


// Безопасное получение первого элемента
ПервыйЭлемент = ?(Элементы.Количество() > 0, Элементы.Получить(0), Неопределено);

// Вставка элемента. Если ПервыйЭлемент равен Неопределено, группа добавится в начало пустой формы
НоваяГруппа = Элементы.Вставить("МояНоваяГруппа", Тип("ГруппаФормы"), ЭтаФорма, ПервыйЭлемент);
НоваяГруппа.Вид = ВидГруппыФормы.ОбычнаяГруппа;

Использование тернарного оператора позволяет лаконично обойти потенциальную ошибку времени выполнения.

Реальное позиционирование «под командной панелью»

Давайте разберем более сложную, но крайне жизненную ситуацию. Нам нужно разместить группу строго под командной панелью формы. Здесь возможны два сценария:

  1. Автокомандная панель формы. Если на форме используется стандартная автопанель, она не входит в обычную коллекцию элементов формы на верхнем уровне. В этом случае метод Элементы.Получить(0) вернет первый содержательный элемент формы, и наша группа встанет идеально под автопанелью.
  2. Кастомная командная панель. Очень часто разработчики отключают стандартную автопанель формы и создают свою собственную группу с видом КоманднаяПанель. В этом случае коллекция элементов на верхнем уровне начнется именно с этой командной панели. Если мы выполним вставку перед нулевым элементом, наша группа визуально окажется над кнопками командной панели, что полностью нарушит эргономику интерфейса.

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


ЭлементПередКоторымВставлять = Неопределено;

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

// Вставляем группу в правильное место
НоваяГруппа = Элементы.Вставить("МояНоваяГруппа", Тип("ГруппаФормы"), ЭтаФорма, ЭлементПередКоторымВставлять);
НоваяГруппа.Вид = ВидГруппыФормы.ОбычнаяГруппа;

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

Альтернативный подход: перемещение уже существующего элемента

Что делать, если нужная группа уже создана интерактивно в конфигураторе или была добавлена ранее в коде методом Добавить()? Нам совсем не обязательно удалять ее и создавать заново через Вставить(). Мы можем использовать метод Переместить() коллекции элементов формы.

Давайте рассмотрим синтаксис этого метода:

Элементы.Переместить(<Элемент>, <Родитель>, <ЭлементПередКоторымПоместить>)

Этот метод позволяет быстро «перетащить» элемент в начало списка элементов формы. Посмотрим на практический пример перемещения группы:


// Предположим, что группа "МояГруппа" уже существует на форме
ПервыйЭлемент = ?(Элементы.Количество() > 0, Элементы.Получить(0), Неопределено);

Если Элементы.Найти("МояГруппа") <> Неопределено Тогда
    Элементы.Переместить(Элементы.МояГруппа, ЭтаФорма, ПервыйЭлемент);
КонецЕсли;

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

Важные правила разработки и ограничения платформы

При динамической работе с интерфейсом управляемых форм крайне важно соблюдать технологические стандарты платформы "1С:Предприятие 8", иначе ваш код будет вызывать критические ошибки или работать неоптимально.

  1. Контекст выполнения. Любые манипуляции с составом элементов формы (добавление, удаление, перемещение) допускается выполнять исключительно на сервере. Самым лучшим и безопасным местом для выполнения этого кода является предопределенный обработчик события формы ПриСозданииНаСервере. На клиенте динамическое изменение структуры элементов формы заблокировано платформой из соображений производительности.
  2. Порядок создания реквизитов и элементов. Если вы хотите разместить внутри созданной группы новые поля ввода, которые должны быть привязаны к новым программно создаваемым реквизитам, строго соблюдайте следующую очередность:
    1. Сначала создавайте новые реквизиты формы с помощью метода ИзменитьРеквизиты().
    2. Только после успешного добавления реквизитов приступайте к созданию элементов формы (групп, полей ввода) методами Вставить() или Добавить(). Попытка указать в качестве пути к данным элемента формы реквизит, который еще не зарегистрирован в схеме формы, приведет к аварийному завершению программы.
  3. Влияние на производительность системы. Программное добавление и перемещение элементов на управляемой форме отключает автоматический механизм кэширования интерфейса на стороне клиента. Каждое открытие такой формы будет требовать полноценной генерации интерфейса сервером и передачи его клиенту, что увеличивает время отклика. Рекомендуется использовать динамическое создание элементов только тогда, когда это действительно необходимо. Во всех остальных случаях лучше создать группу интерактивно в конфигураторе и управлять ее отображением через свойство Видимость.

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

← На главную