При работе со справочниками в платформах 1С часто возникает задача выбрать только те элементы, у которых заполнен определенный ссылочный реквизит (например, Бренд, Контрагент или Номенклатура). Рассмотрим подробно, как правильно составить запрос, с какими подводными камнями можно столкнуться и как обрабатывать значения NULL.
Если реквизит имеет простой ссылочный тип (например, ссылку на справочник Бренды), то незаполненное значение по умолчанию содержит пустую ссылку этого типа. В языке запросов 1С для проверки заполненности используется оператор <> и функция ЗНАЧЕНИЕ().
Разберем базовый пример запроса:
ВЫБРАТЬ
Номенклатура.Ссылка КАК Ссылка
ИЗ
Справочник.Номенклатура КАК Номенклатура
ГДЕ
Номенклатура.Бренд <> ЗНАЧЕНИЕ(Справочник.Бренды.ПустаяСсылка)
Обратите внимание: если нужно получить уникальный список ссылок элементов справочника, использовать секцию СГРУППИРОВАТЬ ПО лишнее. Поле Ссылка в таблице справочника гарантированно уникально, поэтому лишние группировки только снижают производительность запроса.
Простое сравнение с пустой ссылкой работает не всегда. Выясним причины, почему в некоторых случаях такое условие может пропустить нужные данные или вернуть неполный результат.
Номенклатура включена иерархия групп и элементов, а реквизит Бренд назначен только для элементов, то при попытке прочитать этот реквизит у папок (групп) платформа возвратит значение NULL. Так как любое сравнение с NULL через <> возвращает ложь, группы будут автоматически исключены из результата.НЕОПРЕДЕЛЕНО, прямым сравнением с пустой ссылкой одного справочника обойтись не получится.Для универсальной проверки реквизита на заполненность применяется разименование ссылки через точку (получение свойства реквизита) и проверка полученного значения на NULL:
ВЫБРАТЬ
Номенклатура.Ссылка КАК Ссылка
ИЗ
Справочник.Номенклатура КАК Номенклатура
ГДЕ
НЕ Номенклатура.Бренд.Ссылка ЕСТЬ NULL
Разберем, как работает это условие: если поле Бренд содержит пустую ссылку, не содержит значения вовсе или равно NULL, обращение к его свойству Ссылка вернет NULL. Конструкция НЕ ... ЕСТЬ NULL оставит только те записи, у которых ссылочный реквизит реально заполнен и ссылается на существующий элемент.
Если код запроса формируется динамически или требуется передавать значение пустой ссылки из встроенного языка 1С, целесообразно использовать параметры запроса.
Посмотрим на пример текста запроса:
ВЫБРАТЬ
Номенклатура.Ссылка КАК Ссылка
ИЗ
Справочник.Номенклатура КАК Номенклатура
ГДЕ
Номенклатура.Бренд <> &ПустаяСсылкаНаБренд
И НЕ Номенклатура.ЭтоГруппа
В коде модуля на встроенном языке установка параметра будет выглядеть следующим образом:
Запрос = Новый Запрос;
Запрос.Текст = "..."; // Текст запроса
Запрос.УстановитьПараметр("ПустаяСсылкаНаБренд", Справочники.Бренды.ПустаяСсылка());
РезультатЗапроса = Запрос.Выполнить();
Проанализируем ключевые моменты, влияющие на скорость выполнения запроса:
Бренд в конфигураторе у этого реквизита должно быть включено свойство Индексировать (или Индексировать с доп. упорядочиванием).Номенклатура.Бренд <> ЗНАЧЕНИЕ(...) выполняется СУБД быстрее, так как не создает явных или неявных соединений (LEFT JOIN) с таблицей справочника брендов. Если проверка на NULL не требуется, используйте прямое сравнение по полю.ГДЕ НЕ Номенклатура.ЭтоГруппа. Это повышает читаемость кода и явно определяет логику выборки.