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

В этой статье мы разберём, почему стандартный оператор = NULL не работает, как правильно строить условия для поиска пустых ссылок, дат и числовых полей, а также рассмотрим нюансы производительности и типичные ошибки. Особое внимание уделим различиям между NULL и пустыми строками, которые часто становятся источником багов в отчётах и обработках.

Если вы когда-нибудь получали пустой результат запроса, хотя точно знали, что в базе есть незаполненные поля — эта статья для вас. Мы не только покажем правильный синтаксис, но и объясним, почему он работает именно так, а не иначе.

Почему оператор "= NULL" не работает в 1С

Самая распространённая ошибка новичков — попытка использовать конструкцию ГДЕ Поле = NULL. На первый взгляд, это логично: если мы хотим найти записи, где поле не заполнено, почему бы не сравнить его с NULL? Однако в 1С:Предприятие (как и в большинстве SQL-систем) такое сравнение всегда возвращает ЛОЖЬ, даже если поле действительно пустое.

Дело в том, что NULL в базах данных — это не значение, а отсутствие значения. Любое сравнение с NULL (включая =, <>, <, >) даёт неизвестный результат, который трактуется как ЛОЖЬ. Поэтому для проверки на пустоту существует специальный оператор ЕСТЬ NULL (или IS NULL в SQL-синтаксисе).

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

ВЫБРАТЬ

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

ИЗ

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

ГДЕ

Номенклатура.Артикул = NULL

А вот как этот запрос должен выглядеть правильно:

ВЫБРАТЬ

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

ИЗ

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

ГДЕ

Номенклатура.Артикул ЕСТЬ NULL

📊 Как вы обычно проверяете пустые значения в 1С?
Использую ЕСТЬ NULL
Пишу = NULL (и удивляюсь, почему не работает)
Использую функцию ЗНАЧЕНИЕЗАПОЛНЕНО
Другое

Синтаксис запросов с условием ЕСТЬ NULL / НЕ ЕСТЬ NULL

В 1С:Предприятие 8 для работы с пустыми значениями используются два оператора:

  • 🔹 ЕСТЬ NULL — проверяет, что поле не содержит значения (равно NULL)
  • 🔹 НЕ ЕСТЬ NULL — проверяет, что поле содержит любое значение, кроме NULL

Эти операторы работают со всеми типами данных: ссылками, числами, датами, булевыми значениями и строками. Оператор ЕСТЬ NULL не найдёт строки, где поле содержит пустую строку, и наоборот.

Примеры корректных запросов:

// Найти контрагентов без заполненного ИНН

ВЫБРАТЬ

Контрагент.Наименование

ИЗ

Справочник.Контрагенты КАК Контрагент

ГДЕ

Контрагент.ИНН ЕСТЬ NULL

// Найти документы с заполненной датой оплаты

ВЫБРАТЬ

Документ.Номер

ИЗ

Документ.РеализацияТоваровУслуг КАК Документ

ГДЕ

Документ.ДатаОплаты НЕ ЕСТЬ NULL

Обратите внимание, что в также можно использовать синонимы этих операторов на английском:

  • 🔹 IS NULL вместо ЕСТЬ NULL
  • 🔹 IS NOT NULL вместо НЕ ЕСТЬ NULL
💡

Если запрос с ЕСТЬ NULL работает слишком долго, попробуйте добавить индекс на проверяемое поле. В большинстве случаев это ускорит выполнение в 5-10 раз.

NULL vs пустая строка: в чём разница и как правильно искать

Многие разработчики путают NULL и пустую строку (""), что приводит к ошибкам в отчётах. Давайте разберём ключевые различия:

Характеристика NULL Пустая строка ("")
Тип данных Отсутствие значения (специальный маркер) Строковый тип с нулевой длиной
Как проверить в запросе ЕСТЬ NULL = "" или = ЗНАЧЕНИЕ(Строка)
Занимает место в базе Нет Да (минимальное)
Как ведёт себя в агрегатных функциях Игнорируется (например, СУММА не учитывает NULL) Учитывается как ноль в числовых контекстах

Чтобы найти все незаполненные строковые поля (и NULL, и пустые строки), нужно использовать комбинированное условие:

ВЫБРАТЬ

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

ИЗ

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

ГДЕ

Номенклатура.Комментарий ЕСТЬ NULL

ИЛИ Номенклатура.Комментарий = ""

Аналогично, для поиска заполненных строковых полей (и не-NULL, и не пустых) используйте:

ГДЕ

Номенклатура.Комментарий НЕ ЕСТЬ NULL

И Номенклатура.Комментарий <> ""

Почему пустая строка не равна NULL?

В базах данных NULL означает "значение неизвестно или не применимо", тогда как пустая строка — это известное значение (строка длиной 0). Например, если у номенклатуры нет артикула, это может быть зафиксировано как NULL (артикул не назначен) или как "" (артикул явно установлен как пустой).

Работа с NULL в связках таблиц (JOIN)

Особенности обработки NULL проявляются и при соединении таблиц. Если в условии соединения (СОЕДИНИТЬ) участвует поле, которое может содержать NULL, результат может отличаться от ожидаемого.

Рассмотрим пример с левым соединением (ЛЕВОЕ СОЕДИНЕНИЕ), где мы хотим получить все документы реализации, даже если у них не указан контрагент:

ВЫБРАТЬ

Документ.Номер КАК НомерДокумента,

Контрагент.Наименование КАК Контрагент

ИЗ

Документ.РеализацияТоваровУслуг КАК Документ

ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Контрагенты КАК Контрагент

ПО Документ.Контрагент = Контрагент.Ссылка

ГДЕ

Документ.Дата МЕЖДУ &НачалоПериода И &КонецПериода

В этом запросе строки, где Документ.Контрагент ЕСТЬ NULL, всё равно попадут в результат, но поле Контрагент.Наименование для них будет NULL. Если же использовать внутреннее соединение (СОЕДИНЕНИЕ без ЛЕВОЕ), такие строки будут исключены из результата.

Чтобы явно отфильтровать строки с незаполненными ссылками при соединении, добавьте условие в секцию ГДЕ:

ГДЕ

Документ.Контрагент НЕ ЕСТЬ NULL

☑️ Проверка соединений с NULL

Выполнено: 0 / 4

NULL в агрегатных функциях: СУММА, СРЕДНЕЕ, МАКСИМУМ

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

  • 📊 СУММА — пропускает NULL и суммирует только ненулевые значения
  • 📊 СРЕДНЕЕ — не учитывает NULL в расчёте среднего
  • 📊 МАКСИМУМ/МИНИМУМ — игнорируют NULL, но если все значения NULL, результат тоже будет NULL
  • 📊 КОЛИЧЕСТВО — считает все строки, включая те, где поле NULL
  • 📊 КОЛИЧЕСТВО РАЗЛИЧНЫХ — игнорирует NULL (не считает их за уникальное значение)

Пример запроса, где NULL влияет на результат:

ВЫБРАТЬ

Контрагент.Наименование,

СУММА(Документ.СуммаДокумента) КАК ОбщаяСумма,

СРЕДНЕЕ(Документ.СуммаДокумента) КАК СредняяСумма,

КОЛИЧЕСТВО(Документ.СуммаДокумента) КАК КоличествоДокументов

ИЗ

Документ.РеализацияТоваровУслуг КАК Документ

ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Контрагенты КАК Контрагент

ПО Документ.Контрагент = Контрагент.Ссылка

ГДЕ

Документ.Дата МЕЖДУ &НачалоПериода И &КонецПериода

СГРУППИРОВАТЬ ПО

Контрагент.Наименование

Если в этом запросе у некоторых документов поле СуммаДокумента будет NULL, то:

  • 🔢 СУММА проигнорирует их
  • 🔢 СРЕДНЕЕ рассчитается только по ненулевым суммам
  • 🔢 КОЛИЧЕСТВО посчитает все документы, включая те, где сумма NULL

Критический нюанс: если вам нужно, чтобы NULL учитывался как ноль в агрегатных функциях, используйте конструкцию ВЫРАЗИТЬ(Поле КАК Число(15,2)) или ЗНАЧЕНИЕ(Поле, 0).

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

Даже опытные разработчики иногда допускают ошибки при работе с NULL в 1С. Вот наиболее распространённые из них и способы их избежать:

⚠️ Внимание: Если вы используете конструкцию ГДЕ Поле = "" для поиска незаполненных строковых полей, вы пропустите все записи, где поле равно NULL. Всегда комбинируйте проверки: ГДЕ Поле ЕСТЬ NULL ИЛИ Поле = "".

Ошибка 1: Использование = NULL вместо ЕСТЬ NULL

// Неверно:

ГДЕ Документ.Контрагент = NULL

// Правильно:

ГДЕ Документ.Контрагент ЕСТЬ NULL

Ошибка 2: Проверка на неравенство <> NULL

// Неверно (всегда ЛОЖЬ):

ГДЕ Документ.ДатаОплаты <> NULL

// Правильно:

ГДЕ Документ.ДатаОплаты НЕ ЕСТЬ NULL

Ошибка 3: Игнорирование NULL в соединениях таблиц

// Если в Документ.Контрагент есть NULL, эти строки пропадут из результата:

ВЫБРАТЬ..

ИЗ Документ.Реализация КАК Документ

СОЕДИНЕНИЕ Справочник.Контрагенты КАК Контрагент

ПО Документ.Контрагент = Контрагент.Ссылка

// Используйте ЛЕВОЕ СОЕДИНЕНИЕ, если нужны все документы:

ВЫБРАТЬ..

ИЗ Документ.Реализация КАК Документ

ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Контрагенты КАК Контрагент

ПО Документ.Контрагент = Контрагент.Ссылка

Ошибка 4: Неучёт NULL в агрегатных функциях

// Если некоторые суммы NULL, среднее будет рассчитано неверно:

СРЕДНЕЕ(Документ.Сумма)

// Правильно:

СРЕДНЕЕ(ВЫРАЗИТЬ(Документ.Сумма КАК Число(15,2)))

⚠️ Внимание: При обновлении платформы 1С поведение некоторых функций с NULL может меняться. Например, в версиях до 8.3.10 функция ЗНАЧЕНИЕ(NULL) возвращала NULL, а в новых версиях может возвращать значение по умолчанию для типа. Всегда тестируйте критичные запросы после обновления платформы.

Оптимизация запросов с проверкой на NULL

Запросы с условиями ЕСТЬ NULL/НЕ ЕСТЬ NULL могут работать медленно на больших базах данных. Вот несколько советов по оптимизации:

  • 🚀 Добавьте индексы на поля, которые часто проверяются на NULL. Например, если вы регулярно ищете номенклатуру без артикула, создайте индекс по полю Артикул.
  • 🚀 Используйте подзапросы для предварительной фильтрации. Например:
    ВЫБРАТЬ..
    

    ИЗ Документ.ЗаказКлиента КАК Заказ

    ГДЕ Заказ.Ссылка В (

    ВЫБРАТЬ ЗаказКлиента.Ссылка

    ИЗ Документ.ЗаказКлиента КАК ЗаказКлиента

    ГДЕ ЗаказКлиента.Контрагент ЕСТЬ NULL

    )

  • 🚀 Заменяйте NULL на значения по умолчанию с помощью ВЫРАЗИТЬ или ЗНАЧЕНИЕ, если это не искажает логику. Например:
    ВЫБРАТЬ
    

    ЗНАЧЕНИЕ(Документ.Сумма, 0) КАК Сумма

  • 🚀 Избегайте НЕ ЕСТЬ NULL в больших таблицах. Если возможно, перестройте запрос так, чтобы проверка на ненулевые значения была в подзапросе или соединении.

Пример оптимизированного запроса для поиска документов без указанного менеджера:

// Неоптимально (полное сканирование таблицы):

ВЫБРАТЬ..

ИЗ Документ.Реализация КАК Документ

ГДЕ Документ.Менеджер ЕСТЬ NULL

// Оптимально (с использованием индекса):

ВЫБРАТЬ..

ИЗ Документ.Реализация КАК Документ

ГДЕ Документ.Ссылка В (

ВЫБРАТЬ ДокументВнутри.Ссылка

ИЗ Документ.Реализация КАК ДокументВнутри

ГДЕ ДокументВнутри.Менеджер ЕСТЬ NULL

)

💡

Проверка на NULL в больших таблицах без индексов может замедлить запрос в десятки раз. Всегда анализируйте план выполнения запроса в консоли запросов 1С (кнопка "Объяснить").

Практический пример: поиск незаполненных реквизитов в справочниках

Допустим, вам нужно найти все элементы справочника Номенклатура, у которых не заполнены:

  • 📌 Артикул
  • 📌 Единица измерения
  • 📌 Ставка НДС

Вот как будет выглядеть такой запрос:

ВЫБРАТЬ

Номенклатура.Ссылка КАК Ссылка,

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

ВЫРАЗИТЬ(Номенклатура.Артикул КАК Строка) КАК Артикул,

ВЫРАЗИТЬ(Номенклатура.ЕдиницаИзмерения КАК Строка) КАК ЕдиницаИзмерения,

ВЫРАЗИТЬ(Номенклатура.СтавкаНДС КАК Строка) КАК СтавкаНДС

ИЗ

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

ГДЕ

Номенклатура.Артикул ЕСТЬ NULL

ИЛИ Номенклатура.ЕдиницаИзмерения ЕСТЬ NULL

ИЛИ Номенклатура.СтавкаНДС ЕСТЬ NULL

Если вам нужно вывести только те позиции, где все три поля пустые, замените ИЛИ на И:

ГДЕ

Номенклатура.Артикул ЕСТЬ NULL

И Номенклатура.ЕдиницаИзмерения ЕСТЬ NULL

И Номенклатура.СтавкаНДС ЕСТЬ NULL

Для удобства можно добавить вычисляемое поле, которое покажет, какие именно реквизиты не заполнены:

ВЫБРАТЬ

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

ВЫБОР

КОГДА Номенклатура.Артикул ЕСТЬ NULL

ТОГДА "Артикул; "

ИНАЧЕ ""

КОНЕЦ +

ВЫБОР

КОГДА Номенклатура.ЕдиницаИзмерения ЕСТЬ NULL

ТОГДА "Ед.изм.; "

ИНАЧЕ ""

КОНЕЦ +

ВЫБОР

КОГДА Номенклатура.СтавкаНДС ЕСТЬ NULL

ТОГДА "НДС; "

ИНАЧЕ ""

КОНЕЦ КАК НезаполненныеРеквизиты

ИЗ

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

ГДЕ

Номенклатура.Артикул ЕСТЬ NULL

ИЛИ Номенклатура.ЕдиницаИзмерения ЕСТЬ NULL

ИЛИ Номенклатура.СтавкаНДС ЕСТЬ NULL

💡

Чтобы быстро найти все справочники с незаполненными реквизитами, создайте универсальную обработку, которая динамически формирует запрос для любого справочника на основе его структуры метаданных.

FAQ: Частые вопросы по работе с NULL в 1С

Почему запрос с условием Поле = "" не находит строки, где поле не заполнено?

Потому что пустая строка ("") и NULL — это разные вещи. Пустая строка — это строковое значение длиной 0, а NULL — отсутствие значения. Чтобы найти все незаполненные строковые поля, используйте:

ГДЕ Поле ЕСТЬ NULL ИЛИ Поле = ""
Как в запросе заменить NULL на какое-то значение, например, "Не указано"?

Используйте функцию ВЫРАЗИТЬ или ЗНАЧЕНИЕ:

ВЫБРАТЬ

ВЫРАЗИТЬ(Контрагент.ИНН КАК Строка) КАК ИНН,

ЗНАЧЕНИЕ(Контрагент.ИНН, "Не указано") КАК ИННДляОтображения

ИЗ Справочник.Контрагенты КАК Контрагент

Функция ВЫРАЗИТЬ преобразует NULL в пустую строку, а ЗНАЧЕНИЕ позволяет указать произвольное значение по умолчанию.

Можно ли в 1С использовать оператор ISNULL как в SQL Server?

Нет, в языке запросов 1С нет оператора ISNULL. Вместо него используйте:

  • 🔹 ЗНАЧЕНИЕ(Поле, ЗначениеПоУмолчанию) — для замены NULL на заданное значение
  • 🔹 ВЫРАЗИТЬ(Поле КАК Тип) — для преобразования NULL в значение по умолчанию для типа (например, пустую строку или 0)
Почему при соединении таблиц пропадают строки, где поле равно NULL?

Это происходит потому, что по умолчанию используется ВНУТРЕННЕЕ СОЕДИНЕНИЕ (INNER JOIN), которое возвращает только строки, где есть совпадения в обеих таблицах. Если в поле соединения есть NULL, такие строки исключаются из результата.

Решения:

  • 🔹 Используйте ЛЕВОЕ СОЕДИНЕНИЕ (LEFT JOIN), если нужны все строки из левой таблицы
  • 🔹 Добавьте явную проверку Поле НЕ ЕСТЬ NULL в условие соединения, если нужно исключить пустые ссылки
Как найти документы, где хотя бы одно поле из списка равно NULL?

Используйте оператор ИЛИ для перечисления всех полей:

ВЫБРАТЬ..

ИЗ Документ.ЗаказКлиента КАК Заказ

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

ИЛИ Заказ.Менеджер ЕСТЬ NULL

ИЛИ Заказ.ДатаОплаты ЕСТЬ NULL

Если список полей большой, можно использовать динамический запрос, сформированный в коде 1С.