При разработке и доработке отчетов на базе системы компоновки данных (СКД) разработчики периодически сталкиваются с ситуацией: простое добавление нового поля в выбранные поля отчета неожиданно изменяет итоговые суммы ресурсов или количество строк. Более того, при выгрузке встроенного отчета во внешний файл идентичный отчет с теми же параметрами может выдать результат, отличный от встроенного варианта и совпадающий с консолью запросов. Разберем детально, почему это происходит и как правильно решить данную проблему.
Основная причина изменения итогов при добавлении поля кроется в алгоритме оптимизации, который платформа 1С применяет к запросам схемы компоновки данных. Рассмотрим, как компоновщик макета формирует итоговый запрос к СУБД:
ЛЕВОЕ СОЕДИНЕНИЕ, но поля из присоединяемой таблицы не выбраны в отчете, не участвуют в группировках, отборах или сортировках, СКД полностью вырезает эту секцию соединения из итогового SQL-запроса для экономии ресурсов СУБД.Проанализируем, почему выгруженный во внешний файл отчет может сразу выдавать другие данные по сравнению со встроенным:
ХранилищеВариантовОтчетов). Внешний отчет запускается с чистыми настройками схемы по умолчанию, где эти скрытые фильтры отсутствуют.Чтобы точно определить, какой именно запрос отправляется в СУБД, снимем макет компоновки программно. Посмотрим на пример кода, позволяющего получить реальный текст запроса с учетом всех примененных оптимизаций:
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(
СхемаКомпоновкиДанных,
КомпоновщикНастроек.ПолучитьНастройки(),
ДанныеРасшифровки
);
Для Каждого НаборДанных Из МакетКомпоновки.НаборыДанных Цикл
Если ТипЗнч(НаборДанных) = Тип("НаборДанныхЗапросКомпоновкиДанных") Тогда
ТекстРеальногоЗапроса = НаборДанных.Запрос;
Сообщить("Фактический запрос СКД:");
Сообщить(ТекстРеальногоЗапроса);
КонецЕсли;
КонецЦикла;
Сравним текст полученного запроса до и после добавления поля: мы увидим появление секций ЛЕВОЕ СОЕДИНЕНИЕ или дополнительных условий в секции ГДЕ.
Разберем основные варианты исправления схемы компоновки данных для получения корректных итогов:
Вместо объединения таблиц через ЛЕВОЕ СОЕДИНЕНИЕ внутри одного текста запроса вынесем присоединяемую таблицу в отдельный Набор данных - запрос. Свяжем наборы на вкладке Связи наборов данных схемы компоновки. В этом случае СКД самостоятельно выполнит соединение результатов на уровне процессора компоновки без физического умножения строк базового набора и без искажения ресурсов.
Если необходимо оставить связь внутри одного запроса, гарантируем уникальность ключей во второй таблице. Для этого предварительно сгруппируем ее во временной таблице по полям связи с использованием агрегатных функций (МАКСИМУМ или МИНИМУМ), исключая появление дублей по ключу соединения.
Если размножение строк неизбежно из-за структуры данных, скорректируем расчет итогов на вкладке Ресурсы. Используем поле Рассчитывать по или специальные функции языка выражений СКД, например расчет ресурса по уникальным группировкам через Сумма(ВычислитьВыражениеСГруппировкойМассив(...)), чтобы исключить повторный учет дублированных записей в итогах.
При тестировании встроенного отчета обязательно выполним команду Установить стандартные настройки в пользовательском режиме. Это исключит влияние кэшированных фильтров и параметров, сохраненных в информационной базе для текущего пользователя.