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