Как программно вывести таблицу значений с динамическими колонками на управляемую форму в 1С?

Программист 1С v8.3 (Управляемые формы) 1С:Управление торговлей IT и автоматизация бизнеса
← На главную

Работа с управляемыми формами в 1С 8.3 существенно отличается от привычных «обычных» форм. Одной из самых частых трудностей, с которыми сталкиваются разработчики, является вывод произвольной ТаблицыЗначений на форму, особенно когда состав ее колонок заранее неизвестен и может меняться. В управляемом приложении структура формы жестко типизирована на сервере, поэтому просто «приравнять» таблицу к элементу формы не получится.

В этой статье мы подробно разберем, как решить эту задачу, избегая нудного ручного заполнения в цикле, и рассмотрим наиболее эффективные методы, включая программное создание реквизитов и использование встроенных механизмов платформы.

Метод 1: Полное программное пересоздание структуры таблицы

Этот метод является наиболее универсальным. Мы разберем ситуацию, когда на форме изначально может не быть нужных колонок, и нам требуется создать их «на лету» на основании полученного результата запроса или загруженной таблицы. Основная сложность здесь заключается в том, что нам нужно работать в два этапа: сначала создать реквизиты формы (данные), а затем — элементы формы (визуальное отображение).

Рассмотрим пошаговый алгоритм реализации этой задачи на сервере:


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

    // 3. Подготавливаем массив новых реквизитов на основании колонок ТЗ
    МассивНовыхРеквизитов = Новый Массив;
    Для Каждого КолонкаТЗ Из ТаблицаРезультат.Колонки Цикл
        НовыйРеквизит = Новый РеквизитФормы(КолонкаТЗ.Имя, КолонкаТЗ.ТипЗначения, ИмяТаблицыНаФорме, КолонкаТЗ.Заголовок);
        МассивНовыхРеквизитов.Добавить(НовыйРеквизит);
    КонецЦикла;

    // 4. Применяем изменения структуры (важно: это тяжелая операция, вызываем один раз)
    ИзменитьРеквизиты(МассивНовыхРеквизитов, МассивУдаляемыхРеквизитов);

    // 5. Создаем визуальные элементы (колонки) в таблице на форме
    Для Каждого КолонкаТЗ Из ТаблицаРезультат.Колонки Цикл
        НоваяКолонка = Элементы.Добавить(ИмяТаблицыНаФорме + КолонкаТЗ.Имя, Тип("ПолеФормы"), ЭлементТаблица);
        НоваяКолонка.Вид = ВидПоляФормы.ПолеВвода;
        НоваяКолонка.ПутьКДанным = ИмяТаблицыНаФорме + "." + КолонкаТЗ.Имя;
        НоваяКолонка.Заголовок = КолонкаТЗ.Заголовок;
    КонецЦикла;

    // 6. Заполняем данные
    ЗначениеВРеквизитФормы(ТаблицаРезультат, ИмяТаблицыНаФорме);

КонецПроцедуры

Важный нюанс: Обратите внимание на использование метода ИзменитьРеквизиты. Он позволяет массово добавить и удалить программные реквизиты формы. Если вы будете вызывать его для каждой колонки отдельно, производительность системы резко упадет. Всегда собирайте изменения в массивы и вызывайте метод один раз.

Метод 2: Использование предопределенной структуры

Если вы заранее знаете максимальный набор колонок, которые могут встретиться, лучше создать их в конфигураторе. В этом случае задача упрощается до одной-двух строк кода. Выясним, как это работает на практике.

Когда структура реквизита формы типа ТаблицаЗначений полностью совпадает со структурой объекта ТаблицаЗначений в коде, мы можем использовать метод:

ЗначениеВРеквизитФормы(МояТаблицаЗначений, "ИмяРеквизитаНаФорме");

Если же в вашей ТЗ есть лишние колонки или порядок не совпадает, можно воспользоваться методом Загрузить, но помните, что он работает только с объектом, а не с реквизитом формы напрямую. Поэтому схема будет такой:

  1. Преобразуем реквизит формы в объект: ОбъектТЗ = РеквизитФормыВЗначение("ИмяРеквизитаНаФорме");
  2. Загружаем данные: ОбъектТЗ.Загрузить(РезультатЗапроса.Выгрузить());
  3. Возвращаем данные на форму: ЗначениеВРеквизитФормы(ОбъектТЗ, "ИмяРеквизитаНаФорме");

Метод 3: Динамический список с произвольным запросом

Проанализируем ситуацию: если ваша таблица формируется только на основании данных базы (запросом), то самым правильным решением будет использование ДинамическогоСписка. Многие забывают, что у него есть свойство «Произвольный запрос».

Преимущества этого подхода:

Чтобы программно изменить структуру такого вывода, достаточно изменить текст запроса динамического списка:

Элементы.Список.ТекстЗапроса = "ВЫБРАТЬ * ИЗ Справочник.Номенклатура ГДЕ ...";

Метод 4: Вывод через Табличный документ

Если данные нужны пользователю только для просмотра и анализа (без редактирования в ячейках), рассмотрим наиболее быстрый способ «в две строки» — вывод в поле табличного документа. Это часто используется в отчетах или при предпросмотре загрузки из Excel.

Процесс выглядит следующим образом:

  1. Создаем на форме элемент типа «Поле табличного документа».
  2. Выводим результат запроса или ТЗ напрямую в этот документ:

Построитель = Новый ПостроительОтчета;
Построитель.ИсточникДанных = Новый ОписаниеИсточникаДанных(МояТаблицаЗначений);
Построитель.Вывести(Элементы.ПолеТабличногоДокумента);

Это решение избавляет от необходимости манипулировать реквизитами формы и работает крайне быстро даже на больших объемах данных.

Типичные ошибки при динамической работе с формой

Разберем причину ошибки «Получение элемента по индексу для значения не определено», которая часто возникает у новичков. Она обычно связана с попыткой обратиться к коллекции Элементы по имени, которого не существует в данный момент (например, элемент был удален или еще не создан).

Рекомендации для стабильной работы:

Таким образом, выбор метода зависит от ваших целей. Если нужна полная интерактивность и редактирование — используйте Метод 1 с программным созданием реквизитов. Если достаточно просмотра — Метод 4 с табличным документом сэкономит вам массу времени и строк кода.

← На главную