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

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

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

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

Проверка заполненности — одна из самых частых задач при написании запросов в 1С. Незаполненный реквизит может содержать NULL, пустую ссылку, пустую строку, значение НЕОПРЕДЕЛЕНО или дату '00010101' — и для каждого случая нужен свой способ проверки. Универсального оператора «заполнено» в языке запросов нет, поэтому разработчик должен понимать, какое именно «пустое» значение хранится в поле.

Ошибки в таких проверках приводят к тому, что в отчёт попадают лишние строки или, наоборот, теряются нужные данные. Особенно коварны составные типы реквизитов и соединения таблиц, где NULL появляется неявно. Ниже разобраны все основные способы проверки с примерами кода и указанием границ применимости каждого.

Почему значение NULL и как его проверить через ЕСТЬ NULL

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

Для проверки используется специальный оператор:

ВЫБРАТЬ

Заказы.Ссылка КАК Заказ,

Оплаты.Сумма КАК СуммаОплаты

ИЗ

Документ.ЗаказКлиента КАК Заказы

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

ПО Заказы.Ссылка = Оплаты.Заказ

ГДЕ

Оплаты.Сумма ЕСТЬ NULL

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

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

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

ВЫБРАТЬ

Реализация.Ссылка,

Реализация.Контрагент

ИЗ

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

ГДЕ

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

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

Альтернатива без явного указания типа — передача пустой ссылки через параметр: ГДЕ Поле = &ПустаяСсылка, где параметр устанавливается из кода как Справочники.Контрагенты.ПустаяСсылка(). Это удобно, когда тип реквизита заранее неизвестен или запрос строится динамически.

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

Примитивные типы в 1С не бывают NULL в собственных реквизитах таблицы — у них всегда есть значение по умолчанию. Поэтому «незаполненность» проверяется сравнением с этим значением:

  • строка неограниченной или фиксированной длины: Поле = "" (пустая строка);
  • число: Поле = 0;
  • дата: Поле = ДАТАВРЕМЯ(1, 1, 1);
  • булево: Поле = ЛОЖЬ.

Со строками есть нюанс: реквизит может содержать пробелы или неразрывные пробелы, которые визуально выглядят как пустота, но сравнение с "" не проходят. В запросе нет функции сокращения пробелов, поэтому такие случаи надёжнее обрабатывать в коде после выборки через СокрЛП() либо очищать данные регламентной обработкой.

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

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

Значение НЕОПРЕДЕЛЕНО и составные типы реквизитов

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

ГДЕ

Реквизит = НЕОПРЕДЕЛЕНО

ИЛИ Реквизит ЕСТЬ NULL

Составной реквизит — главный источник сложностей. Например, поле «Договор» типа «СправочникСсылка.Договоры, Строка(50)» может быть пустой ссылкой, пустой строкой, NULL или НЕОПРЕДЕЛЕНО. Проверка заполненности для него выглядит так:

ГДЕ

НЕ (Поле ЕСТЬ NULL)

И Поле <> НЕОПРЕДЕЛЕНО

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

И Поле <> ""

Дополнительный приём — проверка фактического типа значения через оператор ВЫРАЗИТЬ(Поле КАК Справочник.Договоры): если реальный тип другой, результат приведения будет NULL, и это можно использовать как фильтр по типу.

Маршрут решения

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

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

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

В схеме компоновки данных те же операторы доступны в тексте запроса набора данных, но дополнительно проверку можно вынести в отбор СКД. Для этого в настройках используется вид сравнения «Заполнено» / «Не заполнено» — система сама строит корректное условие с учётом типа поля, что избавляет от ручного перечисления пустых значений.

В динамических списках аналогичный отбор доступен пользователю через «Ещё — Настроить список». Если вы разрабатываете произвольный запрос для динамического списка, учитывайте, что отбор «Заполнено» платформа добавляет поверх вашего текста, поэтому не дублируйте такую проверку жёстко в секции ГДЕ без необходимости — это ограничит гибкость настройки.

При передаче условий через параметры помните: параметр не может быть «не задан». Если параметр-отбор опционален, используйте шаблон ГДЕ (&Параметр = НЕОПРЕДЕЛЕНО ИЛИ Поле = &Параметр) и передавайте НЕОПРЕДЕЛЕНО, когда фильтр не нужен.

В отчётах на СКД отбор «Заполнено» надёжнее ручных условий в тексте запроса: платформа учитывает составной тип поля автоматически. Ручные проверки оставляйте для случаев, где логика сложнее простого отбора.
ПЗ
Практическое замечание

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

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

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

Если проверка заполненности нужна для массовой обработки данных (например, найти и заполнить пустые реквизиты), сначала выполните запрос в режиме только чтения и оцените количество строк. Изменение данных делайте на копии базы или в тестовом контуре: ошибочное условие в цикле обработки может затронуть тысячи объектов, и откат без резервной копии невозможен.

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

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

Запрос с условием ЕСТЬ NULL на левом соединении
Норма

Возвращаются только строки без пары в присоединяемой таблице

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

Пустой результат при заведомо существующих незакрытых строках — проверьте условие соединения

Отбор по пустой ссылке
Норма

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

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

Часть «пустых» объектов не найдена — реквизит составного типа, добавьте проверки на НЕОПРЕДЕЛЕНО и пустую строку

Условие в секции ГДЕ
Норма

Запрос выполняется быстро, план использует индекс

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

Резкое замедление — вероятно, поле обёрнуто в функцию, перепишите прямым сравнением

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

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

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

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

В языке запросов нет функции сокращения пробелов, поэтому полноценно отсечь строки из одних пробелов можно только в коде после выборки через СокрЛП. В самом запросе доступна проверка Поле <> "", которая отлавливает только полностью пустые строки.

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

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

Можно ли использовать ЕСТЬNULL в секции ГДЕ для фильтрации?

Технически можно, например ГДЕ ЕСТЬNULL(Поле, 0) = 0, но это нежелательно: оборачивание поля в функцию обычно мешает использованию индекса и замедляет запрос на больших таблицах. Для фильтрации пишите прямое условие Поле ЕСТЬ NULL ИЛИ Поле = 0, а ЕСТЬNULL оставьте для выборки и подстановки значений по умолчанию.

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

Откройте настройку списка («Ещё — Настроить список»), добавьте отбор по нужному полю и выберите вид сравнения «Не заполнено». Платформа сама построит корректное условие с учётом типа реквизита, включая составные типы, без изменения текста запроса списка.

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

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

Итог

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

Заполненность в запросе 1С проверяется по типу поля: NULL — оператором ЕСТЬ NULL, пустая ссылка — сравнением с ЗНАЧЕНИЕ(...ПустаяСсылка), строка — с "", дата — с ДАТАВРЕМЯ(1,1,1), НЕОПРЕДЕЛЕНО — прямым сравнением. Составные типы требуют комбинации проверок, а в СКД и динамических списках удобнее встроенный вид сравнения «Заполнено». Условия пишите прямым сравнением поля без обёрток в функции, чтобы сохранить индексацию.