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