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