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