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

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

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

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

Задача «выбрать только те записи, где реквизит заполнен» возникает в запросах 1С постоянно: отбор контрагентов с указанным ИНН, документы с заполненным ответственным, товары с назначенной группой. Проблема в том, что «пустота» в 1С неоднородна: пустая ссылка, NULL, пустая строка, пустая дата и неопределённое значение проверяются по-разному, и универсального оператора «Заполнено» в языке запросов нет.

В модуле объекта или общем модуле для этой цели служит функция ЗначениеЗаполнено(), но внутри текста запроса она недоступна. В запросе приходится сравнивать поле с конкретным «пустым» значением соответствующего типа: ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка), пустой строкой, датой '00010101' или проверять на NULL через ЕСТЬ NULL.

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

Какие виды «пустоты» существуют в запросах 1С

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

Для ссылочных типов (справочники, документы, перечисления, планы счетов) пустое значение — это пустая ссылка соответствующего типа. Для строк — строка нулевой длины, для чисел — ноль, для дат — значение 01.01.0001, для булево — Ложь. Отдельный случай — NULL: он появляется не из самих данных, а из левых и правых соединений, когда для записи основной таблицы не нашлось пары в присоединяемой.

Особая ситуация — реквизиты составного типа, например «Покупатель» с типом «СправочникСсылка.Контрагенты, СправочникСсылка.ФизическиеЛица». Такое поле может содержать пустую ссылку одного из типов или NULL, и простое сравнение с одной пустой ссылкой не покроет все случаи.

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

Основной способ проверить заполненность ссылочного реквизита — сравнить его с пустой ссылкой через оператор ЗНАЧЕНИЕ(). Условие «заполнено» записывается как неравенство:

ГДЕ

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

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

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

Проверка примитивных типов: строка, число, дата

Строковые реквизиты (ИНН, комментарий, адрес) считаются заполненными, если не равны пустой строке: ГДЕ Контрагенты.ИНН <> "". Учтите, что строка из одних пробелов формально заполнена — такие значения условие пропустит. Если нужно отсеять и их, используйте ПОДСТРОКА с проверкой длины либо вычищайте данные на этапе записи.

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

Даты сравниваются с пустой датой через литерал: ГДЕ Документ.ДатаОплаты <> ДАТАВРЕМЯ(1, 1, 1). Функция ДАТАВРЕМЯ(1,1,1) формирует дату 01.01.0001 00:00:00 — именно она является «пустой» датой в 1С.

Сравнение способов проверки

Сравнение с пустой ссылкой

Для ссылочных типов. Точный и быстрый способ, но требует знать конкретный тип реквизита.

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

Для строк, чисел и дат. Простой синтаксис, но ноль и пустая строка могут быть осмысленными значениями.

ЕСТЬ NULL / НЕ ... ЕСТЬ NULL

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

ЗначениеЗаполнено() вне запроса

Для проверки параметров до выполнения запроса. Внутри текста запроса недоступна.

Проверка на NULL при соединениях и составных типах

NULL нельзя сравнивать через = или <> — любое сравнение с NULL даёт не Истину и не Ложь, а неопределённый результат, и строка просто выпадет из выборки. Для NULL существуют специальные операторы ЕСТЬ NULL и НЕ ... ЕСТЬ NULL:

ГДЕ

НЕ Остатки.КоличествоОстаток ЕСТЬ NULL

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

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

Типичные ошибки
01
Сравнение с NULL через = или &lt;&gt; — строка молча выпадает из результата, итоги не сходятся без видимой причины.
02
Проверка составного поля одной пустой ссылкой — записи с пустой ссылкой другого типа или NULL проходят фильтр.
03
Использование ЗначениеЗаполнено() внутри текста запроса — функция там недоступна, запрос не выполнится.
04
Отбор строк по &lt;&gt; "" без учёта строк из пробелов — «пустые» по смыслу значения попадают в выборку.

Составные типы и параметры: комбинированные условия

Для реквизита составного типа надёжная проверка заполненности выглядит как комбинация условий по всем возможным пустым состояниям. Например, поле «Контрагент» типа «Контрагенты или ФизическиеЛица»:

ГДЕ

НЕ Документ.Контрагент ЕСТЬ NULL

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

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

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

ГДЕ

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

ИЛИ Продажи.Контрагент = &Контрагент)

Здесь проверка «параметр заполнен» выполняется сравнением параметра с пустой ссылкой. Перед выполнением запроса тот же параметр удобно проверять в коде через ЗначениеЗаполнено(Контрагент) и вообще не передавать лишние условия, формируя текст запроса динамически или используя СКД с необязательными отборами — это читаемее и быстрее.

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

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

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

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

Ещё один ориентир — логика итогов. Если после добавления условия заполненности суммы в отчёте изменились неожиданно, проверьте, не отсекаются ли записи с NULL из соединений: это самая частая причина «потерянных» строк.

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

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

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

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

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

Пропали записи с заполненными реквизитами — вероятно, сработал NULL из соединения

Поле из присоединённой таблицы в выборке
Норма

NULL встречается только там, где нет связанной записи

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

NULL на месте существующих данных — ошибка в условии соединения

Составное поле
Норма

Отсекаются пустые ссылки всех типов и NULL

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

Проходят пустые ссылки «второго» типа

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

Можно ли использовать ЗначениеЗаполнено() прямо в тексте запроса?

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

Почему условие «Поле <> ПустаяСсылка» убирает строки после левого соединения?

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

Как проверить заполненность поля типа «ЛюбаяСсылка»?

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

Чем проверка в запросе отличается от отбора в СКД?

В СКД необязательные отборы добавляются автоматически только когда пользователь задал значение, поэтому шаблон «параметр пуст ИЛИ поле = параметр» там обычно не нужен. Если отбор всё же описан в тексте запроса СКД, действуют те же правила сравнения с пустыми значениями.

Строка с пробелами считается заполненной — как её отсечь?

Сравнение с "" такую строку пропустит. Варианты: проверять длину через выражение с ПОДСТРОКА, либо надёжнее — очищать данные при записи (сокращение пробелов в обработчиках), чтобы в базе не оставалось «пустых по смыслу» строк.

Ноль в числовом поле — это «не заполнено»?

Технически да: незаполненное число хранится как 0. Но по бизнес-логике ноль может быть осмысленным значением (нулевая цена, нулевой остаток). Если различие важно, вводите отдельный признак заполненности, а не полагайтесь на сравнение с нулём.

Итог

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

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