Разработка и Конфигурация · 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 — только проверка через IS NULL, обычное сравнение не работает
Отбор NULL после соединений таблиц
NULL появляется в результате запроса, когда левое соединение не нашло пару в правой таблице: поля правой таблицы в таких строках содержат NULL. Это стандартный приём поиска «осиротевших» записей — например, товаров, по которым не было движений, или контрагентов без документов:
ВЫБРАТЬ
Номенклатура.Ссылка КАК Товар,
Остатки.КоличествоОстаток КАК Остаток
ИЗ
Справочник.Номенклатура КАК Номенклатура
ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки КАК Остатки
ПО Номенклатура.Ссылка = Остатки.Номенклатура
ГДЕ
Остатки.Номенклатура ЕСТЬ NULL
Ключевое правило: NULL нельзя сравнивать знаком равенства. Условие ГДЕ Поле = NULL всегда даёт неопределённый результат и не отберёт ни одной строки. Используйте только операторы ЕСТЬ NULL и ЕСТЬ НЕ NULL. Это одна из самых распространённых ошибок у начинающих разработчиков 1С.
Если NULL нужно заменить на конкретное значение прямо в выборке, применяется функция ЕСТЬNULL(Поле, ЗначениеЗамены). Например, ЕСТЬNULL(Остатки.КоличествоОстаток, 0) вернёт ноль вместо NULL, что упрощает дальнейшие вычисления и группировки.
Пустые значения в реквизитах составного типа
Реквизиты составного типа (например, «Получатель» с типами Справочник.Контрагенты и Справочник.ФизическиеЛица) требуют особого подхода. Незаполненный составной реквизит чаще всего хранит NULL, а не одну из пустых ссылок, поэтому условие ГДЕ Получатель = ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка) может ничего не найти.
Надёжный вариант — комбинировать проверки через ИЛИ, охватывая все возможные представления пустоты:
ГДЕ
Документ.Получатель = ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка)
ИЛИ Документ.Получатель = ЗНАЧЕНИЕ(Справочник.ФизическиеЛица.ПустаяСсылка)
ИЛИ Документ.Получатель ЕСТЬ NULL
ИЛИ Документ.Получатель = НЕОПРЕДЕЛЕНО
Также для составных полей полезна функция ВЫРАЗИТЬ: приведение поля к конкретному типу (ВЫРАЗИТЬ(Документ.Получатель КАК Справочник.Контрагенты)) превращает значения других типов в NULL, после чего можно работать стандартными проверками. Это удобно, когда нужно отобрать записи, где получатель — именно контрагент, но реквизит пуст.
Передача пустого значения через параметр
Когда условие формируется динамически из кода модуля, пустое значение удобнее передавать параметром. В коде на встроенном языке пустая ссылка получается через менеджер объекта, а дальше подставляется в запрос:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Реализация.Ссылка КАК Документ
|ИЗ
| Документ.РеализацияТоваровУслуг КАК Реализация
|ГДЕ
| Реализация.Контрагент = &ПустойКонтрагент";
Запрос.УстановитьПараметр("ПустойКонтрагент",
Справочники.Контрагенты.ПустаяСсылка());
Результат = Запрос.Выполнить();
Для пустой даты в параметр передаётся Дата(1,1,1), для строки — "", для NULL — значение Неопределено либо явно NULL через конструкцию в тексте запроса. Приём с параметром предпочтителен, когда один и тот же запрос должен работать в разных режимах: иногда отбирать пустые значения, иногда — конкретное значение реквизита. Тогда параметр просто заполняется нужным значением без изменения текста запроса.
Если требуется режим «отбирать всё, включая пустое», применяют приём с двумя параметрами или условие вида ГДЕ (Поле = &Значение ИЛИ &БезОтбора), где второй параметр — булево. Это стандартный шаблон для универсальных отчётов и обработок.
- 1Определите точный тип реквизита в конфигураторе: ссылка, дата, строка, число или составной тип
- 2Выберите соответствующее пустое значение: ЗНАЧЕНИЕ(...ПустаяСсылка), ДАТАВРЕМЯ(1,1,1), "" или 0
- 3Если поле участвует в левом соединении или составное — добавьте проверку ЕСТЬ NULL
- 4Выполните запрос в консоли запросов на копии базы и проверьте количество строк
- 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. Такое комбинированное условие — стандартная практика для реквизитов составного типа и полей, полученных соединением таблиц.
Что вернёт сравнение строки с пробелами с пустой строкой?
Строка из пробелов не равна пустой строке, поэтому условие ГДЕ Поле = "" такую запись не отберёт. Если в базе возможны значения из пробелов, потребуется либо очистка данных, либо дополнительные условия в запросе, учитывающие этот случай.