Работа с пустыми значениями (NULL) — одна из самых частых задач при написании запросов в 1С:Предприятие 8

Бесплатная консультация юриста

+7 (800) 302-87-29

Реклама jurik.ru

Работа с пустыми значениями (NULL) — одна из самых частых задач при написании запросов в 1С:Предприятие 8. Неверная обработка пустоты приводит к ошибкам в отчетах, некорректным итогам и логическим ошибкам в алгоритмах. В этой статье мы подробно разберем все способы проверки реквизита на «не пустоту» в языке запросов 1С.

Теоретические основы: Что такое пустое значение?

В 1С пустое значение (NULL) — это специальное значение, обозначающее «отсутствие значения». Оно не равно нулю (0), не равно пустой строке ("") и не равно дате '00010101'.

  • Для строк: пусто — это NULL (отличается от "").
  • Для чисел: пусто, это NULL (отличается от 0).
  • Для дат: пусто — это NULL (отличается от ДАТАВРЕМЯ(1, 1, 1)).
  • Для ссылок (объектов метаданных): пусто — это NULL (отличается от пустой ссылки, хотя в запросах они часто ведут себя одинаково при сравнении).

Важное правило: Любое сравнение с NULL через операторы =, <>, >, < дает результат NULL (ложь), а не Истина. Поэтому конструкция ГДЕ Реквизит <> NULL не сработает.

Основные способы проверки на «НЕ ПУСТО»

Оператор IS NOT NULL (Стандарт SQL)

Это самый правильный, читаемый и производительный способ. Он работает для полей любого типа.

ВЫБРАТЬ
 Номенклатура.Наименование,
 Номенклатура.Артикул
ИЗ
 Справочник.Номенклатура КАК Номенклатура
ГДЕ
 Номенклатура.Артикул IS NOT NULL

Плюсы: Явная семантика, стандарт SQL, оптимизатор запросов отлично работает с этим условием (может использовать индексы).

Функция ЗНАЧЕНИЕ (Сравнение со значением по умолчанию)

В 1С для каждого типа существует «значение по умолчанию» (пустая строка, 0, дата 00010101, пустая ссылка). Функция ЗНАЧЕНИЕ(Тип) возвращает именно это значение.

ВЫБРАТЬ
 Контрагенты.Наименование,
 Контрагенты.ИНН
ИЗ
 Справочник.Контрагенты КАК Контрагенты
ГДЕ
 Контрагенты.ИНН <> ЗНАЧЕНИЕ(Строка)

Нюанс: Это работает, потому что в запросах 1С значение NULL при сравнении с конкретным значением (пустой строкой) дает Ложь, а непустое значение — Истина (если оно не равно пустой строке).

Минус: Если в поле реально записана пустая строка "" (а не NULL), условие <> ЗНАЧЕНИЕ(Строка) отфильтрует её как «пустую». Часто это и требуется, но нужно понимать разницу.

Функция ЕСТЬNULL / ISNULL (Замена NULL на значение)

Часто используется не для фильтрации в ГДЕ, а для подстановки значения по умолчанию в ВЫБРАТЬ или внутри выражений.

ВЫБРАТЬ
 Товары.Наименование,
ИЗ
 Справочник.Номенклатура КАК Товары

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

ГДЕ
 ЕСТЬNULL(Товары.Артикул, "") <> ""

Функция РАЗНОСТЬ (Встречается в старом коде)

Возвращает Истина, если значения не равны (учитывая NULL).

ГДЕ
 РАЗНОСТЬ(Номенклатура.Артикул, ЗНАЧЕНИЕ(Строка))

Сейчас считается устаревшим, лучше использовать IS NOT NULL или прямое сравнение.

Специфика для разных типов данных

Строковые поля

Часто требуется отсеять и NULL, и пустые строки "", и строки из пробелов.

ВЫБРАТЬ

 Клиенты.Наименование
ИЗ
 Справочник.Клиенты КАК Клиенты
ГДЕ
 Клиенты.Телефон IS NOT NULL
 И СОКРЛП(Клиенты.Телефон) <> ""

Числовые поля

Проверка на не ноль и не пустоту — разные вещи.

  • Сумма IS NOT NULL, есть значение (может быть 0).
  • Сумма <> 0 — значение не ноль (но может быть NULL, тогда условие ложно).
  • Сумма IS NOT NULL И Сумма <> 0, есть значение И оно не ноль.

Ссылочные поля (Справочники, Документы)

Для ссылок пустое значение — это NULL (в БД) или пустая ссылка (в языке 1С). В запросах лучше всего использовать:

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

Или сравнение с пустой ссылкой (менее предпочтительно для производительности, но понятно):

ГДЕ
 Документ.Контрагент <> ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка)

Поля составных типов (ЛюбаяСсылка и т.д.)

Если реквизит имеет составной тип, проверка IS NOT NULL работает корректно — она проверяет, что ссылка вообще выбрана (независимо от типа).

ВЫБРАТЬ
 Движения.СчетДт,
 Движения.СчетКт
ИЗ
 РегистрБухгалтерии.Хозрасчетный КАК Движения
ГДЕ
 Движения.СчетДт IS NOT NULL

Проверка в секции ВЫБРАТЬ (CASE, ВЫБОР)

Часто нужно вывести флаг «Заполнено/Не заполнено» или подставить значение.

Вариант А: Конструкция ВЫБОР (CASE)

ВЫБРАТЬ
 Номенклатура.Наименование,
 ВЫБОР
 КОГДА Номенклатура.Артикул IS NOT NULL ТОГДА "Есть артикул"
 ИНАЧЕ "Артикул не заполнен"
 КОНЕЦ КАК СтатусАртикула
ИЗ
 Справочник.Номенклатура КАК Номенклатура

Вариант Б: Функция ЕСТЬNULL (Кратко)

ВЫБРАТЬ
 Номенклатура.Наименование,
 ЕСТЬNULL(Номенклатура.Артикул, "НЕ ЗАПОЛНЕН") КАК АртикулИлиТекст
ИЗ
 Справочник.Номенклатура КАК Номенклатура

Проверка в виртуальных таблицах и остатках

При работе с виртуальными таблицами (Остатки, Обороты) важно помнить: если по измерению нет записей, в выборку попадает строка с NULL по ресурсам (если не указано АВТОУПОРЯДОЧИВАНИЕ или условия отбора).

ВЫБРАТЬ
 Остатки.Номенклатура,
 Остатки.КоличествоОстаток
ИЗ
 РегистрНакопления.ТоварыНаСкладах.Остатки КАК Остатки
ГДЕ
 Остатки.КоличествоОстаток IS NOT NULL
 И Остатки.КоличествоОстаток <> 0

Совет: Для ресурсов числового типа в виртуальных таблицах 1С часто подставляет 0 вместо NULL (зависит от настроек регистра и параметров виртуальной таблицы). Проверяйте через консоль запросов.

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

Ошибка Почему это плохо Как правильно
ГДЕ Поле = NULL или ГДЕ Поле <> NULL Сравнение с NULL всегда дает NULL (Ложь). Индексы не используются. ГДЕ Поле IS NULL / ГДЕ Поле IS NOT NULL
ГДЕ НЕ (Поле = NULL) Тоже не сработает по той же причине. ГДЕ Поле IS NOT NULL
Использование ЗНАЧЕНИЕ(Строка) для ссылок Ошибка типов. Для ссылок нужно ЗНАЧЕНИЕ(Справочник.Имя). Поле IS NOT NULL (универсально) или Поле <> ЗНАЧЕНИЕ(Справочник.Имя.ПустаяСсылка)
Проверка строки только на IS NOT NULL Пропускает строки с пробелами " " или пустые "". Поле IS NOT NULL И СОКРЛП(Поле) <> ""

Производительность и индексы

  1. IS NOT NULL — лучший друг оптимизатора. СУБД (PostgreSQL, MS SQL, IBM DB2) отлично использует индексы для такого предиката (Index Seek / Index Scan с фильтром).
  2. Функции над полем (СОКРЛП, ВРЕГ, ЕСТЬNULL) в секции ГДЕ часто делают запрос несаргебельным (Non-SARGable) — индекс по этому полю не используется, происходит полное сканирование таблицы (Table Scan / Index Scan).
  3. Если нужно искать по «не пустой строке без пробелов», лучше завести вычисляемое поле в БД (или РВ в 1С) ЕстьАртикул (Булево) и индексировать его.

Практический пример: Комплексная проверка

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

ВЫБРАТЬ
 Товары.Ссылка КАК Номенклатура,
 Товары.Наименование,
 Товары.Артикул,
 Товары.БазоваяЕдиницаИзмерения КАК ЕдИзм
ИЗ
 Справочник.Номенклатура КАК Товары
ГДЕ
 // 1. Артикул не NULL
 Товары.Артикул IS NOT NULL
 // 2. Артикул не пустая строка и не пробелы
 И СОКРЛП(Товары.Артикул) <> ""
 // 3. Единица измерения выбрана (ссылка не пуста)
 И Товары.БазоваяЕдиницаИзмерения IS NOT NULL
УПОРЯДОЧИТЬ ПО
 Товары.Наименование

Резюме: Чек-лист для разработчика

  • По умолчанию используйте IS NOT NULL. Это стандарт, это быстро, это понятно.
  • Для строк добавляйте И СОКРЛП(Поле) <> "", если пустые строки/пробелы недопустимы.
  • Для ссылок IS NOT NULL покрывает все случаи (и NULL в БД, и пустая ссылка).
  • Избегайте функций (ЕСТЬNULL, СОКРЛП) в секции ГДЕ на больших таблицах — это убивает производительность.
  • Помните: NULL <> 0, NULL <> "", NULL <> ПустаяСсылка — все эти сравнения дают Ложь.

Грамотная работа с пустыми значениями — залог корректных отчетов и быстрых запросов. Используйте IS NOT NULL как основной инструмент, и ваши запросы станут надежнее.