Как в СКД вывести один набор данных в разные таблицы с независимыми итогами?

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

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

Разберем типичную ошибку: если мы просто продублируем элемент Таблица в настройках структуры отчета и на каждую таблицу наложим свой отбор, то состав строк изменится верно, но общие итоги (Grand Totals) по обеим таблицам будут одинаковыми. Выясним причину: СКД по умолчанию рассчитывает общие итоги на уровне всего набора данных до применения локальных отборов структуры.

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

Способ 1. Использование фиктивной верхней группировки (Вычисляемое поле)

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

  1. Создадим пользовательское или вычисляемое поле. Назовем его, например, ТипСтроки.
  2. В выражении этого поля пропишем условие проверки. Если соглашение заполнено, присваиваем одну строку, если нет — другую.
    
    ВЫБОР КОГДА Соглашение Заполнено ТОГДА "По соглашениям" ИНАЧЕ "Без соглашений" КОНЕЦ
    
  3. В структуре отчета добавим одну общую группировку по этому новому полю ТипСтроки.
  4. Внутрь этой группировки вложим детальные записи или нужную структуру колонок и строк.
  5. Секретный шаг: чтобы визуально отчет выглядел как две разные таблицы, перейдем в настройки верхней группировки на вкладку "Другие настройки" и отключим вывод самой группировки (установим РасположениеПолейГруппировок в значение "Нет", либо просто скроем заголовки).

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

Способ 2. Разделение ресурсов в самом запросе

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

Рассмотрим пример кода в запросе:


ВЫБРАТЬ 
    Товар,
    Соглашение,
    ВЫБОР КОГДА Соглашение = ЗНАЧЕНИЕ(Справочник.Соглашения.ПустаяСсылка) ТОГДА 0 ИНАЧЕ Сумма КОНЕЦ КАК СуммаС_Соглашением,
    ВЫБОР КОГДА Соглашение = ЗНАЧЕНИЕ(Справочник.Соглашения.ПустаяСсылка) ТОГДА Сумма ИНАЧЕ 0 КОНЕЦ КАК СуммаБезСоглашения
ИЗ 
    РегистрНакопления.Продажи КАК Продажи

Затем на вкладке "Ресурсы" мы просто задаем суммирование для этих двух полей. Таким образом, итоги будут автоматически разделены.

Способ 3. Использование нескольких независимых наборов данных

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

Вместо того чтобы тянуть все данные одним запросом, создадим в схеме СКД два независимых набора данных (наборы данных типа запрос).

  1. Первый набор данных будет содержать запрос с жестким условием в секции ГДЕ (оставляем только заполненные соглашения).
  2. Второй набор данных — аналогичный запрос, но с условием на пустую ссылку.
  3. Важно: связывать эти наборы на вкладке "Связи наборов данных" не нужно!
  4. В настройках отчета просто добавим две независимые группировки на один уровень. Каждая группировка должна использовать поля только из своего набора данных.

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

Способ 4. Использование вложенных схем компоновки данных

Посмотрим на еще один элегантный метод — использование вложенных отчетов в СКД.

  1. Создадим одну базовую схему, которая умеет выводить данные и считать итоги. В этой схеме настроим параметр отчета, например, ВыводитьССоглашением (тип Булево).
  2. В основной схеме отчета в структуру дважды добавим элемент Вложенный отчет.
  3. Для первого вложенного отчета в настройках передадим параметр ВыводитьССоглашением = Истина.
  4. Для второго вложенного отчета передадим ВыводитьССоглашением = Ложь.

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

Способ 5. Программный вывод отчета

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

Разберем по шагам логику программного вывода:

  1. Программно формируем настройки СКД и устанавливаем отбор "Соглашение заполнено".
  2. Инициализируем ПроцессорКомпоновкиДанных и ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент.
  3. Выводим первую таблицу в результирующий ТабличныйДокумент.
  4. Затем программно меняем отбор в настройках на "Соглашение не заполнено".
  5. Снова компонуем макет и с помощью метода Вывести продолжаем вывод данных в тот же табличный документ ниже первой таблицы.
  6. Устанавливаем параметр СтандартнаяОбработка = Ложь, чтобы система не вывела отчет по умолчанию поверх нашего.

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

Резюме: выбор способа зависит от сложности ваших ресурсов и требований к визуалу. Для простых задач лучше всего подходит группировка по вычисляемому полю (Способ 1), а для сложной аналитики со множеством колонок — разделение на независимые наборы данных (Способ 3) или использование вложенных схем (Способ 4).

← На главную