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

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

Как в запросе 1С проверить, заполнен ли реквизит

Способы проверки заполненности реквизита в запросе 1С: сравнение с NULL, пустыми ссылками и строками, функция ЕСТЬNULL, типичные ошибки и примеры кода.

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

Главная сложность в том, что «незаполненный» реквизит в 1С может храниться по-разному: как NULL, как пустая ссылка конкретного типа, как пустая строка, как ноль или как значение по умолчанию для составного типа. Универсального условия «пусто / не пусто» в языке запросов нет, поэтому проверку нужно строить с учётом типа данных поля.

Ниже разобраны рабочие способы проверки для каждого типа реквизита, примеры условий в секции ГДЕ, использование функции ЕСТЬNULL и типичные ошибки, из-за которых запрос возвращает неверный результат.

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

В базе данных 1С пустое значение реквизита зависит от его типа. Ссылка на справочник, который не заполнен, хранится как пустая ссылка этого справочника — это не NULL и не пустая строка. Строковый реквизит без значения — это строка нулевой длины. Числовой — ноль. И только в отдельных случаях (соединения таблиц, необязательные измерения в виртуальных таблицах) в поле действительно оказывается NULL.

Из-за этого условие Реквизит = NULL для обычного реквизита документа почти никогда не сработает, а сравнение ссылки с пустой строкой вообще не имеет смысла. Прежде чем писать условие, откройте конфигуратор и посмотрите точный тип реквизита: простой он или составной, ссылочный или примитивный.

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

Для реквизитов типа «СправочникСсылка», «ДокументСсылка», «ПеречислениеСсылка» и подобных правильная проверка — сравнение со значением пустой ссылки через функцию ЗНАЧЕНИЕ(). Например, выбрать документы, где не указан контрагент:

ВЫБРАТЬ

РеализацияТоваров.Ссылка КАК Документ

ИЗ

Документ.РеализацияТоваровУслуг КАК РеализацияТоваров

ГДЕ

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

Обратное условие — «реквизит заполнен» — записывается через знак неравенства: РеализацияТоваров.Контрагент <> ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка). Вместо ЗНАЧЕНИЕ() допустимо передать пустую ссылку параметром, получив её в коде через Справочники.Контрагенты.ПустаяСсылка(), — результат будет тот же.

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

Проверка строк, чисел и дат

Строковые реквизиты проверяются сравнением с пустой строкой: Номенклатура.Артикул = "". Учтите, что строка из одних пробелов формально заполнена — условие её не отфильтрует. Если такие значения возможны, стоит дополнительно анализировать данные, потому что функции сокращения пробелов (СРОКП) в языке запросов нет.

Числовой реквизит без значения равен нулю, поэтому условие выглядит как Документ.Сумма = 0. Здесь есть тонкость: ноль может быть и осмысленным значением (например, бесплатная отгрузка). Если бизнес-логика различает «ноль» и «не заполнено», надёжнее хранить признак заполненности отдельно, потому что в запросе их не отличить.

Пустая дата проверяется сравнением с началом отсчёта: Заказ.ДатаОтгрузки = ДАТАВРЕМЯ(1, 1, 1). Пропуск ведущих нулей в литерале даты допустим, но для читаемости лучше писать полностью.

СсылкаПустая ссылка типа

Сравнение через ЗНАЧЕНИЕ(...ПустаяСсылка)

СтрокаПустая строка

Сравнение с "" (пробелы не считаются пустотой)

Число0

Ноль может быть и осмысленным значением

Дата01.01.0001

Сравнение с ДАТАВРЕМЯ(1,1,1)

Поле из соединенияNULL

Проверка через ЕСТЬ NULL или ЕСТЬNULL()

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

NULL появляется в результате левых соединений, при обращении к полям через разыменование отсутствующей ссылки, в итогах и виртуальных таблицах. Проверка выполняется оператором ЕСТЬ NULL:

ВЫБРАТЬ

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

Цены.Цена КАК Цена

ИЗ

РегистрСведений.Товары КАК Товары

ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.Цены КАК Цены

ПО Товары.Номенклатура = Цены.Номенклатура

ГДЕ

Цены.Цена ЕСТЬ NULL

Функция ЕСТЬNULL(Поле, ЗначениеПоУмолчанию) подменяет NULL указанным значением и удобна, когда нужно не отфильтровать, а вывести понятный результат: ЕСТЬNULL(Цены.Цена, 0) КАК Цена. С её помощью можно и проверить заполненность ссылочного поля, пришедшего из соединения: ЕСТЬNULL(Свойства.Ответственный, ЗНАЧЕНИЕ(Справочник.Пользователи.ПустаяСсылка)) = ЗНАЧЕНИЕ(Справочник.Пользователи.ПустаяСсылка).

Важно помнить: сравнение Поле = NULL в запросе не работает так, как ожидается. Любое сравнение с NULL даёт неопределённый результат, и строка в выборку не попадёт. Только конструкция ЕСТЬ NULL / НЕ ЕСТЬ NULL корректна.

Типичные ошибки
01
Сравнение Поле = NULL вместо ЕСТЬ NULL — условие никогда не срабатывает, строки теряются без предупреждения
02
Проверка ссылки на пустую строку или на NULL вместо пустой ссылки — фильтр молча не работает
03
Проверка только одного типа у составного реквизита — часть пустых значений проходит в отчёт
04
Сравнение строки с "", когда в данных есть строки из пробелов — такие записи считаются заполненными
05
Использование ЕСТЬNULL без учёта типа подставляемого значения — ошибка несоответствия типов при выполнении

Составные типы и поля через точку

Если реквизит имеет составной тип (например, «Покупатель» — справочник «Контрагенты» или «ФизическиеЛица»), пустое значение может храниться как пустая ссылка любого из входящих в тип видов либо как неопределённое значение составного типа. Надёжный вариант — перечислить все варианты пустых ссылок через ИЛИ или привести поле к одному типу функцией ВЫРАЗИТЬ и сравнить с его пустой ссылкой:

ГДЕ

ВЫРАЗИТЬ(Заказ.Покупатель КАК Справочник.Контрагенты)

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

Отдельная ловушка — обращение к реквизиту через точку: Документ.Контрагент.ИНН. Если контрагент не заполнен, разыменование вернёт NULL, а не пустую строку. Поэтому условие Документ.Контрагент.ИНН = "" не найдёт документы без контрагента. Правильно проверять либо саму ссылку, либо использовать ЕСТЬNULL на разыменованное поле.

Перед написанием условия выполните запрос без фильтра и посмотрите, что реально лежит в поле у «пустых» записей: пустая ссылка, NULL или пустая строка. Одна проверка в консоли запросов экономит больше времени, чем отладка готового отчёта.
ПЗ
Практическое замечание

Пошаговый порядок написания проверки

Чтобы условие сработало с первого раза, удобно действовать по фиксированной последовательности: определить тип, выбрать способ сравнения, проверить на тестовых данных. Ниже — краткий алгоритм и маршрут выбора для типовых ситуаций.

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

Как выбрать проверку

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

Проверка результата и границы безопасной работы

После написания условия обязательно проверьте его на данных, где результат известен заранее. Возьмите несколько записей с гарантированно пустым и гарантированно заполненным реквизитом и убедитесь, что фильтр делит их правильно. Особенно внимательно проверяйте запросы с соединениями: добавление ЕСТЬNULL в секцию ГДЕ может неявно превратить левое соединение во внутреннее и изменить состав выборки.

Отладку проводите в консоли запросов на копии базы или в тестовом контуре. Сам запрос на выборку данных не меняет, но условия заполненности часто используются в обработках, которые затем массово записывают или удаляют объекты — там цена ошибки уже высокая. Перед запуском такой обработки в рабочей базе сверьте количество отобранных записей с ожидаемым и сделайте резервную копию.

Контрольные точки

Как проверить результат

Записи с пустым реквизитом в выборке
Норма

Отбираются ровно те записи, где реквизит визуально не заполнен

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

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

Записи из левого соединения без совпадений
Норма

Строки с NULL обработаны через ЕСТЬ NULL или ЕСТЬNULL

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

Строки без совпадений пропали из результата

Количество строк до и после добавления условия
Норма

Изменение соответствует числу пустых значений в данных

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

Количество изменилось резко и необъяснимо

Частые вопросы

Можно ли проверить заполненность реквизита любого типа одним универсальным условием?

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

Почему условие «Реквизит = NULL» не находит записи?

Потому что любое сравнение с NULL даёт неопределённый результат, а не истину. Для проверки на NULL существует специальный оператор ЕСТЬ NULL (и его отрицание НЕ ЕСТЬ NULL). Замените сравнение на эту конструкцию.

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

Используйте обратные условия: неравенство пустой ссылке (<> ЗНАЧЕНИЕ(...ПустаяСсылка)), неравенство пустой строке, оператор НЕ ЕСТЬ NULL. Для составных типов все варианты пустых значений нужно исключить одновременно.

Чем ЕСТЬNULL отличается от ЕСТЬ NULL?

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

Почему проверка реквизита через точку (Контрагент.ИНН) не находит документы без контрагента?

При разыменовании незаполненной ссылки результатом будет NULL, а не пустая строка. Условие Контрагент.ИНН = "" такие записи пропустит. Проверяйте саму ссылку на пустое значение или оберните разыменованное поле в ЕСТЬNULL.

Итог

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

Способ проверки заполненности зависит от типа реквизита: ссылки сравнивают с ЗНАЧЕНИЕ(...ПустаяСсылка), строки — с "", NULL — оператором ЕСТЬ NULL. Для составных типов и полей через точку используйте ВЫРАЗИТЬ и ЕСТЬNULL. Всегда проверяйте условие на данных с известным результатом.