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

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

Как в запросе 1С выбрать пустое значение

Как в запросе 1С выбрать пустое значение: ЗНАЧЕНИЕ с пустыми ссылками, NULL, пустая строка и дата. Примеры кода, типичные ошибки и проверка результата.

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

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

Ниже разобраны все основные способы выбора пустых значений в языке запросов 1С: конструкция ЗНАЧЕНИЕ, операторы сравнения, работа с NULL через ЕСТЬ NULL, а также отбор по составным типам, где пустота определяется сложнее.

Что считается пустым значением в запросе 1С

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

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

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

Выбор пустой ссылки через ЗНАЧЕНИЕ

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

ВЫБРАТЬ

Реализация.Ссылка КАК Документ,

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

ИЗ

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

ГДЕ

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

Тип внутри ЗНАЧЕНИЕ должен точно соответствовать типу реквизита. Если реквизит «Склад» имеет тип СправочникСсылка.Склады, то и в условии указывается ЗНАЧЕНИЕ(Справочник.Склады.ПустаяСсылка). Указание другого справочника не даст ошибки исполнения, но сравнение всегда вернёт ЛОЖЬ — и запрос ничего не найдёт.

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

Пустая дата, строка и число

Для примитивных типов конструкция ЗНАЧЕНИЕ не нужна — используются литералы. Пустая дата записывается как ДАТАВРЕМЯ(1,1,1) — это первое января года 1, значение по умолчанию для типа «Дата»:

ВЫБРАТЬ

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

Заказ.ДатаОтгрузки КАК ДатаОтгрузки

ИЗ

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

ГДЕ

Заказ.ДатаОтгрузки = ДАТАВРЕМЯ(1,1,1)

Строковые реквизиты сравниваются с пустой строкой: ГДЕ Номенклатура.Артикул = "". Здесь есть тонкость: если реквизит имеет неограниченную длину или данные вводились с пробелами, строка из одних пробелов не равна пустой строке. Для таких случаев условие дополняют проверкой через ПОДОБНО или приводят данные к чистому виду ещё на этапе ввода.

Числовые реквизиты по умолчанию равны нулю, поэтому отбор незаполненного количества — это ГДЕ ТабЧасть.Количество = 0. Проблема в том, что ноль может быть и осмысленным значением (нулевой остаток — валидные данные). Прежде чем трактовать ноль как «не заполнено», убедитесь, что по логике конфигурации нулевое значение действительно означает отсутствие данных.

Сравнение пустых значений по типам

Ссылочный тип

ЗНАЧЕНИЕ(Справочник.Имя.ПустаяСсылка) — тип должен точно совпадать с типом реквизита

Дата

ДАТАВРЕМЯ(1,1,1) — значение по умолчанию, обратный отбор через оператор <>

Строка

"" — не ловит строки из пробелов и неограниченные строки с пробелами

Число

0 — не отличает «не заполнено» от осмысленного нуля

NULL

ЕСТЬ NULL — только проверка через IS NULL, обычное сравнение не работает

Отбор NULL после соединений таблиц

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

ВЫБРАТЬ

Номенклатура.Ссылка КАК Товар,

Остатки.КоличествоОстаток КАК Остаток

ИЗ

Справочник.Номенклатура КАК Номенклатура

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

ПО Номенклатура.Ссылка = Остатки.Номенклатура

ГДЕ

Остатки.Номенклатура ЕСТЬ NULL

Ключевое правило: NULL нельзя сравнивать знаком равенства. Условие ГДЕ Поле = NULL всегда даёт неопределённый результат и не отберёт ни одной строки. Используйте только операторы ЕСТЬ NULL и ЕСТЬ НЕ NULL. Это одна из самых распространённых ошибок у начинающих разработчиков 1С.

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

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

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

Надёжный вариант — комбинировать проверки через ИЛИ, охватывая все возможные представления пустоты:

ГДЕ

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

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

ИЛИ Документ.Получатель ЕСТЬ NULL

ИЛИ Документ.Получатель = НЕОПРЕДЕЛЕНО

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

Типичные ошибки
01
Сравнение с NULL через знак равенства — условие никогда не сработает, нужен оператор ЕСТЬ NULL
02
Указание в ЗНАЧЕНИЕ типа, отличного от типа реквизита, — запрос молча возвращает пустой результат
03
Отбор «поле <> пустая ссылка» без учёта NULL — часть незаполненных записей теряется
04
Проверка строки только на "" — строки из пробелов считаются заполненными
05
Трактовка нуля в числовом поле как «не заполнено», хотя ноль является осмысленным значением

Передача пустого значения через параметр

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

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| Реализация.Ссылка КАК Документ

|ИЗ

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

|ГДЕ

| Реализация.Контрагент = &ПустойКонтрагент";

Запрос.УстановитьПараметр("ПустойКонтрагент",

Справочники.Контрагенты.ПустаяСсылка());

Результат = Запрос.Выполнить();

Для пустой даты в параметр передаётся Дата(1,1,1), для строки — "", для NULL — значение Неопределено либо явно NULL через конструкцию в тексте запроса. Приём с параметром предпочтителен, когда один и тот же запрос должен работать в разных режимах: иногда отбирать пустые значения, иногда — конкретное значение реквизита. Тогда параметр просто заполняется нужным значением без изменения текста запроса.

Если требуется режим «отбирать всё, включая пустое», применяют приём с двумя параметрами или условие вида ГДЕ (Поле = &Значение ИЛИ &БезОтбора), где второй параметр — булево. Это стандартный шаблон для универсальных отчётов и обработок.

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

Проверка результата и контрольные точки

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

Дополнительная проверка — вывести само проверяемое поле в результат и визуально посмотреть несколько строк. Пустая ссылка в выборке отображается как пустое представление объекта, NULL — как пустая ячейка без типа. Если в колонке встречаются и те и другие, условие отбора должно учитывать оба варианта.

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

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

Сумма выборок «пусто» и «не пусто»
Норма

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

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

Меньше общего числа — есть NULL или значения другого типа

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

Все незаполненные ячейки однородны

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

Часть ячеек пустые ссылки, часть — NULL

Итоги отчёта после добавления условия
Норма

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

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

Итоги уменьшились без объяснимой причины

При работе в реальной базе любые запросы, по результатам которых планируется массовая обработка данных (заполнение реквизитов, удаление, перепроведение), сначала выполняйте в режиме просмотра и только после сверки запускайте изменение. Обновление тысяч документов по ошибочно составленному условию откатывается долго и болезненно.

Итог

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

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

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

Почему условие «= ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка)» ничего не находит, хотя реквизит точно не заполнен?

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

Чем NULL отличается от пустой ссылки?

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

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

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

Как отобрать документы, у которых не заполнена дата?

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

Можно ли в одном условии проверить и пустую ссылку, и NULL?

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

Что вернёт сравнение строки с пробелами с пустой строкой?

Строка из пробелов не равна пустой строке, поэтому условие ГДЕ Поле = "" такую запись не отберёт. Если в базе возможны значения из пробелов, потребуется либо очистка данных, либо дополнительные условия в запросе, учитывающие этот случай.