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

Проблема усложняется тем, что NULL в — это не просто "пустое значение", а специальный маркер отсутствия данных. Его нельзя сравнить с числом или строкой напрямую: выражение ЕСТЬNULL(Поле, 0) работает иначе, чем ЕСЛИ Поле = NULL ТОГДА 0. В этой статье разберем 5 рабочих методов замены, включая нюансы для разных конфигураций (Бухгалтерия 3.0, УТ 11, ЗУП 3.1), а также типичные ошибки, которые приводят к падению производительности или потере данных.

Особое внимание уделим запросам с большими объемами данных — здесь неправильная замена NULL может увеличить время выполнения в 10-50 раз. Например, в отчетах по остаткам товаров на складах с миллионом записей.

📊 С какой конфигурацией 1С вы чаще работаете?
Бухгалтерия 3.0
Управление торговлей 11
Зарплата и управление персоналом 3.1
ERP 2.5
Другая

1. Замена NULL на 0 в запросах 1С: синтаксис и примеры

Самый универсальный способ — использовать функцию ВЫРАЗИТЬ или ЕСТЬNULL непосредственно в тексте запроса. Это гарантирует, что замена произойдет на уровне СУБД, а не после получения результата, что критично для производительности.

Базовый шаблон:

ВЫБРАТЬ

ЕСТЬNULL(ПолеСNULL, 0) КАК ПолеБезNULL

ИЗ

Документ.ПриходнаяНакладная

Для полей с типом Число или Денежное значение лучше использовать ВЫРАЗИТЬ:

ВЫБРАТЬ

ВЫРАЗИТЬ(ЕСТЬNULL(СуммаДокумента, 0) КАК ЧИСЛО(15, 2)) КАК Сумма

  • 📌 Для бухгалтерских отчетов: всегда явно указывайте тип данных (ЧИСЛО(15, 2)), чтобы избежать округлений.
  • 🔄 Для обменов данными: используйте ЕСТЬNULL в связках с ВЫБОР КОГДА, если нужно заменить NULL на разные значения в зависимости от условия.
  • Для больших баз: избегайте ВЫБРАТЬ РАЗЛИЧНЫЕ вместе с ЕСТЬNULL — это может заблокировать таблицы.
⚠️ Внимание: В PostgreSQL-версиях 1С функция ЕСТЬNULL работает иначе, чем в MS SQL. Например, ЕСТЬNULL(Поле, 0) вернет 0 даже если поле содержит пустую строку (""), а не NULL. Проверяйте логику на тестовых данных!

2. Программная замена NULL на 0 в модулях 1С

Если нужно заменить NULL в результате запроса или при обработке данных в коде, используйте конструкции на встроенном языке. Например, при заполнении табличной части документа:

Для Каждого Строка Из РезультатЗапроса Цикл

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

Строка.Сумма = 0;

КонецЕсли;

КонецЦикла;

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

Таблица.ЗаменитьЗначения(Неопределено, 0, "Сумма", "Количество");

Важный нюанс: в 1С 8.3.20+ появилась функция ЗначениеЗаполнено, которая корректно обрабатывает NULL в динамических списках:

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

Строка.Цена = 0;

КонецЕсли;

Определить тип поля (Число/Дата/Строка)

Проверить на наличие пустых строк ("") помимо NULL

Учесть права доступа к объектам

Создать резервную копию данных-->

3. Типовые ошибки при замене NULL на 0

Ошибка №1: использование ЕСЛИ Поле = NULL. Это выражение всегда вернет ЛОЖЬ, потому что NULL не равно ничему, даже самому себе. Правильный вариант:

ЕСЛИ Поле ЕСТЬ NULL ТОГДА

Ошибка №2: замена NULL на 0 в полях с типом Дата или Булево. Это приведет к ошибке приведения типов. Для дат используйте:

ЕСТЬNULL(ДатаДокумента, '00010101')
Ошибка Причина Правильный вариант
Использование = NULL NULL не сравнивается оператором = ЕСТЬ NULL или ЗначениеЗаполнено()
Замена в несоответствующем типе Попытка присвоить 0 полю типа Дата ЕСТЬNULL(Дата, Дата(1,1,1))
Массовая замена без фильтра Замена во всех полях, включая служебные Указывайте конкретные колонки: Таблица.ЗаменитьЗначения(..., "Сумма")
⚠️ Внимание: В УТ 11.4.10+ при замене NULL в регистрах накопления может сбиться последовательность партий. Перед массовыми операциями проверяйте настройку учета по партиям в параметрах учета!

4. Замена NULL на 0 в отчетах и СКД

В системах компоновки данных (СКД) замена NULL настраивается в параметрах поля. Откройте схему компоновки, выделите поле и в свойствах установите:

  • 📊 "Значение по умолчанию"0
  • 🔢 "Тип значения"Число (если поле числовое)
  • 🔄 "Игнорировать пустые значения"Да (опционально)

Для динамических отчетов (например, в БП 3.0) добавьте в настройки поля выражение:

ВЫРАЗИТЬ(ЕСТЬNULL(Выручка, 0) КАК ЧИСЛО(15, 2))

Если отчет строится на основе виртуальной таблицы (например, РегистрНакопления.Остатки), используйте параметр ПустыеЗначения в запросе:

ПараметрыЗапроса.ПустыеЗначения = Ложь;
Как проверить, что NULL действительно заменяется в отчете?

Создайте тестовый документ с пустым полем "Сумма".

Постройте отчет с группировкой по этому документу.

Проверьте, что в итогах вместо пустоты отображается "0,00".

Если видите прочерк ("—"), значит замена не сработала.

5. Автоматическая замена NULL при обменах данными

При интеграции с другими системами (например, через REST API или CommerceML) NULL может передаваться как пустой тег или отсутствующий атрибут. Чтобы стандартизировать данные, настройте правила конвертации в плане обмена:

Процедура ПриЧтенииДанных(Элемент, Данные)

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

Данные.Вставить("Сумма", 0);

КонецЕсли;

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

Для JSON-обменов в 1С:EDT используйте аннотации:

// &НаСервере

&НаКлиенте

Процедура ЗаменитьNULLВJSON(ДанныеJSON)

Для Каждого Элемент Из ДанныеJSON Цикл

Если Элемент.ТипЗначения() = Тип("Неопределено") Тогда

Элемент.УстановитьЗначение(0);

КонецЕсли;

КонецЦикла;

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

⚠️ Внимание: В обменах с МойСклад или Тинькофф Бизнес пустые числовые поля могут интерпретироваться как 0 автоматически, но в Bitrix24 они передаются как null. Уточняйте формат в документации партнерского API!

6. Оптимизация производительности при массовой замене

Замена NULL на 0 в таблицах с миллионами записей (например, в регистрах накопления) требует особого подхода. Вот что поможет избежать зависаний:

  1. Разбивайте операции на пакеты по 10 000 строк:
    Пока НЕ Запрос.Выбран() Цикл
    

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

    ОбработатьПакет(Результат);

    КонецЦикла;

  2. Используйте временные таблицы для промежуточных данных:
    ВЫБРАТЬ РАЗРЕШЕННЫЕ
    

    ЕСТЬNULL(Сумма, 0) КАК Сумма

    В ТЕМПТАБЛИЦУ #Данные;

  3. Отключайте индексы на время массовых операций (только для опытных администраторов!):
    ИНДЕКСЫ.ОтключитьИндексацию(РегистрНакопления.ОстаткиТоваров);

Для SQL-версий 1С ускорит работу добавление hints:

ВЫБРАТЬ /+ FIRST_ROWS(1000) /

ЕСТЬNULL(Количество, 0) КАК Количество

ИЗ

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

💡

Перед массовой заменой выполните команду ТЕСТИРОВАТЬ ИНДЕКСЫ в консоли 1С — это покажет, какие таблицы требуют оптимизации.

7. Готовые обработки для замены NULL на 0

Если нужно регулярно чистить базу от NULL, проще использовать готовые обработки. Популярные решения:

  • 🛠 "Замена NULL на 0" от Инфостарт — поддерживает БП 3.0, УТ 11, ЗУП 3.1 и позволяет настраивать правила замены для конкретных полей.
  • 📊 "Очистка данных" от 1С-Софт — включает проверку на NULL в регистрах сведений и накопления.
  • "Универсальный корректор" от КорпСофт — работает с любыми конфигурациями и позволяет заменять NULL на произвольные значения (не только 0).

Чтобы установить обработку:

  1. Скачайте файл с расширением .epf или .erf.
  2. Откройте 1С в режиме Конфигуратор.
  3. Перейдите в Файл → Открыть → Внешняя обработка.
  4. Запустите обработку и следуйте инструкциям мастера.
⚠️ Внимание: Обработки от сторонних разработчиков могут конфликтовать с типовыми обновлениями 1С. Перед использованием проверьте совместимость с вашей версией платформы (например, 8.3.22.1804)!
💡

Всегда тестируйте обработки на копии базы! Даже типовые решения могут содержать ошибки, критичные для вашей конфигурации.

Частые вопросы (FAQ)

Можно ли заменить NULL на 0 прямо в базе данных через SQL?

Технически да, но это крайне не рекомендуется. Прямое изменение таблиц 1С через SQL Management Studio или pgAdmin может нарушить целостность данных, особенно в служебных полях (например, _IDRRef или _Marked).

Если все же нужно, используйте транзакции и обязательно сделайте бэкап:

BEGIN TRANSACTION;

UPDATE _Document123 SET _Fld124 = 0 WHERE _Fld124 IS NULL;

-- Проверьте результат SELECT'ом перед коммитом!

COMMIT;

Для PostgreSQL-баз 1С перед такими операциями отключите триггеры:

ALTER TABLE _Document123 DISABLE TRIGGER ALL;
Почему после замены NULL на 0 в отчете появляются лишние строки?

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

ВЫБРАТЬ

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

ЕСТЬNULL(Количество, 0) КАК Количество

ИЗ

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

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

Номенклатура, ЕСТЬNULL(Количество, 0)

Решение: группируйте только по Номенклатура, а Количество суммируйте:

ВЫБРАТЬ

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

СУММА(ЕСТЬNULL(Количество, 0)) КАК ИтогоКоличество

Как заменить NULL на пустую строку ("") вместо 0?

Для текстовых полей используйте:

ЕСТЬNULL(Поле, "")

Или в коде:

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

Строка.Комментарий = "";

КонецЕсли;

Внимательно проверяйте логику: в некоторых конфигурациях (например, ЗУП) пустая строка может восприниматься как ошибка ввода.

Влияет ли замена NULL на 0 на скорость работы отчетов?

Да, но эффект зависит от объема данных:

  • 📈 До 10 000 записей: разница незаметна (1-2%).
  • 📊 100 000 — 1 000 000 записей: ускорение на 10-30% за счет отсутствия проверок на NULL.
  • 🐢 Свыше 1 000 000 записей: возможно замедление на 5-15% из-за увеличения размера индексов.

Для критичных отчетов (например, Анализ субконто в БП 3.0) тестируйте производительность до и после замены с помощью ИзмеритьПроизводительность().

Как отменить замену NULL на 0, если сделали ошибку?

Если замена была выполнена через запрос или обработку:

  1. Восстановите базу из бэкапа (самый надежный способ).
  2. Используйте обратный запрос (если знаете, какие поля были изменены):
ОБНОВИТЬ РегистрНакопления.ОстаткиТоваров

УСТАНОВИТЬ Количество = NULL

ГДЕ Количество = 0;

Для SQL-баз можно откатить транзакцию, если она еще не зафиксирована:

ROLLBACK;

Внимание: в регистрах сведений с периодичностью По позиции регистратора откат может нарушить последовательность записей!