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

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

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

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

Проверка значения на заполненность — одна из самых частых задач при написании запросов в 1С. Проблема в том, что «незаполненное» значение в базе данных может храниться по-разному: как NULL, как пустая ссылка, как пустая строка, как дата '00010101' или как ноль — и для каждого варианта нужен свой способ проверки.

Ошибка в такой проверке приводит к тому, что в выборку попадают лишние строки или, наоборот, теряются нужные документы. Особенно коварен NULL: сравнение Реквизит = NULL никогда не вернёт истину, и запрос молча отфильтрует данные не так, как ожидал разработчик.

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

Как 1С хранит незаполненные значения

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

Второй вид — значение по умолчанию для типа: пустая строка "" для строк, 0 для чисел, дата '0001-01-01' для дат, ЛОЖЬ для булево. Третий — пустая ссылка: объект ссылочного типа, у которого задан тип, но не задан сам объект. Четвёртый — Неопределено, но в запросах оно не используется: это понятие встроенного языка, а не языка запросов.

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

Единственный корректный способ проверить NULL — операторы ЕСТЬ NULL и ЕСТЬ НЕ NULL (в английском синтаксисе IS NULL / IS NOT NULL). Условие ГДЕ Товары.Количество ЕСТЬ NULL выберет строки, где значение отсутствует вовсе.

Типичный сценарий — левое соединение. Если соединить документы с регистром оплат, то у неоплаченных документов поля регистра будут NULL. Проверка Оплаты.Сумма ЕСТЬ NULL надёжно выберет именно неоплаченные документы, тогда как сравнение Оплаты.Сумма = 0 их пропустит, потому что NULL не равен нулю.

bsl
ВЫБРАТЬ
	Реализация.Ссылка КАК Документ,
	Оплаты.Сумма КАК СуммаОплаты
ИЗ
	Документ.РеализацияТоваровУслуг КАК Реализация
		ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.Оплаты КАК Оплаты
		ПО Реализация.Ссылка = Оплаты.Документ
ГДЕ
	Оплаты.Сумма ЕСТЬ NULL

Проверка пустых ссылок и примитивных типов

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

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

Функция ЕСТЬNULL — универсальная замена NULL

Функция ЕСТЬNULL(Поле, ЗначениеПоУмолчанию) возвращает значение поля, а если оно NULL — подставляет указанное значение. Это позволяет свести проверку к обычному сравнению: ГДЕ ЕСТЬNULL(Оплаты.Сумма, 0) = 0 выберет и строки с NULL, и строки с нулевой суммой.

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

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

Проверка через ВЫБОР и вывод признака заполненности

Иногда нужно не отфильтровать записи, а показать в результате признак «заполнено / не заполнено». Для этого используется конструкция ВЫБОР КОГДА ... ТОГДА ... ИНАЧЕ ... КОНЕЦ. Например, в отчёте можно вывести колонку-флаг: ВЫБОР КОГДА Заказы.Менеджер = ЗНАЧЕНИЕ(Справочник.Пользователи.ПустаяСсылка) ТОГДА ИСТИНА ИНАЧЕ ЛОЖЬ КОНЕЦ КАК МенеджерНеУказан.

Такой подход удобен в СКД и динамических списках: пользователь видит проблемные строки и может отсортировать или отфильтровать их уже на форме. Это безопаснее, чем жёсткий отбор в запросе, когда часть данных просто исчезает из выборки.

Особые случаи: иерархия, строки с пробелами, составные типы

Для иерархических справочников проверка «группа или элемент» выполняется через ЭтоГруппа в запросах по таблице справочника, но к заполненности это отношения не имеет — важно не путать пустую ссылку с группой. Группа — вполне заполненное значение.

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

Составной реквизит требует комбинированного условия. Например, реквизит «Плательщик» типа «Справочник.Контрагенты или Справочник.Организации» нужно проверять так: Плательщик ЕСТЬ NULL ИЛИ Плательщик = ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка) ИЛИ Плательщик = ЗНАЧЕНИЕ(Справочник.Организации.ПустаяСсылка) ИЛИ Плательщик = НЕОПРЕДЕЛЕНО — последний вариант возможен, если тип значения не входит в составной тип поля.

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

Проверка результата и отладка запроса

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

Полезный приём — временно вывести диагностические колонки: само поле, Поле ЕСТЬ NULL через ВЫБОР и результат ЕСТЬNULL. Так видно, какие именно варианты «пустоты» встречаются в данных, и можно составить условие, покрывающее все случаи.

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

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

Запрос без отбора
Норма

Видны строки с NULL, пустыми ссылками и заполненными значениями

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

Тип поля оказался не тем, что ожидался

Отбор по незаполненным
Норма

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

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

Часть пустых строк не попала — не учтён NULL или другой тип

Отбор по заполненным
Норма

Нет строк с пустыми ссылками и NULL

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

Попали пустые ссылки — проверка шла только на NULL

Итог

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

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

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

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

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

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

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

Чем ЕСТЬNULL лучше проверки ЕСТЬ NULL?

ЕСТЬNULL не проверяет, а устраняет NULL, подставляя значение по умолчанию. Это удобно, когда дальше нужны вычисления, группировки или единое условие для NULL и обычного «пустого» значения. Для простого отбора достаточно ЕСТЬ NULL.

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

Незаполненная дата хранится как 1 января 0001 года. Условие: Поле = ДАТАВРЕМЯ(1,1,1). Если поле пришло из левого соединения, добавьте проверку на NULL или оберните поле в ЕСТЬNULL(Поле, ДАТАВРЕМЯ(1,1,1)).

Работает ли проверка на заполненность в СКД и динамических списках?

Да, все перечисленные конструкции — ЕСТЬ NULL, ЗНАЧЕНИЕ, ЕСТЬNULL, ВЫБОР — поддерживаются в тексте запроса СКД и в произвольном запросе динамического списка. В отборах СКД доступен также стандартный вид сравнения «Заполнено» / «Не заполнено», который платформа сама преобразует в нужное условие.

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

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