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