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

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

При работе с Системой Компоновки Данных (СКД) часто возникает ситуация, когда компоновщик самостоятельно определяет место наложения отбора. В частности, при выполнении левого соединения основной таблицы с дополнительной, СКД может наложить отбор на поле присоединенной таблицы в секции ГДЕ итогового запроса. Это приводит к тому, что левое соединение превращается во внутреннее, так как строки, не прошедшие отбор в правой таблице, просто отсекаются.

Многие разработчики в такой ситуации привыкли отключать флаг Автозаполнение, но это лишает нас удобства автоматического формирования запросов. Давайте разберем, как решить эту проблему, сохраняя все преимущества Автозаполнения.

Метод «разведения» полей (псевдоним для отбора)

Этот метод является наиболее надежным и элегантным способом управления поведением компоновщика. Суть подхода заключается в том, что мы создаем «обманку» для пользователя, которая физически ссылается на другое поле в запросе.

  1. Откройте Набор данных - запрос в вашей схеме компоновки.
  2. Добавьте в запрос дополнительное поле, которое будет использоваться исключительно для наложения отбора. Назовем его, например, ЦветДляОтбора.
  3. На вкладке Наборы данных установите для этого поля ЦветДляОтбора ограничение Условие, разрешив его использование. В то же время для исходного поля Цвет установите ограничение, запрещающее использование в Условии (отметьте галочку Ограничение поля - Условие).
  4. Перейдите на вкладку Настройки в раздел Отбор. Добавьте туда поле Цвет.
  5. В колонке Представление для этого поля укажите Цвет, а в качестве пути к данным (в расширенном режиме) укажите наше техническое поле ЦветДляОтбора.

Таким образом, пользователь в интерфейсе видит привычное поле Цвет, но при наложении отбора СКД будет использовать значение из поля ЦветДляОтбора. Поскольку ЦветДляОтбора жестко определен в запросе источника, вы можете управлять тем, как именно он обрабатывается внутри соединения, не позволяя компоновщику выносить условие в итоговый ГДЕ.

Использование временных таблиц и параметров

Если ваша архитектура предполагает использование Временных таблиц, помните, что СКД по умолчанию просматривает весь текст запроса и пытается оптимизировать условия. Чтобы исключить некорректное наложение отбора:

Рассмотрим пример правильной организации логики:


ВЫБРАТЬ
    Данные.Ссылка КАК Ссылка,
    ПрисоединяемыеДанные.Цвет КАК Цвет
ПОМЕСТИТЬ ВТ_Данные
ИЗ
    Данные КАК Данные
ЛЕВОЕ СОЕДИНЕНИЕ ПрисоединяемыеДанные КАК ПрисоединяемыеДанные
ПО Данные.Ссылка = ПрисоединяемыеДанные.Ссылка
ГДЕ
    (ПрисоединяемыеДанные.Цвет = &Цвет ИЛИ &Цвет ЕСТЬ NULL)

В данном случае, если вы используете параметр &Цвет, СКД не будет пытаться вмешаться в логику фильтрации, так как условие уже жестко прописано внутри Временной таблицы. Вам лишь потребуется передать значение из отбора СКД в этот параметр через настройки связей или через ПриКомпоновкеРезультата.

Почему возникает проблема с расшифровкой?

Важно понимать, что СКД при расшифровке пытается «угадать» путь к данным. Если поле называется одинаково в основной и присоединенной таблице, компоновщик может выбрать неверный путь. Чтобы избежать этого:

Рекомендуем придерживаться стратегии именования полей, отражающей их источник (например, Данные_Цвет и Присоединяемые_Цвет). Это предотвратит конфликты при построении отчета и обеспечит корректную работу механизма расшифровки. Применяя описанные методы, вы сохраните гибкость Автозаполнения, получив полный контроль над структурой результирующего запроса.

← На главную