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