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