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