К статье
Практический материал

Разработка и Конфигурация · 12 мин

1С: как в запросе проверить значения — NULL, пустые ссылки и условия

Как в запросе 1С проверить NULL, пустую ссылку, пустую строку и вхождение в иерархию. Конструкции ЕСТЬ NULL, ВЫБОР, ПОДОБНО с примерами кода и типичными ошибками.

Язык запросов 1С имеет собственный синтаксис проверок, который заметно отличается от встроенного языка и от классического SQL. Попытка написать = NULL или сравнить ссылку с пустой строкой приводит либо к ошибке построения запроса, либо к молча неверному результату. Поэтому проверки в запросе нужно выполнять специальными конструкциями: ЕСТЬ NULL, ЕСТЬNULL(), оператором ВЫБОР и функциями работы со строками.

Проверки в запросе 1С делятся на несколько типовых задач: проверка на NULL (значение отсутствует после соединения таблиц), проверка на пустую ссылку или пустую строку, проверка вхождения значения в список или иерархию, проверка строки по шаблону. У каждой задачи есть своя идиома, и смешивать их нельзя.

Ниже разобраны все основные сценарии с готовыми фрагментами кода, которые можно переносить в консоль запросов и адаптировать под свои таблицы.

Проверка на NULL: оператор ЕСТЬ NULL

NULL в запросе 1С появляется чаще всего после левого соединения, когда в присоединяемой таблице не нашлось подходящей строки. Также NULL возвращают агрегатные функции по пустому набору и поля составного типа, где фактическое значение отсутствует. Прямое сравнение Поле = NULL в языке запросов 1С не работает так, как ожидается, — результат такого сравнения не определён, и условие фактически не сработает.

Правильная конструкция — постфиксный оператор ЕСТЬ NULL:

ВЫБРАТЬ

Номенклатура.Ссылка КАК Товар,

Остатки.КоличествоОстаток КАК Остаток

ИЗ

Справочник.Номенклатура КАК Номенклатура

ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки КАК Остатки

ПО Номенклатура.Ссылка = Остатки.Номенклатура

ГДЕ

Остатки.КоличествоОстаток ЕСТЬ NULL

Такой запрос вернёт всю номенклатуру, по которой нет остатков. Обратное условие записывается как НЕ Остатки.КоличествоОстаток ЕСТЬ NULL — скобки вокруг всего выражения обязательны, если оно комбинируется с другими условиями через И/ИЛИ.

Замена NULL значением по умолчанию: функция ЕСТЬNULL()

Часто NULL нужно не отфильтровать, а заменить на осмысленное значение — ноль для чисел, пустую строку для строк, конкретную дату. Для этого служит функция ЕСТЬNULL(ПроверяемоеЗначение, ЗначениеЕслиNULL). Оба аргумента должны быть совместимы по типу: нельзя подставить строку вместо числового поля.

ВЫБРАТЬ

Номенклатура.Ссылка КАК Товар,

ЕСТЬNULL(Остатки.КоличествоОстаток, 0) КАК Остаток

ИЗ

Справочник.Номенклатура КАК Номенклатура

ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки КАК Остатки

ПО Номенклатура.Ссылка = Остатки.Номенклатура

Важный нюанс: если поле имеет составной тип (например, «Заказ» может быть ссылкой на разные документы), то ЕСТЬNULL вернёт значение того типа, который передан вторым аргументом. Это удобно для приведения результата к однозначному типу, но при неосторожном использовании может скрыть реальные данные другого типа.

Проверка пустой ссылки, пустой строки и даты

Пустая ссылка и NULL — разные состояния. Пустая ссылка существует в поле явно (например, реквизит не заполнен), а NULL означает отсутствие строки после соединения. Проверка пустой ссылки выполняется сравнением с конструкцией ЗНАЧЕНИЕ:

ГДЕ

Документ.Контрагент = ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка)

Для перечислений синтаксис аналогичен: ЗНАЧЕНИЕ(Перечисление.СтавкиНДС.ПустаяСсылка). Пустая строка проверяется обычным сравнением: Наименование = "". Пустая дата — сравнением с ДАТАВРЕМЯ(1,1,1), это каноническая форма записи незаполненной даты в запросах.

Если поле составного типа и может содержать ссылки разных видов, проверка только на пустую ссылку одного вида недостаточна. Надёжнее комбинировать условия или использовать функцию ВЫРАЗИТЬ для приведения типа перед сравнением.

Типичные ошибки
01
Проверка пустой даты сравнением с пустой строкой — условие никогда не выполнится; используйте ДАТАВРЕМЯ(1,1,1)
02
Смешение NULL и пустой ссылки в одном условии без учёта обоих случаев — часть строк теряется
03
Использование ЕСТЬNULL для замены пустой ссылки — функция не срабатывает, так как пустая ссылка не является NULL
04
Сравнение строки с NULL вместо ЕСТЬ NULL — молча неверный результат без ошибки компиляции

Проверка условий в выборке: оператор ВЫБОР

Когда результат проверки нужно вывести как колонку (например, признак «Есть остаток / Нет остатка»), используется оператор ВЫБОР — аналог CASE из SQL:

ВЫБРАТЬ

Номенклатура.Ссылка КАК Товар,

ВЫБОР

КОГДА Остатки.КоличествоОстаток ЕСТЬ NULL

ТОГДА "Нет на складе"

КОГДА Остатки.КоличествоОстаток = 0

ТОГДА "Нулевой остаток"

ИНАЧЕ "В наличии"

КОНЕЦ КАК Статус

ИЗ

Справочник.Номенклатура КАК Номенклатура

ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки КАК Остатки

ПО Номенклатура.Ссылка = Остатки.Номенклатура

Ветки КОГДА проверяются сверху вниз, срабатывает первая истинная. Ветка ИНАЧЕ необязательна, но без неё при невыполнении всех условий результатом будет NULL — это частый источник неожиданных пустых колонок в отчётах. Все ветки должны возвращать значения совместимых типов.

Проверка вхождения: В, В ИЕРАРХИИ и ПОДОБНО

Проверка по списку значений

Оператор В проверяет вхождение значения в список, переданный параметром, или в результат подзапроса. В параметр удобно передавать массив или список значений из кода:

ГДЕ

Номенклатура.Ссылка В (&СписокТоваров)

Обратное условие — НЕ ... В (...). Учтите, что если в списке встретится NULL, поведение отрицания может отличаться от ожидаемого — список лучше формировать заранее очищенным.

Проверка по иерархии справочника

Для иерархических справочников есть специальный оператор В ИЕРАРХИИ, который выбирает элементы самой группы и всех вложенных уровней без рекурсивных соединений:

ГДЕ

Номенклатура.Ссылка В ИЕРАРХИИ (&ГруппаТоваров)

В параметр можно передать одну группу или список групп. Это самый производительный и читаемый способ проверки принадлежности к ветке дерева; самодельные проверки через Родитель охватывают только фиксированное число уровней и ломаются при изменении глубины иерархии.

Проверка строки по шаблону

Оператор ПОДОБНО проверяет строку по шаблону: символ % — любая последовательность символов, _ — ровно один символ. Например, поиск по фрагменту наименования:

ГДЕ

Номенклатура.Наименование ПОДОБНО "%кабель%"

Если в искомом тексте сами встречаются символы % или _, их нужно экранировать через ключевое слово СПЕЦСИМВОЛ. Учтите, что поиск по шаблону с ведущим % не использует индексы и на больших таблицах выполняется медленно.

Сравнение способов проверки

ЕСТЬ NULL

Единственный корректный способ проверить отсутствие значения после соединения; не работает для пустых ссылок и строк

ЗНАЧЕНИЕ(...ПустаяСсылка)

Проверка незаполненного ссылочного реквизита; требует указания конкретного типа

В / В ИЕРАРХИИ

Проверка вхождения в список или ветку иерархии; список передаётся параметром

ПОДОБНО

Поиск строк по шаблону; медленный на больших таблицах при ведущем %

Проверка результата запроса в коде: Пустой() и типы значений

После выполнения запроса часто нужно проверить, вернул ли он строки. Для этого у объекта РезультатЗапроса есть метод Пустой(). Проверять результат через попытку обхода выборки менее читаемо:

РезультатЗапроса = Запрос.Выполнить();

Если РезультатЗапроса.Пустой() Тогда

Возврат;

КонецЕсли;

Выборка = РезультатЗапроса.Выбрать();

Пока Выборка.Следующий() Цикл

// обработка строки

КонецЦикла;

Если из запроса нужно одно значение, типичный приём — выгрузить результат в таблицу значений и проверить её количество: Если ТаблицаРезультата.Количество() = 0 Тогда .... Для проверки типа значения поля в коде используется функция ТипЗнч() совместно с Тип(), а внутри самого запроса — оператор сравнения с ТИП() через конструкцию ВЫБОР КОГДА Поле ССЫЛКА Справочник.Контрагенты ....

Порядок отладки проверки в запросе
  1. 1
    Откройте консоль запросов и выполните запрос без условия ГДЕ — убедитесь, что данные вообще выбираются
  2. 2
    Добавьте проверяемое поле в список выборки и посмотрите его фактические значения: NULL, пустая ссылка или заполненное значение
  3. 3
    Подберите правильную конструкцию: ЕСТЬ NULL для NULL, ЗНАЧЕНИЕ(...ПустаяСсылка) для пустой ссылки
  4. 4
    Добавьте условие и сравните количество строк до и после — оно должно измениться ожидаемым образом
  5. 5
    Проверьте граничные случаи: записи с NULL, с пустой ссылкой и с заполненным значением
Контрольные точки

Как проверить корректность условия

Количество строк результата
Норма

Изменяется предсказуемо при добавлении условия

Тревожный признак

Результат пустой или не меняется — условие, скорее всего, неверно

Значения проверяемого поля в выборке
Норма

Видно, где NULL, а где пустая ссылка

Тревожный признак

Поле не выведено — тип проверки выбран вслепую

Отрицание условия
Норма

НЕ (условие) возвращает дополнение к исходному набору

Тревожный признак

Сумма строк по условию и его отрицанию меньше общей — в данных есть NULL

Производительность и ограничения проверок

Проверки в секции ГДЕ по индексированным полям (ссылка, измерения регистра) выполняются быстро. Условия с ПОДОБНО "%...", проверки по вычисляемым выражениям и функциям от поля отключают использование индекса и приводят к полному сканированию таблицы. На больших регистрах это может увеличить время выполнения с секунд до минут.

Ещё одно ограничение: условия, наложенные на поля правой таблицы левого соединения, фактически превращают его во внутреннее — строки с NULL отфильтруются. Если нужно сохранить все строки левой таблицы, условие по правой таблице следует переносить в секцию ПО соединения, а не в ГДЕ.

При работе с виртуальными таблицами регистров (Остатки, Обороты, СрезПоследних) условия по измерениям выгоднее передавать в параметры виртуальной таблицы, а не в общее ГДЕ — тогда отбор выполняется до формирования выборки, а не после.

Большинство ошибок с проверками в запросах 1С сводится к смешению трёх состояний: NULL, пустая ссылка и пустая строка. Перед написанием условия полезно один раз выполнить запрос с выводом самого поля и посмотреть, что реально лежит в данных — это экономит время отладки.
ПЗ
Практическое замечание

Частые вопросы о проверках в запросах 1С

Чем NULL отличается от пустой ссылки в запросе 1С?

NULL означает отсутствие значения — например, когда левое соединение не нашло пару в правой таблице. Пустая ссылка — это вполне конкретное значение, записанное в поле. NULL проверяется оператором ЕСТЬ NULL, пустая ссылка — сравнением с ЗНАЧЕНИЕ(Тип.ПустаяСсылка). Одно условие не заменяет другое, и в надёжных запросах часто проверяют оба случая.

Как проверить, что строковое поле не заполнено, если там могут быть пробелы?

Сравнение с пустой строкой не отловит значение из одних пробелов. Используйте выражение вида ВЫРАЗИТЬ(Поле КАК СТРОКА(1)) = "" — если после обрезки до одного символа поле пустое, содержимого фактически нет. Либо комбинируйте условие с ПОДОБНО для отбора строк, состоящих только из пробелов.

Можно ли проверить тип значения составного поля прямо в запросе?

Да. Используйте конструкцию ВЫБОР КОГДА Поле ССЫЛКА Справочник.Контрагенты ТОГДА ... — оператор ССЫЛКА проверяет, что значение является ссылкой указанного типа. Это стандартный способ различать типы в полях составного типа без выгрузки данных в код.

Почему условие по полю правой таблицы «ломает» левое соединение?

Условие в секции ГДЕ применяется уже к результату соединения. Для строк, где правая таблица дала NULL, сравнение с конкретным значением не выполняется, и такие строки отбрасываются — соединение ведёт себя как внутреннее. Чтобы сохранить все строки левой таблицы, перенесите условие в секцию ПО самого соединения.

Как проверить дату на пустое значение в запросе?

Пустая дата в 1С хранится как начало отсчёта, поэтому проверка выглядит так: Поле = ДАТАВРЕМЯ(1,1,1). Для незаполненной даты в составе NULL после соединения дополнительно нужна проверка ЕСТЬ NULL — одно сравнение оба случая не покрывает.

Что быстрее: В ИЕРАРХИИ или проверка через Родитель?

Оператор В ИЕРАРХИИ корректнее и обычно производительнее: он охватывает все уровни вложенности и использует внутренние механизмы платформы. Проверка через Родитель.Родитель.Родитель ограничена фиксированной глубиной и требует переписывания запроса при изменении структуры справочника.

Итог

Что важно запомнить

NULL проверяется через ЕСТЬ NULL, пустая ссылка — через ЗНАЧЕНИЕ(...ПустаяСсылка), пустая дата — через ДАТАВРЕМЯ(1,1,1). Для замены NULL используйте ЕСТЬNULL(), для вычисляемых признаков — ВЫБОР, для списков и иерархии — В и В ИЕРАРХИИ. Перед написанием условия посмотрите фактические значения поля в консоли запросов.