Как правильно вывести строки в макет методом Присоединить для создания динамических отчетов

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

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

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

Анализ проблемы: почему «съезжает» макет?

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

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

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

Для реализации качественного отчета нам необходимо применить так называемый метод «Сетки». Разберем его по шагам.

Шаг 1. Получение полных списков измерений.

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

Шаг 2. Подготовка данных для быстрого доступа.

Чтобы не делать поиск в таблице значений внутри вложенных циклов (что крайне медленно), проанализируем возможность использования объекта Соответствие или Структура. Мы можем выгрузить основной результат запроса в таблицу и проиндексировать её, либо собрать ключ вида Период + Организация + Налог.

Программная реализация вывода строк

Рассмотрим пример кода, который реализует правильный обход. Предположим, у нас уже выведена шапка отчета, и у нас есть массив МассивОрганизаций и МассивПериодов.


// 1. Сначала выводим левую фиксированную часть строки (Наименование налога)
Для Каждого ТекущийНалог Из СписокНалогов Цикл
    
    ОбластьСтрокаНаименование = Макет.ПолучитьОбласть("Строка|Наименование");
    ОбластьСтрокаНаименование.Параметры.НаименованиеНалога = ТекущийНалог.Значение;
    ТабДок.Вывести(ОбластьСтрокаНаименование);
    
    // 2. Вложенный цикл по периодам (колонки)
    Для Каждого ТекущийПериод Из МассивПериодов Цикл
        
        // 3. Вложенный цикл по организациям (под-колонки)
        Для Каждого ТекущаяОрг Из МассивОрганизаций Цикл
            
            ОбластьДанных = Макет.ПолучитьОбласть("Строка|ДанныеОрганизации");
            
            // Пытаемся найти сумму для этой комбинации Налог + Период + Организация
            ПараметрыПоиска = Новый Структура;
            ПараметрыПоиска.Вставить("Налог", ТекущийНалог.Значение);
            ПараметрыПоиска.Вставить("Период", ТекущийПериод);
            ПараметрыПоиска.Вставить("Организация", ТекущаяОрг);
            
            СтрокиДанных = ТаблицаРезультатов.НайтиСтроки(ПараметрыПоиска);
            
            Если СтрокиДанных.Количество() > 0 Тогда
                ОбластьДанных.Параметры.Сумма = СтрокиДанных[0].Сумма;
            Иначе
                // Критически важно: заполняем нулем, если данных нет
                ОбластьДанных.Параметры.Сумма = 0;
            КонецЕсли;
            
            // Присоединяем область всегда, независимо от наличия данных
            ТабДок.Присоединить(ОбластьДанных);
            
        КонецЦикла;
        
    КонецЦикла;
    
КонецЦикла;

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

Оптимизация с использованием итогов в запросе

Проанализируем более профессиональный подход. Вместо нескольких запросов и ручного поиска в таблице значений, мы можем использовать один запрос с предложением ИТОГИ. Это позволит нам использовать обход выборки по группировкам.

Пример структуры обхода:

  1. ВыборкаНалог = Результат.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам, "Налог"); — здесь мы делаем Вывести() левой части строки.
  2. ВыборкаПериод = ВыборкаНалог.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам, "Период", "ВСЕ"); — ключевое слово ВСЕ заставит систему 1С вернуть даже те периоды, в которых нет данных по текущему налогу.
  3. ВыборкаОрг = ВыборкаПериод.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам, "Организация", "ВСЕ"); — аналогично получаем все организации.

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

Оформление и границы ячеек

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

Альтернатива: Система компоновки данных (СКД)

Важно упомянуть, что ручной вывод макета через Присоединить — это трудоемкий процесс. В современной разработке на платформе 8.3 для таких задач рекомендуется использовать СКД с типом вывода «Таблица».

В СКД достаточно перетащить «Налоги» в строки, а «Период» и «Организацию» в колонки. Система автоматически выполнит соединение данных, создаст эталонную сетку колонок и заполнит пустые значения. Это экономит время разработчика и снижает вероятность ошибок при верстке макета.

Однако, если требования к оформлению специфичны (например, сложная многоуровневая шапка с объединенными ячейками, которые нельзя реализовать в СКД), метод Присоединить остается единственным надежным инструментом программиста.

← На главную