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

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

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

Почему метод УстановитьПривязку не сдвигает элементы автоматически

Проанализируем механику работы метода УстановитьПривязку(). В обычных формах привязки служат исключительно для управления поведением границ элементов при изменении геометрических размеров родительского окна пользователем (растягивание или сжатие формы). Они не реализуют механизм авторазметки (flow/autolayout) и не перемещают элементы управления в момент вызова.

Начальное физическое положение и габариты любого элемента определяются исключительно его координатами:

  1. Лево — расстояние от левой границы контейнера или формы;
  2. Верх — расстояние от верхней границы;
  3. Ширина — горизонтальный размер элемента;
  4. Высота — вертикальный размер элемента.

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

Пошаговый алгоритм: добавление поля и смещение соседних элементов

Рассмотрим конкретную задачу: на форме присутствуют надпись Надписьученик и поле ввода ученик. Нам нужно вставить между ними числовое поле Возвраст шириной 50 пикселей.

Разберем последовательность действий:

  1. Создаем новый элемент через коллекцию ЭлементыФормы.Добавить() с указанием нужного типа элемента управления.
  2. Устанавливаем тип значения через объект ОписаниеТипов.
  3. Вычисляем начальные координаты нового элемента (Верх, Лево, Высота, Ширина) относительно базовых полей.
  4. Корректируем размеры и положение соседнего поля ученик.

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

Посмотрим на рабочий пример кода в обработчике события ПриОткрытии:


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

Настройка привязок при масштабировании формы

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

Чтобы форма масштабировалась гармонично, настроим привязку границ динамического элемента и соседнего с ним поля:


// Привязываем правую границу нового поля пропорционально или к соседним элементам
НовоеПоле.УстановитьПривязку(ГраницаЭлементаУправления.Лево, ЭлементыФормы.Надписьученик, ГраницаЭлементаУправления.Право);
НовоеПоле.УстановитьПривязку(ГраницаЭлементаУправления.Право, ЭлементыФормы.Надписьученик, ГраницаЭлементаУправления.Право);

// Перепривязываем левую границу сдвинутого поля к правому краю нового элемента
ЭлементыФормы.ученик.УстановитьПривязку(ГраницаЭлементаУправления.Лево, НовоеПоле, ГраницаЭлементаУправления.Право);

Дополнительные аспекты, о которых важно помнить

При программном управлении элементами обычных форм обратим внимание на следующие особенности платформы:

  1. Указание родительского контейнера: Метод ЭлементыФормы.Добавить() принимает четвертым параметром родительский элемент (например, панель или страницу панели). Если целевые реквизиты расположены внутри панели, а родитель не указан, созданное поле разместится на самой форме с нулевым отсчетом от окна, что вызовет наложение интерфейсных элементов.
  2. Порядок обхода (клавиша Tab): Новый программный элемент помещается в конец очереди обхода. Чтобы пользователь мог переходить в поле естественным образом, следует использовать метод формы УстановитьПорядокОбхода().
  3. Альтернативное решение через видимость: Если состав полей известен заранее, гораздо стабильнее нарисовать элемент непосредственно в конфигураторе, настроить его привязки визуально и установить свойство Видимость = Ложь. В коде останется только включить видимость нужного элемента, избавившись от сложных математических расчетов координат в рантайме.
← На главную