Разработка и Конфигурация · 11 мин
1С запрос: как проверить заполненность значения
Как в запросе 1С проверить заполненность поля: ЕСТЬ NULL, НЕОПРЕДЕЛЕНО, пустые ссылки, строки и даты. Примеры кода, типичные ошибки и FAQ.
Проверка заполненности — одна из самых частых задач при написании запросов в 1С. Незаполненный реквизит может содержать NULL, пустую ссылку, пустую строку, значение НЕОПРЕДЕЛЕНО или дату '00010101' — и для каждого случая нужен свой способ проверки. Универсального оператора «заполнено» в языке запросов нет, поэтому разработчик должен понимать, какое именно «пустое» значение хранится в поле.
Ошибки в таких проверках приводят к тому, что в отчёт попадают лишние строки или, наоборот, теряются нужные данные. Особенно коварны составные типы реквизитов и соединения таблиц, где NULL появляется неявно. Ниже разобраны все основные способы проверки с примерами кода и указанием границ применимости каждого.
Почему значение NULL и как его проверить через ЕСТЬ NULL
Значение NULL в запросах 1С появляется в трёх типовых ситуациях: при левом соединении, когда в присоединяемой таблице нет подходящей строки; при обращении к реквизиту через точку от NULL-ссылки; при группировках с итогами. NULL — это не «пустое значение», а отсутствие значения, и его нельзя сравнивать обычным знаком равенства: условие Поле = NULL всегда ложно.
Для проверки используется специальный оператор:
ВЫБРАТЬ
Заказы.Ссылка КАК Заказ,
Оплаты.Сумма КАК СуммаОплаты
ИЗ
Документ.ЗаказКлиента КАК Заказы
ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.Оплаты КАК Оплаты
ПО Заказы.Ссылка = Оплаты.Заказ
ГДЕ
Оплаты.Сумма ЕСТЬ NULL
Такой запрос вернёт заказы, по которым нет ни одной строки оплаты. Обратное условие — НЕ Оплаты.Сумма ЕСТЬ NULL или Оплаты.Сумма ЕСТЬ NULL НЕ — отберёт только строки с заполненным значением. Для подстановки значения по умолчанию вместо NULL применяется функция ЕСТЬNULL(Поле, 0).
Как проверить заполненность ссылки на справочник или документ
Незаполненный реквизит ссылочного типа хранит не NULL, а пустую ссылку соответствующего типа. Проверка выполняется сравнением с конструкцией ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка):
ВЫБРАТЬ
Реализация.Ссылка,
Реализация.Контрагент
ИЗ
Документ.РеализацияТоваровУслуг КАК Реализация
ГДЕ
Реализация.Контрагент = ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка)
Для отбора только заполненных значений условие инвертируется: Реализация.Контрагент <> ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка). Тот же приём работает для документов, перечислений, планов счетов и других ссылочных типов — меняется только имя объекта метаданных в конструкторе ЗНАЧЕНИЕ.
Альтернатива без явного указания типа — передача пустой ссылки через параметр: ГДЕ Поле = &ПустаяСсылка, где параметр устанавливается из кода как Справочники.Контрагенты.ПустаяСсылка(). Это удобно, когда тип реквизита заранее неизвестен или запрос строится динамически.
Проверка строк, чисел, дат и булевых полей
Примитивные типы в 1С не бывают NULL в собственных реквизитах таблицы — у них всегда есть значение по умолчанию. Поэтому «незаполненность» проверяется сравнением с этим значением:
- строка неограниченной или фиксированной длины:
Поле = ""(пустая строка); - число:
Поле = 0; - дата:
Поле = ДАТАВРЕМЯ(1, 1, 1); - булево:
Поле = ЛОЖЬ.
Со строками есть нюанс: реквизит может содержать пробелы или неразрывные пробелы, которые визуально выглядят как пустота, но сравнение с "" не проходят. В запросе нет функции сокращения пробелов, поэтому такие случаи надёжнее обрабатывать в коде после выборки через СокрЛП() либо очищать данные регламентной обработкой.
С датами помните, что пустая дата — это '0001-01-01 00:00:00', и сравнение Поле = ДАТАВРЕМЯ(1,1,1) корректно её отлавливает. Если реквизит может быть NULL (например, из левого соединения), комбинируйте проверки: Поле ЕСТЬ NULL ИЛИ Поле = ДАТАВРЕМЯ(1,1,1).
Значение НЕОПРЕДЕЛЕНО и составные типы реквизитов
Значение НЕОПРЕДЕЛЕНО появляется в реквизитах составного типа, когда тип значения не задан, а также как результат некоторых обращений к данным. Проверка выполняется прямым сравнением:
ГДЕ
Реквизит = НЕОПРЕДЕЛЕНО
ИЛИ Реквизит ЕСТЬ NULL
Составной реквизит — главный источник сложностей. Например, поле «Договор» типа «СправочникСсылка.Договоры, Строка(50)» может быть пустой ссылкой, пустой строкой, NULL или НЕОПРЕДЕЛЕНО. Проверка заполненности для него выглядит так:
ГДЕ
НЕ (Поле ЕСТЬ NULL)
И Поле <> НЕОПРЕДЕЛЕНО
И Поле <> ЗНАЧЕНИЕ(Справочник.Договоры.ПустаяСсылка)
И Поле <> ""
Дополнительный приём — проверка фактического типа значения через оператор ВЫРАЗИТЬ(Поле КАК Справочник.Договоры): если реальный тип другой, результат приведения будет NULL, и это можно использовать как фильтр по типу.
Как выбрать способ проверки
Проверка заполненности в СКД и динамических списках
В схеме компоновки данных те же операторы доступны в тексте запроса набора данных, но дополнительно проверку можно вынести в отбор СКД. Для этого в настройках используется вид сравнения «Заполнено» / «Не заполнено» — система сама строит корректное условие с учётом типа поля, что избавляет от ручного перечисления пустых значений.
В динамических списках аналогичный отбор доступен пользователю через «Ещё — Настроить список». Если вы разрабатываете произвольный запрос для динамического списка, учитывайте, что отбор «Заполнено» платформа добавляет поверх вашего текста, поэтому не дублируйте такую проверку жёстко в секции ГДЕ без необходимости — это ограничит гибкость настройки.
При передаче условий через параметры помните: параметр не может быть «не задан». Если параметр-отбор опционален, используйте шаблон ГДЕ (&Параметр = НЕОПРЕДЕЛЕНО ИЛИ Поле = &Параметр) и передавайте НЕОПРЕДЕЛЕНО, когда фильтр не нужен.
В отчётах на СКД отбор «Заполнено» надёжнее ручных условий в тексте запроса: платформа учитывает составной тип поля автоматически. Ручные проверки оставляйте для случаев, где логика сложнее простого отбора.
Проверка результата и границы самостоятельной работы
После написания условия проверьте его на тестовых данных с заведомо известным составом: создайте по одному объекту с пустой ссылкой, NULL (через соединение), пустой строкой и заполненным значением. Запрос должен отобрать ровно ожидаемое подмножество. Консоль запросов позволяет быстро перебирать варианты условий без перезапуска отчёта.
Обратите внимание на производительность: условия вида НЕ (Поле ЕСТЬ NULL) и сравнения с пустыми ссылками обычно используют индексы, а вот оборачивание поля в функции (например, ЕСТЬNULL(Поле, "") = "" в секции ГДЕ) может отключить индексацию и замедлить запрос на больших таблицах. По возможности пишите условие прямым сравнением поля.
Если проверка заполненности нужна для массовой обработки данных (например, найти и заполнить пустые реквизиты), сначала выполните запрос в режиме только чтения и оцените количество строк. Изменение данных делайте на копии базы или в тестовом контуре: ошибочное условие в цикле обработки может затронуть тысячи объектов, и откат без резервной копии невозможен.
Как проверить результат
Возвращаются только строки без пары в присоединяемой таблице
Пустой результат при заведомо существующих незакрытых строках — проверьте условие соединения
Находятся объекты с визуально незаполненным реквизитом
Часть «пустых» объектов не найдена — реквизит составного типа, добавьте проверки на НЕОПРЕДЕЛЕНО и пустую строку
Запрос выполняется быстро, план использует индекс
Резкое замедление — вероятно, поле обёрнуто в функцию, перепишите прямым сравнением
Частые вопросы
Чем NULL отличается от пустой ссылки в запросе 1С?
NULL означает отсутствие данных — он возникает при соединениях и обращениях через точку к несуществующему объекту. Пустая ссылка — это конкретное значение ссылочного типа, которое хранится в реквизите. NULL проверяется оператором ЕСТЬ NULL, пустая ссылка — сравнением с ЗНАЧЕНИЕ(...ПустаяСсылка). Сравнение с NULL через знак равенства не работает.
Как проверить, что строковый реквизит заполнен, с учётом пробелов?
В языке запросов нет функции сокращения пробелов, поэтому полноценно отсечь строки из одних пробелов можно только в коде после выборки через СокрЛП. В самом запросе доступна проверка Поле <> "", которая отлавливает только полностью пустые строки.
Как проверить заполненность реквизита составного типа одним условием?
Одним условием не обойтись: составной реквизит может содержать NULL, НЕОПРЕДЕЛЕНО, пустую ссылку и пустую строку одновременно в разных записях. Перечислите все варианты через ИЛИ для поиска незаполненных либо через И с отрицанием — для поиска заполненных. В СКД вместо этого используйте вид сравнения «Заполнено».
Можно ли использовать ЕСТЬNULL в секции ГДЕ для фильтрации?
Технически можно, например ГДЕ ЕСТЬNULL(Поле, 0) = 0, но это нежелательно: оборачивание поля в функцию обычно мешает использованию индекса и замедляет запрос на больших таблицах. Для фильтрации пишите прямое условие Поле ЕСТЬ NULL ИЛИ Поле = 0, а ЕСТЬNULL оставьте для выборки и подстановки значений по умолчанию.
Как в динамическом списке отобрать только записи с незаполненным реквизитом?
Откройте настройку списка («Ещё — Настроить список»), добавьте отбор по нужному полю и выберите вид сравнения «Не заполнено». Платформа сама построит корректное условие с учётом типа реквизита, включая составные типы, без изменения текста запроса списка.
Почему условие Поле = NULL не находит записи?
Потому что NULL не равно ничему, включая сам себя: любое сравнение с NULL даёт «неизвестно», и строка отбрасывается. Для проверки на NULL существует специальный оператор ЕСТЬ NULL, а для отрицания — НЕ (Поле ЕСТЬ NULL). Это стандартное поведение, унаследованное из SQL.
Что важно запомнить
Заполненность в запросе 1С проверяется по типу поля: NULL — оператором ЕСТЬ NULL, пустая ссылка — сравнением с ЗНАЧЕНИЕ(...ПустаяСсылка), строка — с "", дата — с ДАТАВРЕМЯ(1,1,1), НЕОПРЕДЕЛЕНО — прямым сравнением. Составные типы требуют комбинации проверок, а в СКД и динамических списках удобнее встроенный вид сравнения «Заполнено». Условия пишите прямым сравнением поля без обёрток в функции, чтобы сохранить индексацию.