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

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

При переходе с одной версии платформы на другую программисты часто сталкиваются с ситуацией, когда проверенные временем отчеты начинают вести себя непредсказуемо. Одной из самых коварных проблем является разное поведение Системы компоновки данных (СКД) при обработке одного и того же запроса с идентичными настройками отборов. В этой статье мы разберем, почему на платформе 8.3.10 отчет может выдавать пустой результат, а на 8.3.17 работать корректно, и как это исправить.

Проблема: отборы в СКД и эволюция платформы

Рассмотрим ситуацию: у нас есть сложный запрос, использующий объединения (ОБЪЕДИНИТЬ ВСЕ) или пакеты запросов. На старых релизах платформы (например, 8.3.10) отбор, установленный пользователем в настройках, может применяться не к итоговому результату, а «проталкиваться» внутрь вложенных запросов. Если в разных частях объединения поля имеют одинаковые псевдонимы, но разный смысл или структуру, возникает конфликт имен. Платформа может ошибочно наложить отбор там, где данные не соответствуют условию, что в итоге приводит к пустой таблице.

Выясним причину такого поведения. Начиная с версий 8.3.14 и выше, компания 1С существенно оптимизировала компоновщик макета. Основные изменения коснулись механизма Filter Push-down (проталкивание фильтров). В новых версиях платформы алгоритмы анализа текста запроса стали более «интеллектуальными», позволяя более точно определять, куда именно в SQL-запросе нужно подставить условие WHERE.

Разберем по шагам: почему поведение различается?

Проанализируем ключевые технические факторы, влияющие на результат:

  1. Унификация отборов: В версии 8.3.17 была проведена унификация применения отборов между «Набором данных - объединение» и «Набором данных - запрос» с внутренними объединениями. Ранее СКД могла по-разному интерпретировать поля, если они имели одинаковые синонимы в разных частях UNION.
  2. Механизм автозаполнения: При включенном автозаполнении (Автозаполнение = Истина) СКД сама решает, какие поля доступны для отбора. Если в запросе есть поле Статья, которое встречается в трех разных вложенных таблицах, старая платформа могла запутаться, к какой именно «Статье» относится пользовательский фильтр.
  3. Режим совместимости: Поведение СКД во многом диктуется не только версией установленной платформы, но и режимом совместимости конфигурации. Однако, даже на одной и той же конфигурации разные «движки» платформ могут генерировать разный итоговый SQL-текст.

Как проанализировать исполняемый запрос

Чтобы понять, что именно идет не так, нам недостаточно видеть текст запроса в схеме компоновки. Нам нужно увидеть тот запрос, который СКД отправляет в СУБД. Проанализируем ситуацию с помощью Консоли системы компоновки данных.

Выполним следующие действия:

  1. Загрузим наш отчет в консоль СКД на платформе 8.3.10.
  2. Сгенерируем макет компоновки и извлечем исполняемый запрос.
  3. Повторим процедуру на платформе 8.3.17.
  4. Сравним секции ГДЕ (WHERE).

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

Решение проблемы: устранение двусмысленности

Если мы столкнулись с тем, что отбор «шалит», наиболее эффективным способом будет ручная корректировка псевдонимов полей в финальной части запроса. Рассмотрим пример. Предположим, у нас есть запрос с объединением, где поле называется Статья.

Вместо того чтобы оставлять это имя, создадим итоговый пакет запроса, где явно переименуем результирующее поле. Посмотрим на пример изменения структуры запроса:


// Было (упрощенно):
ВЫБРАТЬ Статья, Сумма ИЗ (
    ВЫБРАТЬ СтатьяЗатрат КАК Статья, Сумма ИЗ Таблица1
    ОБЪЕДИНИТЬ ВСЕ
    ВЫБРАТЬ СтатьяДДС КАК Статья, Сумма ИЗ Таблица2
) КАК ВложенныйЗапрос

// Стало (решение конфликта):
ВЫБРАТЬ Статья КАК СтатьяИтог, Сумма ИЗ (
    ВЫБРАТЬ СтатьяЗатрат КАК Статья, Сумма ИЗ Таблица1
    ОБЪЕДИНИТЬ ВСЕ
    ВЫБРАТЬ СтатьяДДС КАК Статья, Сумма ИЗ Таблица2
) КАК ВложенныйЗапрос

После изменения текста запроса необходимо выполнить следующие действия в конструкторе СКД:

  1. На закладке «Наборы данных» убедиться, что появилось новое поле СтатьяИтог.
  2. На закладке «Настройки» (вкладка «Отбор») заменить старое поле Статья на новое — СтатьяИтог.
  3. Отключить возможность отбора по промежуточным полям, если это необходимо, чтобы компоновщик не пытался «протолкнуть» фильтр слишком глубоко.

Важный момент: Переименование поля в СтатьяИтог заставляет компоновщик макета накладывать отбор именно на результирующую выборку, так как имя поля становится уникальным и не встречается во вложенных частях запроса. Это гарантирует одинаковый результат на любой версии платформы.

Практические советы для разработчиков

Разберем еще несколько рекомендаций, которые помогут избежать подобных проблем в будущем:

Подводя итог, можно сказать, что разница в работе СКД на платформах 8.3.10 и 8.3.17 — это следствие развития продукта и улучшения алгоритмов оптимизации. Если ваш отчет перестал работать, первым делом проанализируйте итоговый макет и устраните неоднозначность имен полей. Это сделает ваш код более надежным и независимым от обновлений платформы.

← На главную