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

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

Как убрать NULL из запроса 1С

Как убрать NULL из запроса 1С: функция ЕСТЬNULL, проверка ЕСТЬ NULL, обработка NULL при соединениях и группировках. Примеры кода и типичные ошибки.

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

Основной инструмент для замены NULL — функция ЕСТЬNULL(Выражение, ЗначениеЗамены). Она проверяет первый аргумент и, если он равен NULL, подставляет второй. Дополнительно NULL можно отфильтровать через условие ЕСТЬ NULL / НЕ ... ЕСТЬ NULL либо убрать саму причину его появления, изменив тип соединения.

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

Откуда в запросе берётся NULL

Понимание источника NULL помогает выбрать правильный способ обработки. Чаще всего NULL возникает при ЛЕВОМ СОЕДИНЕНИИ: если для строки основной таблицы нет пары в присоединяемой, все поля второй таблицы будут NULL. Это нормальное поведение, а не ошибка запроса.

Второй источник — необязательные реквизиты и реквизиты составного типа. Если в документе не заполнен реквизит «Договор», запрос вернёт NULL. Третий случай — итоги и группировки: при ИТОГИ ПО или ОБЩИЕ ИТОГИ в группировочных записях поля, не участвующие в группировке, содержат NULL.

Отдельная ситуация — обращение через точку к реквизиту, когда ссылка битая или объект удалён. В этом случае разыменование даёт NULL, и запрос не падает с ошибкой, что маскирует проблему с данными.

NULL после соединенияЛевое соединение без пары

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

NULL в реквизитеРеквизит не заполнен

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

NULL в итогахГруппировочная запись

Это норма для строк ИТОГИ, обрабатывайте при обходе

NULL при разыменованииБитая ссылка

Проверьте целостность ссылок в базе

Замена NULL через функцию ЕСТЬNULL

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

ВЫБРАТЬ

Номенклатура.Наименование,

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

ИЗ

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

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

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

В этом примере товары без остатков получат значение 0 вместо NULL. Без ЕСТЬNULL колонка «Остаток» была бы пустой, а любое последующее вычисление (например, умножение на цену) дало бы NULL.

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

Фильтрация записей с NULL через ЕСТЬ NULL

Если записи с NULL не нужны вовсе, их можно исключить в секции ГДЕ. Оператор ЕСТЬ NULL проверяет значение на NULL, а конструкция НЕ ... ЕСТЬ NULL — наоборот, оставляет только заполненные значения.

ВЫБРАТЬ

Заказы.Номер,

Заказы.Контрагент

ИЗ

Документ.ЗаказПокупателя КАК Заказы

ГДЕ

НЕ Заказы.Контрагент ЕСТЬ NULL

Критически важно: сравнение Поле = NULL в языке запросов 1С не работает так, как ожидается. NULL не равен ничему, даже самому себе, поэтому условие ГДЕ Поле = NULL никогда не вернёт записей. Используйте только ЕСТЬ NULL.

Аналогично условие Поле <> &Параметр отбросит записи, где поле равно NULL, даже если параметр заполнен. Если нужно учесть и NULL-значения, перепишите условие: ГДЕ ЕСТЬNULL(Поле, 0) <> &Параметр.

Устранение NULL через изменение соединения

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

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

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

Сравнение вариантов

ЕСТЬNULL с заменой

Подходит, когда записи нужны все, а NULL требуется заменить на 0, пустую строку или текст-заглушку

ГДЕ НЕ ... ЕСТЬ NULL

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

ВНУТРЕННЕЕ СОЕДИНЕНИЕ

Подходит, когда по смыслу задачи нужны только связанные записи обеих таблиц

Обработка при обходе

Подходит для NULL в итогах: проверка ТипЗаписи() при обходе результата в коде

Обработка NULL в итогах и при обходе результата

При использовании ИТОГИ ПО группировочные записи содержат NULL в полях, которые не входят в группировку. Заменить их через ЕСТЬNULL прямо в запросе нельзя для самих итоговых строк — обработка выполняется в коде при обходе выборки.

ВыборкаГрупп = Результат.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);

Пока ВыборкаГрупп.Следующий() Цикл

ВыборкаДетали = ВыборкаГрупп.Выбрать();

Пока ВыборкаДетали.Следующий() Цикл

Если ВыборкаДетали.ТипЗаписи() = ТипЗаписиЗапроса.ДетальнаяЗапись Тогда

Количество = ?(ВыборкаДетали.Количество = NULL, 0, ВыборкаДетали.Количество);

КонецЕсли;

КонецЦикла;

КонецЦикла;

В модуле проверка на NULL выполняется простым сравнением Значение = NULL — в отличие от языка запросов, здесь это корректно. Также работает функция ЗначениеЗаполнено(), но она считает незаполненными и пустые ссылки, нули и пустые строки, поэтому для точной проверки именно на NULL используйте прямое сравнение.

Порядок действий
  1. 1
    Определите, откуда появляется NULL: соединение, незаполненный реквизит или итоги
  2. 2
    Выберите способ: ЕСТЬNULL для замены, ЕСТЬ NULL для фильтрации, ВНУТРЕННЕЕ СОЕДИНЕНИЕ для исключения
  3. 3
    Подставьте значение замены совместимого типа: 0 для чисел, "" для строк, пустую ссылку для ссылок
  4. 4
    Выполните запрос в консоли запросов и проверьте, что NULL исчезли
  5. 5
    Проверьте вычисляемые поля и условия ГДЕ, где участвует обработанное поле

Типичные ошибки при работе с NULL

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

Вторая ошибка — арифметика с NULL без обработки. Выражение Цена * Количество, где одно из полей NULL, даёт NULL, и итоговая сумма по документу занижается. Оборачивайте в ЕСТЬNULL оба операнда.

Третья ошибка — несовпадение типов в ЕСТЬNULL. Попытка подставить строку в числовое поле вызывает ошибку выполнения запроса. Четвёртая — обработка NULL только в ВЫБРАТЬ, но не в ГДЕ: поле в условии остаётся необработанным, и фильтрация работает неверно.

Типичные ошибки
01
Условие ГДЕ Поле = NULL — никогда не срабатывает; используйте Поле ЕСТЬ NULL
02
Арифметика без ЕСТЬNULL — результат вычисления становится NULL
03
Несовпадение типов в ЕСТЬNULL — ошибка выполнения запроса
04
Обработка NULL только в списке полей, но не в условиях ГДЕ и соединениях
05
Сравнение Поле <> &Параметр без учёта NULL — записи с NULL теряются из результата

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

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

Дополнительно сравните количество строк до и после изменения. Если вы заменили левое соединение на внутреннее или добавили фильтр НЕ ... ЕСТЬ NULL, число записей должно уменьшиться ровно на количество строк с NULL — не больше.

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

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

Колонка с обработанным полем
Норма

Вместо пустоты подставлено 0, "" или текст-заглушка

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

Ячейки по-прежнему пустые

Количество строк результата
Норма

Совпадает с ожиданием после фильтрации NULL

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

Строк стало заметно меньше без причины

Вычисляемые поля
Норма

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

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

В вычислениях по-прежнему NULL

Условия ГДЕ
Норма

Фильтр учитывает NULL через ЕСТЬNULL или ЕСТЬ NULL

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

Записи с NULL теряются из выборки

Часто задаваемые вопросы

Чем ЕСТЬNULL отличается от ВЫБОР КОГДА для обработки NULL?

Функционально ЕСТЬNULL(Поле, 0) эквивалентна конструкции ВЫБОР КОГДА Поле ЕСТЬ NULL ТОГДА 0 ИНАЧЕ Поле КОНЕЦ. ЕСТЬNULL короче и читабельнее, а ВЫБОР удобен, когда нужно обработать несколько разных условий, а не только NULL.

Можно ли убрать NULL из запроса к регистру сведений с составным типом ресурса?

Да. Обработайте ресурс через ЕСТЬNULL с подстановкой значения одного из типов составного поля. Если нужен конкретный тип, дополнительно используйте ВЫРАЗИТЬ для приведения, например: ВЫРАЗИТЬ(ЕСТЬNULL(Ресурс, 0) КАК ЧИСЛО(15,2)).

Почему условие ГДЕ Поле = NULL ничего не возвращает?

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

Как обработать NULL при выгрузке результата запроса в таблицу значений?

Лучше обработать NULL ещё в тексте запроса через ЕСТЬNULL — тогда в таблице значений сразу будут корректные данные. Если обрабатывать в коде, используйте сравнение Значение = NULL при обходе строк таблицы.

Влияет ли ЕСТЬNULL на производительность запроса?

Влияние минимально: это простая скалярная функция. Гораздо сильнее на скорость влияют сами соединения и отсутствие индексов по полям связи. Оптимизировать стоит соединения и отборы, а не отказываться от ЕСТЬNULL.

Что подставлять вместо NULL для ссылочных полей?

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

Итог

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

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