Разработка и Конфигурация · 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), это каноническая форма записи незаполненной даты в запросах.
Если поле составного типа и может содержать ссылки разных видов, проверка только на пустую ссылку одного вида недостаточна. Надёжнее комбинировать условия или использовать функцию ВЫРАЗИТЬ для приведения типа перед сравнением.
Проверка условий в выборке: оператор ВЫБОР
Когда результат проверки нужно вывести как колонку (например, признак «Есть остаток / Нет остатка»), используется оператор ВЫБОР — аналог CASE из SQL:
ВЫБРАТЬ
Номенклатура.Ссылка КАК Товар,
ВЫБОР
КОГДА Остатки.КоличествоОстаток ЕСТЬ NULL
ТОГДА "Нет на складе"
КОГДА Остатки.КоличествоОстаток = 0
ТОГДА "Нулевой остаток"
ИНАЧЕ "В наличии"
КОНЕЦ КАК Статус
ИЗ
Справочник.Номенклатура КАК Номенклатура
ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки КАК Остатки
ПО Номенклатура.Ссылка = Остатки.Номенклатура
Ветки КОГДА проверяются сверху вниз, срабатывает первая истинная. Ветка ИНАЧЕ необязательна, но без неё при невыполнении всех условий результатом будет NULL — это частый источник неожиданных пустых колонок в отчётах. Все ветки должны возвращать значения совместимых типов.
Проверка вхождения: В, В ИЕРАРХИИ и ПОДОБНО
Проверка по списку значений
Оператор В проверяет вхождение значения в список, переданный параметром, или в результат подзапроса. В параметр удобно передавать массив или список значений из кода:
ГДЕ
Номенклатура.Ссылка В (&СписокТоваров)
Обратное условие — НЕ ... В (...). Учтите, что если в списке встретится NULL, поведение отрицания может отличаться от ожидаемого — список лучше формировать заранее очищенным.
Проверка по иерархии справочника
Для иерархических справочников есть специальный оператор В ИЕРАРХИИ, который выбирает элементы самой группы и всех вложенных уровней без рекурсивных соединений:
ГДЕ
Номенклатура.Ссылка В ИЕРАРХИИ (&ГруппаТоваров)
В параметр можно передать одну группу или список групп. Это самый производительный и читаемый способ проверки принадлежности к ветке дерева; самодельные проверки через Родитель охватывают только фиксированное число уровней и ломаются при изменении глубины иерархии.
Проверка строки по шаблону
Оператор ПОДОБНО проверяет строку по шаблону: символ % — любая последовательность символов, _ — ровно один символ. Например, поиск по фрагменту наименования:
ГДЕ
Номенклатура.Наименование ПОДОБНО "%кабель%"
Если в искомом тексте сами встречаются символы % или _, их нужно экранировать через ключевое слово СПЕЦСИМВОЛ. Учтите, что поиск по шаблону с ведущим % не использует индексы и на больших таблицах выполняется медленно.
Сравнение способов проверки
Единственный корректный способ проверить отсутствие значения после соединения; не работает для пустых ссылок и строк
Проверка незаполненного ссылочного реквизита; требует указания конкретного типа
Проверка вхождения в список или ветку иерархии; список передаётся параметром
Поиск строк по шаблону; медленный на больших таблицах при ведущем %
Проверка результата запроса в коде: Пустой() и типы значений
После выполнения запроса часто нужно проверить, вернул ли он строки. Для этого у объекта РезультатЗапроса есть метод Пустой(). Проверять результат через попытку обхода выборки менее читаемо:
РезультатЗапроса = Запрос.Выполнить();
Если РезультатЗапроса.Пустой() Тогда
Возврат;
КонецЕсли;
Выборка = РезультатЗапроса.Выбрать();
Пока Выборка.Следующий() Цикл
// обработка строки
КонецЦикла;
Если из запроса нужно одно значение, типичный приём — выгрузить результат в таблицу значений и проверить её количество: Если ТаблицаРезультата.Количество() = 0 Тогда .... Для проверки типа значения поля в коде используется функция ТипЗнч() совместно с Тип(), а внутри самого запроса — оператор сравнения с ТИП() через конструкцию ВЫБОР КОГДА Поле ССЫЛКА Справочник.Контрагенты ....
- 1Откройте консоль запросов и выполните запрос без условия ГДЕ — убедитесь, что данные вообще выбираются
- 2Добавьте проверяемое поле в список выборки и посмотрите его фактические значения: NULL, пустая ссылка или заполненное значение
- 3Подберите правильную конструкцию: ЕСТЬ NULL для NULL, ЗНАЧЕНИЕ(...ПустаяСсылка) для пустой ссылки
- 4Добавьте условие и сравните количество строк до и после — оно должно измениться ожидаемым образом
- 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(), для вычисляемых признаков — ВЫБОР, для списков и иерархии — В и В ИЕРАРХИИ. Перед написанием условия посмотрите фактические значения поля в консоли запросов.