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