Разработчики 1С часто сталкиваются с ситуацией, когда один и тот же запрос, выполненный в обычной Консоли запросов и в Системе компоновки данных (СКД), выдает разные цифры. Казалось бы, текст запроса идентичен, но в отчете мы видим странные суммы или «пропавшие» строки. Давайте подробно разберем, почему это происходит, как СКД трансформирует ваш код и на что нужно обратить внимание при разработке сложных отчетов.
Первое и самое важное, что мы должны осознать: СКД — это не просто «исполнитель» вашего текста. Это мощный генератор, который перед отправкой запроса к СУБД полностью перестраивает его структуру. Проанализируем, как это работает. Когда вы запускаете отчет, компоновщик смотрит на Настройки отчета (вкладка «Настройки» в схеме компоновки). Если в выбранных полях или группировках отсутствует какое-то поле, которое прописано в секции ВЫБРАТЬ вашего исходного запроса, СКД с большой вероятностью просто вырежет его из финального SQL-текста.
Рассмотрим пример. Допустим, в запросе вы выбираете Ответственный, Номенклатура и Количество. Если пользователь в настройках отчета вывел только Ответственный и Количество, СКД может убрать поле Номенклатура из группировки. В итоге, если в исходном запросе было две строки по разным номенклатурам для одного ответственного, в консоли запросов вы увидите две строки, а в СКД — одну сгруппированную. Это коренным образом меняет итоговый результат, если логика ваших расчетов завязана на количество строк.
Выясним причину расхождений в суммах. В Консоли запросов мы привыкли самостоятельно прописывать агрегацию, например:
ВЫБРАТЬ
Продажи.Ответственный КАК Ответственный,
СУММА(Продажи.Сумма) КАК СуммаОборот
ИЗ
РегистрНакопления.Продажи КАК Продажи
СГРУППИРОВАТЬ ПО
Продажи.Ответственный
В СКД же за расчет итогов отвечает вкладка Ресурсы. Если вы добавили поле в ресурсы и указали функцию Сумма(Поле), СКД будет применять эту функцию на каждом уровне группировки. Проблема часто кроется в «двойном суммировании». Если в самом тексте запроса у вас уже стоит СУММА(Поле), и это же поле вы назначили ресурсом, компоновщик может применить агрегацию повторно к уже агрегированным данным. Именно поэтому автор вопроса видел в отчете «1 или 2» вместо «0 или 1» — СКД сложила значения там, где консоль просто вывела результат первой выборки.
Также важно помнить, что СКД рассчитывает ресурсы по-разному для детальных записей и для итогов. Для корректной работы мы рекомендуем в тексте запроса выбирать «плоские» данные без группировок, а всю математику (суммирование, расчет среднего, максимумы) отдавать на откуп вкладке «Ресурсы».
Проанализируем ситуацию с левыми соединениями (LEFT JOIN). СКД обладает встроенным интеллектом для оптимизации производительности. Если в вашем запросе есть соединение с какой-то таблицей, но ни одно поле из этой таблицы не используется в выбранных полях, отборах или группировках текущей настройки отчета, компоновщик полностью удалит это соединение из финального запроса.
В Консоли запросов соединение выполнится всегда, и если в правой таблице на одну запись левой приходится несколько совпадений, общее количество строк увеличится (произойдет «размножение» строк). В СКД, если поля правой таблицы не выбраны, оптимизатор уберет JOIN, и количество строк останется исходным. Это часто приводит к тому, что итоги в консоли «раздуты» из-за соединений, а в СКД — «чистые», или наоборот, в зависимости от того, как вы спроектировали связь.
Посмотрим на настройки на вкладке «Наборы данных». У каждого поля есть свойство Роль. Эти роли критически важны для расчета итогов. Если вы неправильно указали «Поле выражения» или ошиблись в полях «Родитель», СКД может некорректно сопоставить данные при построении иерархии.
Особое внимание уделите флажкам Игнорировать значения NULL и определению ключевых полей. Если СКД не может однозначно определить уникальность записи (например, во временной таблице не заданы роли измерений), она может начать объединять строки, которые вы считаете разными, или некорректно рассчитывать остатки на периоды. В консоли запросов таких механизмов нет — она просто отображает выборку БД «как есть».
Разберем, как СКД обрабатывает временные таблицы. Когда вы используете ВТ в цепочке запросов, СКД анализирует зависимости. Если вы создали ВТ с десятью полями, но в основном запросе используете только два, СКД перепишет запрос создания ВТ, оставив в нем только эти два поля (и те, что нужны для связей). Это может повлиять на работу функций внутри ВТ, если они полагались на наличие «выброшенных» полей. В консоли запросов ВТ всегда создается ровно так, как написано в коде.
Выясним влияние флажка Автозаполнение. Если он включен, СКД автоматически пытается найти параметры в запросе и сопоставить их с доступными полями. Это удобно, но чревато неявными отборами. Например, если у вас в запросе есть условие ГДЕ Склад = &Склад, и параметр не заполнен, консоль запросов выдаст ошибку или пустой результат. СКД же может обработать этот параметр иначе, в зависимости от настроек (например, если параметр необязательный, условие просто исчезнет из запроса).
Самый эффективный способ отладки — это просмотр того текста, который СКД реально отправляет на сервер. Мы рекомендуем использовать инструмент Консоль системы компоновки данных (часто входит в состав «Инструментов разработчика»).
Последовательность действий для анализа:
dataset в сгенерированном макете. Вы увидите, что текст запроса стал в несколько раз длиннее, в нем появились временные таблицы для расчета итогов и дополнительные условия.Именно сравнение «чистого» запроса из Консоли запросов и «модифицированного» запроса из Консоли СКД поможет вам мгновенно найти причину расхождений. Чаще всего вы увидите, что в финальном запросе СКД добавила лишнюю группировку или, наоборот, убрала критически важное поле, влияющее на уникальность данных.
Резюме: Чтобы данные в СКД совпадали с Консолью запросов, всегда проверяйте настройки ресурсов, следите за ролями полей и не забывайте, что компоновщик оптимизирует запрос под конкретный набор полей, выбранный пользователем «здесь и сейчас».