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

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

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

1. Автозаполнение и оптимизация текста запроса компоновщиком

Главное отличие системы компоновки данных от обычной консоли запросов заключается в том, что СКД не выполняет исходный текст запроса «как есть». Компоновщик макета анализирует текущие настройки отчета (выбранные поля, группировки, отборы) и перестраивает текст запроса перед отправкой в СУБД:

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

Для проверки этой гипотезы можно отключить свойство Автозаполнение на вкладке «Наборы данных» схемы компоновки и вручную объявить все доступные поля и условия.

2. Как получить и проанализировать реальный запрос СКД

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

Рассмотрим программный способ перехвата сгенерированного запроса:


КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, КомпоновщикНастроек.ПолучитьНастройки());

Для Каждого НаборДанных Из МакетКомпоновки.НаборыДанных Цикл
    Если ТипЗнч(НаборДанных) = Тип("НаборДанныхЗапросМакетаКомпоновкиДанных") Тогда
        ТекстРеальногоЗапроса = НаборДанных.Запрос;
    КонецЕсли;
КонецЦикла;

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

3. Корректность передачи параметров периода

В тексте запроса используются условия фильтрации по датам через параметры &НачПериода и &КонПериода. Проанализируем типичные проблемы при работе с ними в СКД:

  1. Неинициализированные параметры. В консоли запросов параметры заполняются явно. В СКД, если на вкладке «Параметры» для них не настроены выражения связи со стандартным периодом пользователя (например, &СтандартныйПериод.ДатаНачала), в запрос может передаваться пустая дата (01.01.0001 00:00:00), из-за чего отбор МЕЖДУ отсечет все данные.
  2. Некорректные литералы в условиях. Использование конструкций вида ПТК_РП.Ссылка.Дата МЕЖДУ НЕОПРЕДЕЛЕНО И ... является грубой ошибкой. Для поля типа «Дата» недопустимо использовать значение НЕОПРЕДЕЛЕНО. В запросе всегда следует указывать явный литерал минимальной даты: ДАТАВРЕМЯ(1, 1, 1).

4. Механизм расчета ресурсов и группировок

Посмотрим на агрегатные функции в исходном запросе. Если в запросе выполняется деление или вычисление агрегатов вида МАКСИМУМ(...), то при выводе в СКД поведение зависит от вкладки Ресурсы:

  1. Если поле выведено в таблицу или группировку отчета, но не добавлено в список ресурсов, СКД не сможет автоматически рассчитать итоги по группировкам.
  2. Если поле назначено ресурсом с выражением Сумма(СуммаПТК), СКД заново агрегирует детальные записи на уровне группировок, полностью игнорируя предварительный расчет из запроса.
  3. При делении на коэффициенты (например, K1 / K2) необходимо всегда защищаться от деления на ноль и NULL через функцию ЕСТЬNULL и оператор ВЫБОР КОГДА ..., иначе компоновщик при обработке значений выдаст некорректный результат в итогах.

5. Влияние прав доступа (RLS)

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

← На главную