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

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

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

Особенности обращения к ячейкам динамической таблицы значений

В платформе 1С объект СтрокаТаблицыЗначений позволяет обращаться к ячейкам не только через прямое указание реквизита как свойства (через точку), но и с помощью индексного оператора скобок []. Это дает возможность динамически передавать имя колонки в виде строковой переменной или ее порядковый номер.

Рассмотрим два основных сценария работы с динамическими колонками:

  1. Прямое обращение по известному имени колонки: если у нас есть коллекция исходных ключей (например, список кодов поставок), мы формируем имя колонки и напрямую обращаемся к строке: СтрокаТЗ[ИмяКолонки].
  2. Перебор коллекции колонок: если мы не знаем точного состава или хотим найти первую заполненную ячейку в строке среди всех доступных колонок, обходим коллекцию Колонки таблицы значений.

Способ 1. Обход колонок через коллекцию и поиск заполненных значений

Если требуется проанализировать каждую строку таблицы значений и найти, в каких именно динамических колонках присутствуют данные, применим перебор коллекции колонок. Разберем пример реализации:


// Создаем структуру динамических колонок
Для Каждого СтрПоставки Из тзПоставок Цикл
    ИмяКолонки = "П_" + Формат(СтрПоставки.ПоставкаКод, "ЧГ=");
    
    // Обязательно проверяем, не была ли колонка добавлена ранее
    Если тзФакта.Колонки.Найти(ИмяКолонки) = Неопределено Тогда
        тзФакта.Колонки.Добавить(ИмяКолонки);
    КонецЕсли;
КонецЦикла;

// Обход строк и поиск значений в динамических колонках
Для Каждого СтрокаФакта Из тзФакта Цикл
    Для Каждого Колонка Из тзФакта.Колонки Цикл
        // Проверяем, что это динамическая колонка поставок
        Если Лев(Колонка.Имя, 2) = "П_" Тогда
            ЗначениеЯчейки = СтрокаФакта[Колонка.Имя];
            
            Если ЗначениеЗаполнено(ЗначениеЯчейки) Тогда
                // Найдено заполненное значение
                // Выполняем обработку или передачу в шаблон
            КонецЕсли;
        КонецЕсли;
    КонецЦикла;
КонецЦикла;

Важный момент: метод Колонки.Добавить() вызывает исключение при попытке добавить колонку с уже существующим именем. Поэтому перед добавлением всегда следует выполнять проверку через Колонки.Найти(ИмяКолонки).

Способ 2. Вывод кросс-таблицы в макет с горизонтальными и вертикальными секциями

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

  1. В макете создаем фиксированную область строки (например, ШапкаСтроки) и повторяющуюся динамическую область колонки (например, КолонкаДанных).
  2. Область ячеек на пересечении строки и колонки размечается как СтрокаДанных|КолонкаДанных.
  3. В коде сначала выводим левую часть строки методом ТабличныйДокумент.Вывести(), а затем в цикле по колонкам присоединяем ячейки методом ТабличныйДокумент.Присоединить().

Посмотрим на пример формирования отчета:


ТабДок = Новый ТабличныйДокумент;
Макет = ПолучитьМакет("МакетОтчета");

ОбластьШапка = Макет.ПолучитьОбласть("Шапка|ШапкаСтроки");
ОбластьШапкаКолонки = Макет.ПолучитьОбласть("Шапка|КолонкаДанных");
ОбластьСтрокаФикс = Макет.ПолучитьОбласть("СтрокаДанных|ШапкаСтроки");
ОбластьЯчейкаДанных = Макет.ПолучитьОбласть("СтрокаДанных|КолонкаДанных");

// 1. Вывод шапки таблицы
ТабДок.Вывести(ОбластьШапка);
Для Каждого СтрПоставки Из тзПоставок Цикл
    ОбластьШапкаКолонки.Параметры.Заголовок = "Поставка " + Строка(СтрПоставки.ПоставкаКод);
    ТабДок.Присоединить(ОбластьШапкаКолонки);
КонецЦикла;

// 2. Вывод строк с динамическими колонками
Для Каждого СтрФакта Из тзФакта Цикл
    // Заполняем фиксированные реквизиты строки
    ОбластьСтрокаФикс.Параметры.Заполнить(СтрФакта);
    ТабДок.Вывести(ОбластьСтрокаФикс);
    
    // Присоединяем динамические колонки в той же последовательности
    Для Каждого СтрПоставки Из тзПоставок Цикл
        ИмяКолонки = "П_" + Формат(СтрПоставки.ПоставкаКод, "ЧГ=");
        
        // Получаем значение ячейки по имени колонки
        Значение = СтрФакта[ИмяКолонки];
        
        ОбластьЯчейкаДанных.Параметры.Значение = Значение;
        ТабДок.Присоединить(ОбластьЯчейкаДанных);
    КонецЦикла;
КонецЦикла;

Альтернативные архитектурные решения

Если задача заключается в формировании отчетов со сложной аналитикой, ручное создание колонок в таблице значений часто оказывается избыточным. Рассмотрим более удобные механизмы платформы 1С:

  1. Система компоновки данных (СКД): использование структуры «Таблица» в настройках СКД позволяет вывести измерения в строки и колонки автоматически. Платформа самостоятельно сформирует кросс-таблицу без необходимости программного перебора и ручного добавления колонок.
  2. Итоги в запросе: использование конструкции ИТОГИ ПО в тексте запроса с дальнейшим обходом через РезультатЗапроса.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам) позволяет легко разделять уровни строк и колонок.
← На главную