Как программно вывести динамические колонки по месяцам в отчете 1С без использования СКД

Программист Управленческий учет IT и автоматизация бизнеса
← На главную

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

Понятие горизонтальных и вертикальных областей

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

Когда мы создаем макет, мы можем выделить несколько колонок и присвоить им имя (например, КолонкаМесяц). Сочетая горизонтальные секции и вертикальные, мы получаем сетку. Программный доступ к конкретной ячейке на пересечении этих секций осуществляется через символ вертикальной черты "|".

Рассмотрим ключевую конструкцию: Область = Макет.ПолучитьОбласть("СтрокаДанных|Месяц");. В данном случае система найдет пересечение именованной строки СтрокаДанных и именованной колонки Месяц. Именно этот механизм позволяет нам «собирать» строку отчета по кусочкам, добавляя ячейки одну за другой.

Алгоритм формирования отчета с динамическими колонками

Разберем по шагам процесс построения такого отчета. Представим, что у нас есть данные в таблице значений (ТЗ), содержащей колонки Период (дата) и Сумма.

  1. Подготовка списка периодов. Прежде чем начинать вывод, нам нужно точно знать, сколько колонок будет в отчете. Для этого мы должны проанализировать данные и составить массив уникальных месяцев, которые будут выступать заголовками.
  2. Вывод шапки отчета. Сначала мы выводим фиксированную левую часть шапки, а затем в цикле присоединяем области для каждого месяца.
  3. Циклический вывод строк. Для каждой строки данных (например, по контрагенту или договору) мы сначала выводим первую ячейку строки, а затем вложенным циклом присоединяем суммы по соответствующим месяцам.

Реализация вывода шапки

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

Метод Вывести() всегда начинает новую строку в итоговом табличном документе. Метод Присоединить() добавляет область справа от уже выведенной, оставаясь в рамках текущей строки.


// Получаем макет
Макет = ПолучитьМакет("МакетОтчета");

// Выводим левую фиксированную часть шапки
ОбластьШапкаЛево = Макет.ПолучитьОбласть("Шапка|Заголовок");
ТабДок.Вывести(ОбластьШапкаЛево);

// В цикле выводим колонки месяцев
Для Каждого МесяцДанных Из СписокМесяцев Цикл
    ОбластьШапкаМесяц = Макет.ПолучитьОбласть("Шапка|Месяц");
    ОбластьШапкаМесяц.Параметры.НазваниеМесяца = Формат(МесяцДанных, "ДФ=MMMM");
    ТабДок.Присоединить(ОбластьШапкаМесяц);
КонецЦикла;

Программный вывод строк данных

Теперь выясним, как правильно заполнить тело отчета данными. Важно понимать, что если за определенный месяц данных нет, мы все равно должны «присоединить» пустую ячейку (или ячейку с нулем), иначе структура колонок в отчете сместится, и данные окажутся под неверными заголовками.

Проанализируем пример кода для вывода строк:


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

КонецЦикла;

Важные технические нюансы

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

1. Фиксация колонок. Если месяцев много, отчет будет прокручиваться вправо. Чтобы пользователь всегда видел, к какому объекту относится сумма, рекомендуется зафиксировать левые колонки. Это делается свойством ТабДок.ФиксацияСлева = КоличествоФиксированныхКолонок;.

2. Расшифровка. При программном заполнении параметров области не забывайте заполнять поле Расшифровка. Если вы хотите, чтобы при двойном клике на сумму открывался документ-основание, передайте ссылку на него в параметр расшифровки ячейки макета: ОбластьЗначение.Параметры.СуммаРасшифровка = СсылкаНаДокумент;.

3. Производительность. Поиск данных в цикле (метод Найти()) может работать медленно на больших объемах данных. Оптимальным решением будет предварительная подготовка данных в виде Соответствия или Структуры, где ключом будет комбинация «ИдентификаторОбъекта_Период». Это позволит получать значения мгновенно без перебора таблиц.

4. Итоги по горизонтали. Часто требуется вывести колонку «Итого» в конце каждой строки. Для этого после завершения внутреннего цикла по месяцам мы должны еще раз выполнить ТабДок.Присоединить(), передав туда область итоговой колонки с заранее рассчитанной суммой по всем месяцам текущей строки.

Заключение

Мы рассмотрели гибкий и надежный способ формирования сложных отчетов в 1С. Несмотря на популярность СКД, умение работать с макетами через Вывести() и Присоединить() остается базовым навыком 1С-разработчика. Этот метод незаменим при создании специфических печатных форм, управленческих таблиц и любых отчетов, где структура колонок зависит от текущей выборки данных в информационной базе.

← На главную