NULL в 1С — это не «пусто», а «значение неизвестно». Поэтому в запросе условие Поле = NULL никогда не выполняется, арифметика с NULL возвращает NULL, а во встроенном языке приводит к ошибке. Проверять NULL нужно конструкцией ЕСТЬ NULL или функцией ЕСТЬNULL, а для универсальной проверки заполненности в коде — ЗначениеЗаполнено, помня о её особенностях.
Ниже — набор таких ловушек в самых простых конструкциях: NULL и пустые значения, битые ссылки, текущая дата в разных часовых поясах, форматирование дат и превращение строки в число. Каждая из них хотя бы раз стоила мне часа отладки.
Виды «пустоты» в 1С

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

ТекущаяДата()— системное время компьютера, на котором выполняется код. На клиенте и сервере оно может различаться. В современных конфигурациях функцию не используют.ТекущаяДатаСеанса()— время с учётом часового пояса сеанса. Правильный выбор для дат документов.ТекущаяУниверсальнаяДата()— время UTC.
Пример ловушки. Срок приёма заявок — 10:20, пользователи в Ижевске (UTC+4) и Краснодаре (UTC+3) в один момент выполняют:
СрокПриема = Дата(2026, 2, 6, 10, 20, 0);
Если ТекущаяДатаСеанса() > СрокПриема Тогда
ВызватьИсключение "Приём заявок закрыт";
КонецЕсли;Когда в Краснодаре 10:00, в Ижевске уже 11:00: один пользователь заявку отправит, другой — нет. Если срок — это конкретный момент времени, а не «10:20 по местному времени каждого», храните его в UTC и сравнивайте с универсальным временем:
// Срок задан по времени информационной базы — переводим в UTC один раз
СрокПриемаUTC = УниверсальноеВремя(Дата(2026, 2, 6, 10, 20, 0), ЧасовойПояс());
Если ТекущаяУниверсальнаяДата() > СрокПриемаUTC Тогда
ВызватьИсключение "Приём заявок закрыт";
КонецЕсли;ЧасовойПояс() возвращает часовой пояс информационной базы, ЧасовойПоясСеанса() — сеанса. Перепутать их — ещё один частый источник сдвига на несколько часов.
Форматирование дат
Формат(Дата, "ДЛФ=Д") выводит дату в локальном формате, который зависит от региональных установок информационной базы и сеанса. В одной базе это будет «06.02.2026», в другой — «2026-02-06». Для интерфейса это нормально, а вот для имён файлов, обмена и интеграций — нет.
Когда формат важен, задавайте его явно:
ИмяФайла = "Выгрузка_" + Формат(ТекущаяДатаСеанса(), "ДФ=yyyyMMdd_HHmmss") + ".xml";
ДатаДляAPI = Формат(Дата, "ДФ=yyyy-MM-dd");Для XML и JSON используйте сериализацию платформы (XMLСтрока, ЗаписатьJSON с настройками формата даты), а не Формат.
Строка в число
Число("10") работает, а Число("10 1"), Число("") и строка с запятой вместо точки вызывают исключение «Преобразование значения к типу Число не может быть выполнено». Строки из Excel, сайтов и сканеров часто содержат неразрывные пробелы, разделители разрядов и запятые.
// Преобразует строку в число; при неудаче возвращает ЗначениеПоУмолчанию.
Функция ЧислоИзСтроки(Знач Строка, ЗначениеПоУмолчанию = 0) Экспорт
Если ТипЗнч(Строка) <> Тип("Строка") Тогда
Возврат ЗначениеПоУмолчанию;
КонецЕсли;
Строка = СтрЗаменить(Строка, Символы.НПП, "");
Строка = СтрЗаменить(Строка, " ", "");
Строка = СтрЗаменить(Строка, ",", ".");
Если ПустаяСтрока(Строка) Тогда
Возврат ЗначениеПоУмолчанию;
КонецЕсли;
Попытка
Возврат Число(Строка);
Исключение
Возврат ЗначениеПоУмолчанию;
КонецПопытки;
КонецФункцииЗамена запятой на точку подходит, когда запятая — дробный разделитель. Если во входных данных запятая отделяет разряды («1,250.50»), правила надо определить по источнику, иначе 1 250,5 превратится в 1,25. В БСП есть СтроковыеФункцииКлиентСервер.СтрокаВЧисло — перед использованием посмотрите в своей версии, что она возвращает для некорректной строки.
Типичные ошибки — короткий список
ГДЕ Поле = NULLвместоГДЕ Поле ЕСТЬ NULL.- Умножение на поле из левого соединения без
ЕСТЬNULL. Пустая()у реквизита составного типа.Не ЗначениеЗаполненодля числового или булева реквизита, где 0 и Ложь — нормальные значения.- Проверка существования объекта через
ПолучитьОбъект()в цикле. ТекущаяДата()вместоТекущаяДатаСеанса()и сравнение локальных времён пользователей из разных поясов.Форматбез явной строки формата в именах файлов и интеграциях.Число()без нормализации строки и без обработки исключения.
Большинство таких ошибок не видны на тестовой базе: там нет пустых цен, битых ссылок и пользователей из другого часового пояса. Пишите проверки сразу, а не после первого обращения в поддержку.
Такие ловушки я регулярно нахожу при аудите 1С чужих доработок; исправление обычно занимает минуты, а поиск — часы. Если нужна помощь с конкретной ошибкой, подойдёт консультация или доработка 1С.
Итог
- NULL в 1С проверяется через
ЕСТЬ NULLи заменяется черезЕСТЬNULL; равенство с NULL в запросе не работает. ЗначениеЗаполненобезопаснееПустая(), но считает 0 и Ложь незаполненными.- Битая ссылка заполнена, но объекта нет — проверяйте запросом или
ОбщегоНазначения.СсылкаСуществует. - Для сравнения моментов времени между часовыми поясами используйте универсальное время.
- Форматы дат и преобразование строк в числа задавайте явно и с обработкой ошибок.




