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

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

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

Способы проверки заполненности в запросе 1С: сравнение с пустой ссылкой, NULL, пустой строкой и датой. Примеры кода, типичные ошибки и рекомендации.

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

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

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

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

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

Отдельный случай — NULL. Это отсутствие значения как такового. NULL появляется в двух ситуациях: когда реквизит составного типа не заполнен (хранится NULL, а не пустая ссылка) и когда поле получено через левое соединение, для которого не нашлось пары. Главная ловушка: NULL не равен ничему, даже самому себе. Сравнение «Поле = NULL» всегда даёт ложь, поэтому для NULL существуют отдельные операторы IS NULL и IS NOT NULL.

Проверка ссылочных полей через ЗНАЧЕНИЕ

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

ВЫБРАТЬ

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

ИЗ

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

ГДЕ

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

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

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

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

Примитивные типы сравниваются с литералами напрямую. Пустая строка — это две кавычки подряд, пустая дата задаётся функцией ДАТАВРЕМЯ(1,1,1), число сравнивается с нулём:

ГДЕ

НЕ Сотрудники.ИНН = ""

И НЕ Сотрудники.ДатаРождения = ДАТАВРЕМЯ(1, 1, 1)

И НЕ Сотрудники.Оклад = 0

У строк есть нюанс с пробелами. Реквизит, заполненный одним или несколькими пробелами, формально не пуст — сравнение с "" его не отловит. Если такая ситуация возможна (например, данные загружались из внешних источников), проверку делают через ПОДОБНО: НЕ (Поле ПОДОБНО "%[^ ]%") — условие истинно, когда в строке есть хотя бы один непробельный символ. Учтите, что для строк неограниченной длины оператор ПОДОБНО может работать с ограничениями в зависимости от СУБД.

Для булевых полей «незаполненности» как таковой нет: значение по умолчанию — Ложь, и отличить «специально сняли флажок» от «не трогали» в запросе невозможно. Если бизнес-логике нужно третье состояние, его моделируют отдельным реквизитом или перечислением, а не булево.

Работа с NULL: IS NULL, IS NOT NULL и ЕСТЬNULL

Когда поле может содержать NULL — из-за левого соединения или незаполненного составного реквизита — обычные сравнения бессильны. Условие «Поле = ЗНАЧЕНИЕ(...ПустаяСсылка)» для NULL-строки даст не истину и не ложь, а NULL, и строка просто выпадет из результата. Правильные проверки выглядят так:

ГДЕ

Остатки.Склад ЕСТЬ NULL -- склад не указан / нет пары в соединении

ГДЕ

Остатки.Склад ЕСТЬ НЕ NULL -- значение присутствует

Второй инструмент — функция ЕСТЬNULL(Поле, ЗначениеПоУмолчанию). Она подменяет NULL указанным значением, после чего можно использовать обычное сравнение. Это особенно удобно, когда нужно объединить проверку NULL и пустой ссылки в одном условии:

ГДЕ

ЕСТЬNULL(Товары.СтавкаНДС, ЗНАЧЕНИЕ(Перечисление.СтавкиНДС.ПустаяСсылка))

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

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

Особенности реквизитов составного типа

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

Надёжный шаблон для составного поля — комбинация IS NULL и сравнений со всеми возможными пустыми ссылками, либо универсальный приём с ЕСТЬNULL:

ГДЕ

Заказ.Покупатель ЕСТЬ NULL

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

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

Ещё одна ловушка составных типов — «битые» ссылки и ссылки типа, который позже убрали из состава. Такие значения не равны ни одной из перечисленных пустых ссылок и не являются NULL. Если в выборку попадают неожиданные записи, проверьте фактический тип значения через запрос к данным или функцию ВЫРАЗИТЬ — приведение к несоответствующему типу даст NULL.

Типичные ошибки
01
Сравнение с NULL через = или &lt;&gt; — условие никогда не сработает, строки молча теряются
02
Проверка составного реквизита только через одну пустую ссылку — незаполненные значения (NULL) не находятся
03
Сравнение строки с NULL вместо пустой строки — строковые реквизиты хранят "", а не NULL
04
Забытый ЕСТЬNULL после левого соединения — строки без пары выпадают из результата
05
Проверка даты через = НЕОПРЕДЕЛЕНО — в языке запросов нет НЕОПРЕДЕЛЕНО, нужна ДАТАВРЕМЯ(1,1,1)

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

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

Если отбор нужен программно, его добавляют в настройки компоновщика с видом сравнения ВидСравненияКомпоновкиДанных.Заполнено. Для динамических списков аналогичный отбор устанавливается через свойство Отбор элемента формы. Такой подход предпочтительнее жёсткого условия в тексте запроса: фильтр можно включать и выключать без изменения кода.

При этом условия в секции ГДЕ самого запроса всё равно нужны, когда незаполненные записи заведомо не должны участвовать в выборке — например, документы без контрагента не должны попадать в расчёт задолженности. Правило простое: бизнес-ограничение — в запрос, пользовательский фильтр — в отбор СКД.

Сравнение вариантов

Условие в секции ГДЕ

Жёсткое бизнес-правило: записи без значения не должны попадать в результат никогда. Минус — нельзя отключить без правки кода.

Отбор СКД «Заполнено / Не заполнено»

Гибкий фильтр для отчётов, корректно обрабатывает NULL и пустые значения. Подходит, когда решение о фильтрации принимает пользователь.

ЕСТЬNULL в вычисляемом поле

Когда пустое значение нужно подменить (например, вывести "Не указан" или 0 для расчётов), а не отфильтровать строку.

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

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

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

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

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

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

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

Разница равна числу записей с незаполненным полем

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

Строк пропало больше или меньше — вероятен NULL из соединения

Значения проверяемого поля в выборке
Норма

Видны только ожидаемые варианты (NULL, пустая ссылка, заполнено)

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

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

Поведение в отчёте СКД
Норма

Результат совпадает с консолью запросов

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

Расхождение — проверять отборы в настройках и код формирования

Часто задаваемые вопросы

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

Полностью универсального оператора нет. Ближайший вариант — вид сравнения «Заполнено / Не заполнено» в отборах СКД, который платформа сама разворачивает в корректное условие под тип поля. В тексте запроса универсальную проверку можно собрать только комбинацией IS NULL и сравнений со значениями по умолчанию для каждого возможного типа.

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

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

Почему условие «Поле = НЕОПРЕДЕЛЕНО» не работает в запросе?

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

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

Табличная часть — это отдельная таблица, поэтому проверка сводится к наличию строк: левое соединение документа с его табличной частью и условие «ТабличнаяЧасть.НомерСтроки ЕСТЬ NULL» отберёт документы без строк. Обратное условие «ЕСТЬ НЕ NULL» — документы, где табличная часть заполнена хотя бы одной строкой.

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

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

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

Прямого сравнения для «только пробелы» нет. Используйте ПОДОБНО с шаблоном «%[^ ]%»: если строка соответствует шаблону, в ней есть хотя бы один непробельный символ. Условие «НЕ (Поле ПОДОБНО "%[^ ]%")» отберёт и пустые строки, и строки из одних пробелов. Учтите возможные ограничения ПОДОБНО для строк неограниченной длины.

Итог

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

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