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