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