Как реализовать несколько вариантов отчета в одной схеме СКД

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

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

Анализ проблемы: почему запрос из нескольких временных таблиц возвращает пустой результат

Распространенная ошибка начинающих разработчиков — попытка выбрать данные из нескольких временных таблиц в одном пакете запроса, перечисляя таблицы в секции ИЗ через запятую и используя конструкцию ВЫБОР КОГДА &ТипОтчета = ...:


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

При таком написании происходит декартово произведение всех указанных таблиц. Если хотя бы одна из временных таблиц (например, ВТ_ЗачтеноГП) окажется пустой, итоговый результат всего запроса также станет пустым независимо от значения параметра &ТипОтчета. Известно, что декартово произведение любой таблицы с пустой таблицей дает 0 строк.

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

Самый простой и архитектурно верный способ в СКД без написания лишнего кода — создание нескольких наборов данных (тип Набор данных - Запрос) и настройка пользовательских вариантов отчета на закладке Настройки.

Разберем по шагам алгоритм настройки:

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

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

Способ 2. Объединение выборки через ОБЪЕДИНИТЬ ВСЕ с условием по параметру

Если данные необходимо выводить в рамках одного набора данных, но логика выборки зависит от параметра &ТипОтчета, вместо перечисления таблиц в секции ИЗ следует использовать конструкцию ОБЪЕДИНИТЬ ВСЕ с отсечением неактивных веток в секции ГДЕ.

Рассмотрим пример построения запроса:


ВЫБРАТЬ
    ВТ_ЗачтеноГП.ДокументРасчетов КАК СчетРасчетов,
    ВТ_ЗачтеноГП.ОплаченоЗаПериод КАК Сумма
ИЗ
    ВТ_ЗачтеноГП КАК ВТ_ЗачтеноГП
ГДЕ
    &ТипОтчета = 1

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
    ВТ_НаНачало.ДокументРасчетов,
    ВТ_НаНачало.НепогашеннаяЗадолженность
ИЗ
    ВТ_НаНачало КАК ВТ_НаНачало
ГДЕ
    &ТипОтчета = 2

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
    ВТ_Начислено.ДокументРасчетов,
    ВТ_Начислено.ВыставленоСчетов
ИЗ
    ВТ_Начислено КАК ВТ_Начислено
ГДЕ
    &ТипОтчета = 3

В этом случае СУБД оптимизирует выполнение пакета. Выборки из веток, где условие в секции ГДЕ ложно (например, &ТипОтчета = 2 при переданном значении 1), фактически не обрабатываются, и пустые временные таблицы не приводят к обнулению результата других веток.

Способ 3. Программное формирование результата в модуле объекта

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

Проанализируем пример кода:


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

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

← На главную