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

Особенность заключается в том, что здесь нет классического SQL-подхода к NULL: вместо трёхзначной логики (TRUE/FALSE/UNKNOWN) используется собственная система сравнений. Например, выражение Значение = NULL всегда вернёт Ложь, даже если поле действительно пустое. Это требует специальных приёмов для корректного отбора данных.

Статья будет полезна как начинающим разработчикам, так и опытным программистам, которые хотят оптимизировать запросы или избежать типичных ошибок при работе с ненулевыми значениями в конфигурациях 1С:УТ, 1С:БП, 1С:ЗУП и других.

1. Основы работы с NULL в 1С: что нужно знать

В 1С:Предприятие понятие NULL тесно связано с типами данных и контекстом выполнения:

  • 📌 В запросах: NULL обозначает отсутствие значения в поле базы данных. Например, если в документе не заполнено поле "Комментарий", оно будет NULL.
  • 📌 В коде на встроенном языке: аналогом NULL является Неопределённое значение (ТипЗнч(Неопределено)).
  • 📌 В внешних источниках: при обмене данными (например, через REST API или JSON) NULL может преобразовываться в пустую строку или undefined.

Ключевое отличие от SQL: в нельзя использовать оператор IS NULL напрямую. Вместо этого применяются специальные функции:

  • 🔹 ЕстьNULL(Значение, Замена) — возвращает Замена, если Значение равно NULL.
  • 🔹 ЗначениеЗаполнено(Значение) — проверяет, что значение не пустое и не NULL.
  • 🔹 ВЫБРАТЬ РАЗРЕШЕННЫЕ... — в запросах используется конструкция ГДЕ НЕ Значение ЕСТЬ NULL.
⚠️ Внимание: В старых версиях платформы (до 1С 8.3.6) функция ЗначениеЗаполнено() могла работать некорректно с некоторыми типами данных (например, с Дата или Булево). Перед использованием проверьте поведение на вашей версии.

Пример типичной ошибки: если вы напишете в запросе ГДЕ Поле <> NULL, то получите пустой результат, даже если в базе есть ненулевые значения. Правильный синтаксис: ГДЕ НЕ Поле ЕСТЬ NULL.

2. Поиск ненулевых значений в запросах 1С

Самый распространённый способ отбора ненулевых данных — использование конструкции ЕСТЬ NULL в языке запросов. Рассмотрим базовые шаблоны:

2.1. Простой отбор по одному полю

Допустим, нам нужно найти все документы "Заказ клиента", где заполнено поле "Комментарий":

ВЫБРАТЬ

ЗаказКлиента.Ссылка КАК Ссылка,

ЗаказКлиента.Комментарий КАК Комментарий

ИЗ

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

ГДЕ

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

Обратите внимание на ключевое слово НЕ перед проверкой. Без него запрос вернёт записи, где комментарий пустой.

2.2. Отбор по нескольким полям

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

ВЫБРАТЬ

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

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

Номенклатура.Описание КАК Описание

ИЗ

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

ГДЕ

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

ИЛИ НЕ Номенклатура.Описание ЕСТЬ NULL

Для обратной задачи (где все поля ненулевые) замените ИЛИ на И.

2.3. Работа с параметрами запроса

Если значение для сравнения передаётся как параметр, используйте функцию ЕстьNULL:

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| Контрагенты.Ссылка КАК Контрагент,

| Контрагенты.ИНН КАК ИНН

|ИЗ

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

|ГДЕ

| НЕ ЕстьNULL(Контрагенты.ИНН, """") = &ПустоеЗначение";

Запрос.УстановитьПараметр("ПустоеЗначение", "");

Результат = Запрос.Выполнить();

Здесь мы заменяем NULL на пустую строку и сравниваем с параметром. Такой подход полезен, если нужно унифицировать обработку пустых значений в отчётах.

📊 Какой метод поиска ненулевых значений вы используете чаще?
Запросы 1С
Встроенный язык (ЗначениеЗаполнено)
Обход коллекций в коде
Другое

3. Программные методы проверки на NULL

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

3.1. Функция ЗначениеЗаполнено()

Самый надёжный способ проверить, что значение не пустое:

Если ЗначениеЗаполнено(ДокументОбъект.Комментарий) Тогда

Сообщить("Комментарий заполнен: " + ДокументОбъект.Комментарий);

КонецЕсли;

Функция возвращает Истина для:

  • 📌 Ненулевых ссылок на объекты (документы, справочники).
  • 📌 Непустых строк (даже если это пробел).
  • 📌 Числовых значений (включая 0).
  • 📌 Дат (включая '00010101').

Но она вернёт Ложь для:

  • 🚫 NULL (в запросах) или Неопределено (в коде).
  • 🚫 Пустых строк ("").
  • 🚫 Пустых коллекций (массивов, списков значений).

3.2. Проверка на Неопределено

Для явной проверки на NULL-аналог в коде используйте:

Если ДокументОбъект.СуммаДокумента = Неопределено Тогда

Сообщить("Сумма не указана!");

Иначе

Сообщить("Сумма: " + Формат(ДокументОбъект.СуммаДокумента, "ЧДЦ=2"));

КонецЕсли;

Важно: сравнение с Неопределено работает только для переменных, которые действительно не инициализированы. Для полей объектов (например, реквизитов документов) лучше использовать ЗначениеЗаполнено.

3.3. Работа с коллекциями

При обходе массивов или таблиц значений проверяйте элементы на NULL явно:

Для Каждого Строка Из ТаблицаЗначений Цикл

Если НЕ ЗначениеЗаполнено(Строка.Количество) Тогда

Продолжить; // Пропускаем строки с NULL

КонецЕсли;

// Обработка ненулевых значений

КонецЦикла;

В больших таблицах (10 000+ строк) такой обход может тормозить. Для ускорения предварительно отфильтруйте данные запросом.

☑️ Проверка коллекций на NULL

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

4. Типичные ошибки и как их избежать

Даже опытные разработчики иногда допускают ошибки при работе с NULL в . Разберём самые распространённые:

4.1. Сравнение с NULL через "="

Классическая ошибка — попытка сравнить значение с NULL напрямую:

// НЕПРАВИЛЬНО!

Если Документ.ДатаДоставки = NULL Тогда

// Этот код никогда не выполнится

КонецЕсли;

Правильный вариант:

Если НЕ ЗначениеЗаполнено(Документ.ДатаДоставки) Тогда

Сообщить("Дата доставки не указана!");

КонецЕсли;

4.2. Игнорирование типов данных

Функция ЗначениеЗаполнено может вести себя по-разному для разных типов. Например:

Тип данныхЗначениеЗначениеЗаполнено()
Строка""Ложь
Число0Истина
Дата'00010101'Истина
СсылкаНеопределеноЛожь
БулевоЛожьИстина

Это может приводить к неожиданным результатам. Например, если вы проверяете числовое поле на заполненность, 0 будет считаться ненулевым значением.

4.3. Путаница между NULL и пустой строкой

В NULL и пустая строка ("") — это разные вещи. Например, в запросе:

ГДЕ НЕ Поле = ""

не эквивалентно:

ГДЕ НЕ Поле ЕСТЬ NULL

Первый запрос вернёт все записи, где поле не пустое (включая NULL), а второй — где поле не NULL (включая пустые строки).

⚠️ Внимание: При обмене данными через XML или JSON пустые строки могут автоматически преобразовываться в NULL и наоборот. Всегда проверяйте формат данных на стыках систем.

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

При работе с большими базами данных (100 000+ записей) неправильно составленные запросы с проверкой на NULL могут значительно тормозить систему. Рассмотрим способы оптимизации:

5.1. Использование индексов

Если вы часто фильтруете данные по полю с проверкой на NULL, убедитесь, что это поле проиндексировано. Например, для справочника "Контрагенты" по полю "ИНН":

ИНДЕКСИРОВАТЬ ПО ИНН

Добавляется в конфигураторе в свойствах реквизита. Ускоряет запросы вида:

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

5.2. Замена EстьNULL на CASE

В сложных отчётах вместо многократного использования ЕстьNULL можно применять конструкцию ВЫБОР:

ВЫБРАТЬ

ВЫБОР

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

ТОГДА "Без артикула"

ИНАЧЕ Номенклатура.Артикул

КОНЕЦ КАК Артикул

ИЗ

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

Это уменьшает количество вызовов функций и ускоряет выполнение.

5.3. Разделение запросов

Если вам нужно получить данные с разными условиями по NULL, иногда эффективнее сделать два отдельных запроса и объединить результаты:

// Запрос 1: ненулевые значения

Запрос1 = Новый Запрос("ВЫБРАТЬ ... ГДЕ НЕ Поле ЕСТЬ NULL");

// Запрос 2: NULL значения

Запрос2 = Новый Запрос("ВЫБРАТЬ ... ГДЕ Поле ЕСТЬ NULL");

// Объединение результатов

Результат = Новый ТаблицаЗначений;

Результат.Загрузить(Запрос1.Выполнить().Выгрузить());

Результат.Загрузить(Запрос2.Выполнить().Выгрузить());

Такой подход может быть быстрее, чем один сложный запрос с множеством условий.

💡

Перед оптимизацией запросов проверьте план выполнения в консоли запросов (меню "Все функции" → "План запроса"). Это поможет выявить узкие места.

6. Практические примеры для типовых конфигураций

Рассмотрим, как применять рассмотренные методы в реальных конфигурациях .

6.1. 1С:Бухгалтерия — поиск проводок без субконто

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

ВЫБРАТЬ

РегистрБухгалтерииХоз.Период КАК Период,

РегистрБухгалтерииХоз.СчетДт КАК СчетДт,

РегистрБухгалтерииХоз.Сумма КАК Сумма

ИЗ

РегистрБухгалтерии.Хозрасчетный КАК РегистрБухгалтерииХоз

ГДЕ

РегистрБухгалтерииХоз.СубконтоДт0 ЕСТЬ NULL

Здесь СубконтоДт0 — первое субконто по дебету. Для проверки всех субконто используйте:

ГДЕ

РегистрБухгалтерииХоз.СубконтоДт0 ЕСТЬ NULL

И РегистрБухгалтерииХоз.СубконтоДт1 ЕСТЬ NULL

И РегистрБухгалтерииХоз.СубконтоДт2 ЕСТЬ NULL

6.2. 1С:Зарплата и Управление Персоналом — сотрудники без фотографий

Чтобы найти сотрудников, у которых не загружена фотография (поле "Фото" равно NULL):

ВЫБРАТЬ

Сотрудники.Ссылка КАК Сотрудник,

Сотрудники.Наименование КАК ФИО

ИЗ

Справочник.Сотрудники КАК Сотрудники

ГДЕ

Сотрудники.Фото ЕСТЬ NULL

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

Если НЕ ЗначениеЗаполнено(СотрудникОбъект.Фото) Тогда

Сообщить("У сотрудника " + СотрудникОбъект.Наименование + " нет фотографии");

КонецЕсли;

6.3. 1С:Управление Торговлей — товары без штрихкодов

Запрос для поиска номенклатуры без штрихкодов:

ВЫБРАТЬ

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

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

ИЗ

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

ГДЕ

НЕ СУЩЕСТВУЕТ (

ВЫБРАТЬ

ШтрихкодыНоменклатурыСсылка

ИЗ

РегистрСведений.ШтрихкодыНоменклатуры КАК ШтрихкодыНоменклатуры

ГДЕ

ШтрихкодыНоменклатуры.Номенклатура = Номенклатура.Ссылка

)

Альтернативный вариант (если штрихкоды хранятся в табличной части):

ВЫБРАТЬ

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

ИЗ

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

ГДЕ

НЕ Номенклатура.Штрихкоды.Количество() > 0

7. Работа с NULL в обменах данными и интеграциях

При обмене данными между системами (например, и Bitrix, и Excel) обработка NULL требует особого внимания. Рассмотрим ключевые моменты:

7.1. NULL в JSON/XML

При экспорте данных в JSON пустые значения в могут преобразовываться по-разному:

  • 📌 NULL в базе → null в JSON.
  • 📌 Пустая строка → "".
  • 📌 Неопределено → может стать null или отсутствовать в объекте.

Пример обработки при чтении JSON:

ДанныеJSON = ПрочитатьJSON(СтрокаJSON);

Если ДанныеJSON.Свойство("Поле") = Неопределено Тогда

// Поле отсутствует в JSON или равно null

ИначеЕсли ДанныеJSON.Поле = Null Тогда

// Поле присутствует, но равно null

Иначе

// Поле имеет значение

КонецЕсли;

7.2. NULL в обменах через REST API

При отправке данных на внешний сервис важно явно указывать, как обрабатывать пустые значения. Например, в HTTP-запросе:

Запрос = Новый HTTPЗапрос("/api/update");

Тело = Новый Структура;

Тело.Вставить("ИНН", ?(ЗначениеЗаполнено(Контрагент.ИНН), Контрагент.ИНН, Null));

Запрос.УстановитьТелоИзСтроки(ЗаписатьJSON(Тело));

Здесь оператор ?(Условие, Значение1, Значение2) позволяет отправлять null вместо пустой строки.

7.3. NULL в выгрузке в Excel

При выгрузке таблиц в Excel через COM-объект или ADODB пустые ячейки могут интерпретироваться как NULL. Чтобы избежать ошибок:

Для Каждого Строка Из ТаблицаДанных Цикл

Значение = ?(ЗначениеЗаполнено(Строка.Поле), Строка.Поле, "");

ЛистExcel.Cells(НомерСтроки, НомерСтолбца).Value = Значение;

КонецЦикла;

Здесь мы заменяем NULL на пустую строку, чтобы Excel корректно отобразил данные.

⚠️ Внимание: При обмене с 1С:EDT или другими современными инструментами разработки правила обработки NULL могут отличаться. Всегда проверяйте документацию к конкретному механизму обмена.

8. Автоматизация проверки ненулевых значений

Для упрощения работы с NULL можно создать универсальные функции или обработки, которые будут использоваться во всех проектах.

8.1. Универсальная функция проверки

Пример функции, которая работает и в коде, и в запросах:

Функция ЗначениеНенулевое(Значение, Замена = Неопределено)

Если НЕ ЗначениеЗаполнено(Значение) Тогда

Возврат Замена;

Иначе

Возврат Значение;

КонецЕсли;

КонецФункции

Использование:

ИНН = ЗначениеНенулевое(Контрагент.ИНН, "НЕ УКАЗАН");

8.2. Обработка для массовой проверки

Создайте обработку, которая сканирует выбранные справочники или документы на наличие пустых полей:

Процедура ПроверитьНаNULL(ТаблицаДанных)

Результат = Новый Структура;

Для Каждого Колонка Из ТаблицаДанных.Колонки Цикл

Счетчик = 0;

Для Каждого Строка Из ТаблицаДанных Цикл

Если НЕ ЗначениеЗаполнено(Строка[Колонка.Имя]) Тогда

Счетчик = Счетчик + 1;

КонецЕсли;

КонецЦикла;

Если Счетчик > 0 Тогда

Результат.Вставить(Колонка.Имя, Счетчик);

КонецЕсли;

КонецЦикла;

Возврат Результат;

КонецПроцедуры

Такая обработка вернёт структуру с именами полей и количеством пустых значений.

8.3. Интеграция с отчётами

Добавьте в стандартные отчёты (например, "Анализ заполненности данных") колонку с проверкой на NULL:

ВЫБРАТЬ

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

ВЫБОР

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

ТОГДА "Нет"

ИНАЧЕ "Да"

КОНЕЦ КАК АртикулЗаполнен

ИЗ

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

Это поможет быстро оценивать качество данных в базе.

💡

Автоматизация проверки на NULL экономит время при аудите данных и снижает риск ошибок в отчётах.

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

Как отличить NULL от пустой строки в запросе?

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

ГДЕ Поле ЕСТЬ NULL

Для пустых строк:

ГДЕ Поле = ""

Для обоих случаев:

ГДЕ (Поле ЕСТЬ NULL ИЛИ Поле = "")
Почему функция ЗначениеЗаполнено() возвращает Истина для числа 0?

Это особенность : функция ЗначениеЗаполнено() считает заполненными все числовые значения, включая 0, так как нулём может обозначаться реальное количество (например, остаток на складе). Если вам нужно игнорировать 0, добавьте явную проверку:

Если ЗначениеЗаполнено(Значение) И Значение <> 0 Тогда

// Обработка ненулевых чисел

КонецЕсли;

Как найти все документы, где не заполнено хотя бы одно обязательное поле?

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

ВЫБРАТЬ

Документ.Ссылка

ИЗ

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

ГДЕ

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

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

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

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

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

Нет, в языке запросов нет оператора IS NULL. Вместо него используется конструкция ЕСТЬ NULL:

ГДЕ Поле ЕСТЬ NULL  // вместо IS NULL

ГДЕ НЕ Поле ЕСТЬ NULL // вместо IS NOT NULL

Как обработать NULL при загрузке данных из Excel?

При чтении данных из Excel пустые ячейки могут приходить как NULL или пустые строки. Универсальный способ обработки:

Значение = ?(ТипЗнч(ЗначениеИзExcel) = Тип("Null"), Неопределено, ЗначениеИзExcel);

Значение = ?(Значение = "", Неопределено, Значение);

Это преобразует и NULL, и пустые строки в Неопределено для дальнейшей унифицированной обработки.