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

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

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

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

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

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

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

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

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

Проверка на NULL: операторы ЕСТЬ NULL и НЕ ЕСТЬ NULL

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

ВЫБРАТЬ

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

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

ИЗ

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

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

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

ГДЕ

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

Этот запрос вернёт номенклатуру, по которой нет остатков вообще. Если нужно наоборот — исключить NULL и оставить только заполненные значения, используется НЕ ЕСТЬ NULL:

ГДЕ

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

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

ВЫБРАТЬ

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

ЕСТЬNULL(Остатки.КоличествоОстаток, 0) КАК Остаток

Типичные ошибки при работе с NULL
01
Сравнение «Поле = NULL» вместо «Поле ЕСТЬ NULL» — условие никогда не сработает, строки молча теряются
02
Забытая проверка на NULL после левого соединения — в отчёт попадают пустые строки, а итоги искажаются
03
Использование ЕСТЬNULL без указания типа замены, несовместимого с типом поля, — запрос падает с ошибкой

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

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

ВЫБРАТЬ

Поступление.Ссылка КАК Документ,

Поступление.Контрагент КАК Контрагент

ИЗ

Документ.ПоступлениеТоваровУслуг КАК Поступление

ГДЕ

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

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

ГДЕ

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

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

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

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

ВЫБРАТЬ

Контрагенты.Ссылка КАК Контрагент,

Контрагенты.ИНН КАК ИНН

ИЗ

Справочник.Контрагенты КАК Контрагенты

ГДЕ

Контрагенты.ИНН = ""

Для дат незаполненное значение — это начало эпохи, поэтому проверка выглядит так:

ГДЕ

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

Со строками неограниченной длины есть нюанс: сравнение с пустой строкой работает, но в некоторых ситуациях надёжнее проверять длину строки. Функция ДЛИНАСТРОКИ() возвращает количество символов, и для незаполненной строки оно равно нулю:

ГДЕ

ДЛИНАСТРОКИ(Контрагенты.Комментарий) = 0

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

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

Реквизиты составного типа (например, «Партия» в регистрах или «ДокументОснование») требуют особого внимания. Если обратиться к реквизиту через точку от поля составного типа, для значений другого типа запрос вернёт NULL. Это штатное поведение, и проверка ЕСТЬ NULL здесь — корректный способ отделить один тип от другого.

ВЫБРАТЬ

Движения.Регистратор КАК Регистратор,

Движения.Регистратор.Организация КАК Организация

ИЗ

РегистрНакопления.Продажи КАК Движения

ГДЕ

НЕ Движения.Регистратор.Организация ЕСТЬ NULL

Такой запрос оставит только те регистраторы, у которых есть реквизит «Организация». Однако обращение к полям составного типа через точку приводит к неявным соединениям и замедляет запрос. Более производительный и предсказуемый вариант — явное приведение типа оператором ВЫРАЗИТЬ:

ГДЕ

ВЫРАЗИТЬ(Движения.Регистратор КАК Документ.РеализацияТоваровУслуг).Организация

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

Проверка заполненности вне запроса: ЗначениеЗаполнено()

Если значение уже получено в коде встроенного языка (например, параметр запроса или реквизит объекта), используется функция ЗначениеЗаполнено(). Она универсальна: возвращает Ложь для NULL, Неопределено, пустых ссылок, пустых строк, нуля и пустой даты, и Истина для всех заполненных значений.

Если Не ЗначениеЗаполнено(Контрагент) Тогда

Сообщить("Контрагент не указан");

КонецЕсли;

Типичный сценарий — условная установка параметра или отбора запроса. Например, добавлять отбор по контрагенту только если он заполнен, чтобы пустой параметр не обнулял результат:

Если ЗначениеЗаполнено(Контрагент) Тогда

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

|И Продажи.Контрагент = &Контрагент";

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

КонецЕсли;

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

Где проверять заполненность

В языке запросов

ЕСТЬ NULL, сравнение с ЗНАЧЕНИЕ(...ПустаяСсылка), сравнение с пустой строкой или ДАТАВРЕМЯ(1,1,1). Подходит для отбора и соединений, работает на стороне СУБД.

Во встроенном языке

ЗначениеЗаполнено() — универсальная проверка для параметров, реквизитов объектов и результатов выборки. Не работает внутри текста запроса.

Через ЕСТЬNULL()

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

Пошаговый порядок выбора проверки

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

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

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

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

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

Запрос возвращает строки с известно незаполненным реквизитом
Норма

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

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

Строк нет — проверяется не тот вид пустоты (NULL вместо пустой ссылки)

Запрос с левым соединением
Норма

Отсутствующие данные распознаются через ЕСТЬ NULL

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

Пустые строки попадают в итог — проверка на NULL пропущена

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

Используется ВЫРАЗИТЬ для составных типов

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

Множественные обращения через точку к полям составного типа

Итог

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

Итог

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

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

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

Почему условие «Поле = NULL» не работает?

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

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

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

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

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

Как заменить NULL на ноль в итоговой выборке?

Используйте функцию ЕСТЬNULL(Поле, 0) в списке выбираемых полей. Это стандартный приём для остатков и оборотов: вместо пустого значения в отчёт попадёт ноль, и последующие расчёты и группировки не сломаются.

Строка заполнена пробелами — проверка с пустой строкой её не находит. Что делать?

Сравнение с "" считает строку из пробелов заполненной. Варианты: проверять ДЛИНАСТРОКИ(Поле) = 0 вместе с отдельной обработкой пробельных значений, очищать данные при записи, либо фильтровать такие строки уже во встроенном языке после получения выборки.

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

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