Нередко разработчики 1С сталкиваются с ситуацией, когда сложный пакетный запрос с временными таблицами возвращает ожидаемый результат в консоли запросов, но при переносе в схему компоновки данных (СКД) и формировании отчета выдает неверные суммы, обнуляет строки или вовсе возвращает пустой результат. Разберем по шагам, почему это происходит и как найти источник ошибки.
Главное отличие системы компоновки данных от обычной консоли запросов заключается в том, что СКД не выполняет исходный текст запроса «как есть». Компоновщик макета анализирует текущие настройки отчета (выбранные поля, группировки, отборы) и перестраивает текст запроса перед отправкой в СУБД:
ПТК_РП.Ссылка.Контрагент) компоновщик СКД заменяет на автоматические левые соединения с таблицами объектов, что может изменить план выполнения и порядок работы с пустыми значениями NULL.Для проверки этой гипотезы можно отключить свойство Автозаполнение на вкладке «Наборы данных» схемы компоновки и вручную объявить все доступные поля и условия.
Чтобы точно понять, какие изменения СКД внесла в исходный текст, необходимо извлечь фактический запрос из макета компоновки. Сделать это можно как с помощью специализированных консолей отчетов СКД, так и программно на встроенном языке 1С.
Рассмотрим программный способ перехвата сгенерированного запроса:
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, КомпоновщикНастроек.ПолучитьНастройки());
Для Каждого НаборДанных Из МакетКомпоновки.НаборыДанных Цикл
Если ТипЗнч(НаборДанных) = Тип("НаборДанныхЗапросМакетаКомпоновкиДанных") Тогда
ТекстРеальногоЗапроса = НаборДанных.Запрос;
КонецЕсли;
КонецЦикла;
Полученный ТекстРеальногоЗапроса следует скопировать в обычную консоль запросов и выполнить с теми же параметрами, чтобы наглядно увидеть все преобразования схемы.
В тексте запроса используются условия фильтрации по датам через параметры &НачПериода и &КонПериода. Проанализируем типичные проблемы при работе с ними в СКД:
&СтандартныйПериод.ДатаНачала), в запрос может передаваться пустая дата (01.01.0001 00:00:00), из-за чего отбор МЕЖДУ отсечет все данные.ПТК_РП.Ссылка.Дата МЕЖДУ НЕОПРЕДЕЛЕНО И ... является грубой ошибкой. Для поля типа «Дата» недопустимо использовать значение НЕОПРЕДЕЛЕНО. В запросе всегда следует указывать явный литерал минимальной даты: ДАТАВРЕМЯ(1, 1, 1).Посмотрим на агрегатные функции в исходном запросе. Если в запросе выполняется деление или вычисление агрегатов вида МАКСИМУМ(...), то при выводе в СКД поведение зависит от вкладки Ресурсы:
Сумма(СуммаПТК), СКД заново агрегирует детальные записи на уровне группировок, полностью игнорируя предварительный расчет из запроса.K1 / K2) необходимо всегда защищаться от деления на ноль и NULL через функцию ЕСТЬNULL и оператор ВЫБОР КОГДА ..., иначе компоновщик при обработке значений выдаст некорректный результат в итогах.Выясним еще одну частую причину различий: консоль запросов обычно запускается под полными правами администратора, в то время как отчет в пользовательском режиме выполняется с учетом ограничений доступа на уровне записей (RLS). Ограничения прав автоматически добавляют скрытые условия ГДЕ ко всем таблицам документов и регистров, исключая недоступные пользователю данные из выборки.