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