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