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