Как объединить вывод разных отчетов на одной форме и перевести ручной макет на СКД

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

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

Разберем подробно, как интегрировать отчеты с разной логикой формирования в единый интерфейс и почему стратегически правильно переводить старые отчеты на рельсы СКД.

Анализ исходной ситуации и проблемы смешивания подходов

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

Проанализируем программный вывод СКД, который используется для основных отчетов:


&НаСервере
Процедура ВывестиОтчет(НазваниеМакета, НачалоПериода, КонецПериода)
    СхемаКомпоновкиДанных = ПолучитьМакет(НазваниеМакета);
    КомпоновщикНастроек = Новый КомпоновщикНастроекКомпоновкиДанных;
    КомпоновщикНастроек.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(СхемаКомпоновкиДанных));
    КомпоновщикНастроек.ЗагрузитьНастройки(СхемаКомпоновкиДанных.НастройкиПоУмолчанию);
    
    // Установка параметров периода
    Настройки = КомпоновщикНастроек.Настройки;
    ПараметрПериод = Настройки.ПараметрыДанных.НайтиЗначениеПараметра(Новый ПараметрКомпоновкиДанных("Период"));
    Если ПараметрПериод <> Неопределено Тогда
        ПараметрПериод.Значение.ДатаНачала = НачалоДня(НачалоПериода);
        ПараметрПериод.Значение.ДатаОкончания = КонецДня(КонецПериода);
    КонецЕсли;

    // Процесс вывода
    ДанныеРасшифровки = Новый ДанныеРасшифровкиКомпоновкиДанных;
    КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
    МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, Настройки, ДанныеРасшифровки);
    
    ПроцессорКомпоновкиДанных = Новый ПроцессорКомпоновкиДанных;
    ПроцессорКомпоновкиДанных.Инициализировать(МакетКомпоновки, , ДанныеРасшифровки);
    
    Результат = МакетАнализ; // Поле табличного документа на форме
    Результат.Очистить();
    
    ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
    ПроцессорВывода.УстановитьДокумент(Результат);
    ПроцессорВывода.Вывести(ПроцессорКомпоновкиДанных);
КонецПроцедуры

Этот код универсален, так как он берет любую СхемаКомпоновкиДанных и выводит ее в Результат. Чтобы внедрить сюда «ручной» отчет, нам нужно либо переписать его на СКД, либо создать «обертку», которая будет имитировать поведение процессора вывода. Оптимальный путь — полная конвертация в СКД.

Шаг 1. Почему в СКД может выводиться только одна строка

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

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

  1. Откроем конструктор схемы компоновки данных.
  2. Перейдем на вкладку «Настройки».
  3. В левом окне (дерево настроек) нажмем правой кнопкой мыши на элемент «Отчет» и выберем «Новая группировка».
  4. В открывшемся окне выбора полей не будем выбирать ничего (оставим поле пустым) и нажмем «ОК». Появится элемент <Детальные записи>.

Именно наличие элемента Детальные записи заставляет СКД выводить каждую строку из выборки запроса. Без него отчет будет выводить только общие итоги, если определены ресурсы.

Шаг 2. Реализация итогов и подвалов в стиле ручного макета

В «ручном» отчете вы использовали ОбластьПодвалТаблицы и параметры запроса ИТОГИ ПО ОБЩИЕ. В СКД механизм работы с итогами принципиально иной. Посмотрим, как реализовать аналогичное поведение.

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

Оформление подвала:
Для того чтобы итоги выглядели как отдельная область «Подвал», проанализируем настройки вывода:

  1. На вкладке «Настройки» выберем уровень «Отчет».
  2. Перейдем на вложенную вкладку «Другие настройки» (внизу).
  3. Найдем параметр «Расположение общих итогов».
  4. Установим значение Конец. Это гарантирует, что суммарные показатели будут выведены в самом низу таблицы.

Шаг 3. Передача специфических параметров в СКД

В вашем исходном коде была жесткая привязка к сотруднику: Запрос.Параметры.Вставить("Сотрудник", Справочники.Пользователи.НайтиПоКоду("ЦФП")). При переходе на СКД мы можем сделать это более элегантно.

Рассмотрим два варианта установки таких параметров:

Вариант А: В самой схеме (статичный)
На вкладке «Параметры» создадим параметр Сотрудник. В колонке «Выражение» напишем: Справочники.Пользователи.НайтиПоКоду("ЦФП"). Установим флаг «Ограничение доступности». Теперь этот параметр будет всегда вычисляться автоматически, и его не нужно прописывать в коде.

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


Настройки = КомпоновщикНастроек.Настройки;
ПараметрСотрудник = Настройки.ПараметрыДанных.НайтиЗначениеПараметра(Новый ПараметрКомпоновкиДанных("Сотрудник"));
Если ПараметрСотрудник <> Неопределено Тогда
    ПараметрСотрудник.Значение = Справочники.Пользователи.НайтиПоКоду("НужныйКод");
    ПараметрСотрудник.Использование = Истина;
КонецЕсли;

Шаг 4. Объединение логики в едином обработчике

Чтобы ваша кнопка (Декорация1) и выбор в табличном поле работали одинаково, нам нужно свести их к вызову процедуры ВывестиОтчет(). Если вы переделали отчет на СКД и сохранили его как макет в основном объекте (обработке), достаточно просто добавить его название в список доступных макетов.

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


&НаКлиенте
Процедура ПолучитьМакеты()
    ТабличноеПолеАнализ.Очистить();
    
    // Обычные отчеты на СКД
    НовыйМакет = ТабличноеПолеАнализ.Добавить();
    НовыйМакет.Название = "Скорость";
    НовыйМакет.Описание = "Анализ скорости выполнения";
    
    // Наш новый отчет, переведенный с ручного макета на СКД
    НовыйМакет = ТабличноеПолеАнализ.Добавить();
    НовыйМакет.Название = "ОтчетПоЦФП"; // Имя макета СКД в объекте
    НовыйМакет.Описание = "Судебный отчет (ЦФП)";
КонецПроцедуры

Теперь при выборе строки "Судебный отчет" сработает та же процедура ВывестиОтчет, которая инициализирует компоновщик, установит период и выведет данные в Результат. Это избавляет от необходимости открывать отдельные формы через ПолучитьФорму().

Рекомендации по оформлению (Макеты СКД)

Если стандартный вид таблицы СКД не устраивает и нужно в точности повторить «ручной» макет (определенные цвета, шрифты, объединение ячеек в шапке), следует воспользоваться вкладкой «Макеты» в конструкторе СКД. Это позволяет:

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

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

← На главную