Работа с запросами в 1С:Предприятие часто требует проверки, заполнен ли тот или иной реквизит перед его использованием в условиях или вычислениях. Неправильная обработка пустых значений может приводить к ошибкам выполнения, некорректным отчётам или даже падению системы при массовой обработке данных. В этой статье разберём все актуальные способы проверки заполненности — от элементарных конструкций ЕСТЬ NULL до нюансов работы с составными типами и динамическими списками.
Особое внимание уделим типичным ошибкам, которые допускают даже опытные разработчики. Например, почему проверка ЗНАЧЕНИЕ ЗАПОЛНЕНО() в некоторых случаях работает не так, как ожидается, или как отличить действительно пустое значение от нулевой даты. Материал будет полезен как начинающим программистам 1С, так и тем, кто хочет систематизировать свои знания по работе с запросами.
1. Базовые методы проверки: ЕСТЬ NULL и ЗНАЧЕНИЕ ЗАПОЛНЕНО()
Самый распространённый и универсальный способ проверки — использование конструкции ЕСТЬ NULL непосредственно в тексте запроса. Этот оператор работает со всеми типами данных и возвращает true, если значение не заполнено (равно NULL в терминологии СУБД). Пример:
ВЫБРАТЬ
Справочник.Контрагенты.Наименование КАК Контрагент,
Справочник.Контрагенты.ИНН КАК ИНН
ИЗ
Справочник.Контрагенты КАК Справочник.Контрагенты
ГДЕ
Справочник.Контрагенты.ИНН ЕСТЬ NULL
Важно понимать, что ЕСТЬ NULL проверяет именно состояние поля в базе данных, а не его представление в 1С. Для проверки заполненности в коде на встроенном языке часто используют функцию ЗНАЧЕНИЕЗАПОЛНЕНО(). Однако здесь есть нюанс:
- 🔹
ЕСТЬ NULLв запросе — проверяет NULL на уровне СУБД (работает всегда) - 🔹
ЗНАЧЕНИЕЗАПОЛНЕНО()в коде — проверяет неопределённость на уровне 1С (может давать ложноположительные срабатывания) - 🔹
ПУСТОЕЗНАЧЕНИЕ()— возвращает пустое значение текущего типа (полезно для сравнений)
Распространённая ошибка: пытаться использовать ЗНАЧЕНИЕЗАПОЛНЕНО() непосредственно в тексте запроса. Это приведёт к синтаксической ошибке, так как функция доступна только на встроенном языке. Для аналогичной логики в запросах используйте:
ВЫБРАТЬ
Справочник.Номенклатура.Наименование КАК Товар
ИЗ
Справочник.Номенклатура КАК Справочник.Номенклатура
ГДЕ
НЕ Справочник.Номенклатура.Артикул ЕСТЬ NULL
2. Проверка заполненности составных типов данных
Особую сложность представляют составные типы — такие как ХранилищеЗначения, ДвоичныеДанные или ГрафическаяСхема. Для них стандартная проверка ЕСТЬ NULL может работать некорректно, так как технически объект существует, но его содержимое пустое. Рассмотрим типичные случаи:
| Тип данных | Корректная проверка в запросе | Проверка на встроенном языке |
|---|---|---|
ХранилищеЗначения |
ЗНАЧЕНИЕ(ДЛСТР(Хранилище)) = 0 |
Хранилище.Пустое() |
ДвоичныеДанные |
ДЛСТР(ДвоичныеДанные) = 0 |
ДвоичныеДанные.Размер() = 0 |
ГрафическаяСхема |
ЗНАЧЕНИЕ(ГрафическаяСхема) ЕСТЬ NULL |
ГрафическаяСхема = Неопределённо |
Для ХранилищеЗначения важно понимать, что даже если оно технически существует (не NULL), его содержимое может быть пустым. В запросах это проверяется через функцию ДЛСТР(), которая возвращает длину хранимых данных. На встроенном языке для этого есть метод .Пустое().
С ДвоичнымиДанными ситуация аналогичная — проверяем размер файла. А вот ГрафическаяСхема ведёт себя как обычный объект: если не заполнена, то равна NULL/Неопределённо.
Для проверки заполненности реквизита типа ХранилищеЗначения в отчётах используйте выражение ВЫРАЗИТЬ(ДЛСТР(Хранилище) > 0 КАК БУЛЕВО) — это позволит корректно отображать галочки в колонках.
3. Работа с датами и числами: нюансы проверки
С реквизитами типа Дата и Число часто возникает путаница. Дело в том, что пустая дата в 1С — это не NULL, а специальное значение '00010101' (1 января 1 года). Аналогично, пустое число — это ноль, а не NULL. Это приводит к типичным ошибкам:
- ❌
ГДЕ ДатаДокумента ЕСТЬ NULL— не найдёт пустые даты! - ✅
ГДЕ ДатаДокумента = ДАТАВРЕМЯ(1,1,1)— правильный вариант - ❌
ГДЕ СуммаДокумента = NULL— синтаксическая ошибка - ✅
ГДЕ СуммаДокумента = 0— если нужно найти нулевые суммы
Для универсальной проверки (на случай, если в поле может быть и NULL, и пустая дата) используйте комбинированное условие:
ВЫБРАТЬ
Документ.ПоступлениеТоваров.Дата КАК ДатаПоступления
ИЗ
Документ.ПоступлениеТоваров КАК Документ.ПоступлениеТоваров
ГДЕ
Документ.ПоступлениеТоваров.Дата ЕСТЬ NULL
ИЛИ Документ.ПоступлениеТоваров.Дата = ДАТАВРЕМЯ(1,1,1)
С числами ситуация проще, но здесь важно понимать разницу между пустым значением (0) и неопределённым (NULL). Если в вашей конфигурации числовые реквизиты могут хранить NULL (например, после миграции данных), всегда проверяйте оба варианта.
Почему пустая дата — это 00010101?
В 1С:Предприятие внутреннее представление даты основано на количестве дней с 1 января 1 года. Значение 0 соответствует этой дате, поэтому оно используется как "нулевое" для типа Дата. Это наследие архитектурных решений платформы, сохранённое для обратной совместимости.
4. Проверка заполненности в динамических списках и отчётах
При работе с динамическими списками или системой компоновки данных (СКД) проверка заполненности имеет свои особенности. Здесь нельзя напрямую использовать ЕСТЬ NULL в настройках отчёта. Вместо этого применяют:
- Условное оформление — для визуального выделения пустых значений
- Отборы — для фильтрации данных перед выводом
- Вычисляемые поля — для создания флагов заполненности
Пример настройки условного оформления в СКД для выделения пустых ИНН:
- Откройте настройки отчёта → вкладка
Условное оформление - Добавьте новое правило с условием:
ЗНАЧЕНИЕ(ИНН) = "" - Задайте формат (например, красный цвет текста)
Для отборов в динамических списках используйте параметры с типом Булево и формулами вида:
НЕ ПУСТОЕЗНАЧЕНИЕ(ИНН) И НЕ ИНН = ""
Важно: в СКД пустые значения часто представлены как пустые строки (""), а не как NULL. Это связано с особенностями преобразования типов при выводе данных. Поэтому для надёжной проверки комбинируйте оба условия.
Настроить отбор по условию ЗНАЧЕНИЕЗАПОЛНЕНО(Реквизит)|Добавить вычисляемое поле с флагом заполненности|Проверить условное оформление для пустых значений|Учесть преобразование типов (NULL → пустая строка)-->
5. Типичные ошибки и как их избежать
Даже опытные разработчики иногда допускают ошибки при проверке заполненности. Вот наиболее распространённые ловушки и способы их обхода:
⚠️ Внимание! При использовании функцииВЫРАЗИТЬ()для преобразования типов пустые значения могут некорректно интерпретироваться. Например,ВЫРАЗИТЬ(NULL КАК СТРОКА)вернёт пустую строку, а неNULL.
- 🚫 Ошибка: Использование
= NULLвместоЕСТЬ NULL
Последствия: Запрос не найдёт пустые значения (синтаксическая ошибка в большинстве СУБД) - 🚫 Ошибка: Проверка
ЗНАЧЕНИЕЗАПОЛНЕНО()для полей БД в запросе
Последствия: Ошибка выполнения — функция недоступна в языке запросов - 🚫 Ошибка: Игнорирование разницы между
NULLи пустыми строками/нулями
Последствия: Пропуск части данных в отчётах
Ещё один коварный момент — работа с виртуальными таблицами (например, Документ.ПоступлениеТоваров.Товары). В них пустые реквизиты могут представляться по-разному в зависимости от версии платформы. Всегда тестируйте запросы на реальных данных!
Критическая особенность: в запросах к регистрам накопления пустые ресурсы (например, не заполненное количество) могут не отображаться в результатах вообще, а не как NULL. Это связано с оптимизацией хранения данных в СУБД.
6. Продвинутые техники: использование ВЫБОР и КОГДА
Для сложной логики проверки заполненности удобно использовать конструкции ВЫБОР КОГДА. Это позволяет не только проверять пустоту, но и сразу подставлять альтернативные значения. Пример:
ВЫБРАТЬ
ВЫБОР
КОГДА Справочник.Контрагенты.ИНН ЕСТЬ NULL
ТОГДА "ИНН не указан"
КОГДА Справочник.Контрагенты.ИНН = ""
ТОГДА "ИНН пустой"
ИНАЧЕ Справочник.Контрагенты.ИНН
КОНЕЦ КАК СтатусИНН,
Справочник.Контрагенты.Наименование КАК Контрагент
ИЗ
Справочник.Контрагенты КАК Справочник.Контрагенты
Этот подход особенно полезен для:
- 📊 Формирования сводных отчётов с индикацией проблемных записей
- 🔄 Подготовки данных для обмена (замена пустых значений на значения по умолчанию)
- 📋 Создания пользовательских представлений данных с поясняющими метками
С конструкцией ВЫБОР можно комбинировать любые условия, включая проверку длины строк, диапазоны дат и т.д. Это делает её одним из самых мощных инструментов для работы с неполными данными.
Конструкция ВЫБОР КОГДА позволяет не только проверять заполненность, но и сразу трансформировать данные в удобный для отображения формат. Это сокращает объём пост-обработки на клиенте.
7. Оптимизация запросов с проверкой пустых значений
Массовая проверка заполненности может существенно замедлять выполнение запросов, особенно на больших базах данных. Вот несколько приёмов для оптимизации:
- Индексирование — убедитесь, что поля, по которым идёт проверка на
NULL, проиндексированы в СУБД - Ограничение выборки — используйте
РАЗЛИЧНЫЕилиПЕРВЫЕ, если не нужны все записи - Объединение условий — группируйте проверки в одном условии через
И/ИЛИ
Пример оптимизированного запроса для поиска документов с незаполненными реквизитами:
ВЫБРАТЬ РАЗЛИЧНЫЕ
Документ.РеализацияТоваровУслуг.Ссылка КАК Ссылка
ИЗ
Документ.РеализацияТоваровУслуг КАК Документ.РеализацияТоваровУслуг
ГДЕ
Документ.РеализацияТоваровУслуг.Контрагент ЕСТЬ NULL
ИЛИ Документ.РеализацияТоваровУслуг.ДатаДокумента = ДАТАВРЕМЯ(1,1,1)
ИЛИ ДЛСТР(Документ.РеализацияТоваровУслуг.Комментарий) = 0
ИТОГИ ПО
Ссылка
Для ускорения работы с большими наборами данных рассмотрите возможность использования временных таблиц. Они позволяют сначала отфильтровать записи с пустыми значениями, а затем работать уже с уменьшенным набором данных.
⚠️ Внимание! Поведение запросов с проверкой ЕСТЬ NULL может отличаться в разных СУБД (MS SQL, PostgreSQL, IBM DB2). Всегда тестируйте критические запросы на целевой платформе.
FAQ: Частые вопросы по проверке заполненности
Как проверить заполненность реквизита типа "Строка" длиной более 0 символов?
Используйте функцию ДЛСТР() в запросе или СТРДЛИНА() на встроенном языке:
ГДЕ ДЛСТР(Справочник.Номенклатура.Артикул) > 0
Это гарантированно отфильтрует как NULL, так и пустые строки.
Почему условие ГДЕ Поле = "" не находит пустые строки в запросе?
В языке запросов 1С пустые строки и NULL — разные вещи. Используйте:
ГДЕ (Поле ЕСТЬ NULL ИЛИ Поле = "")
Или универсальный вариант:
ГДЕ ЗНАЧЕНИЕ(Поле) = ""
Как проверить заполненность реквизита в управляемой форме без запроса?
В модуле формы используйте:
Если НЕ ЗначениеЗаполнено(Объект.Реквизит) Тогда
// Обработка пустого значения
КонецЕсли;
Для полей ввода на форме можно проверять свойство Значение:
Если ЭлементыФормы.ПолеВвода.Значение = Неопределённо Тогда
// Поле не заполнено
КонецЕсли;
Можно ли в одном запросе проверить заполненность реквизитов разных типов?
Да, но нужно учитывать особенности каждого типа. Пример комбинированной проверки:
ВЫБРАТЬ
Справочник.Контрагенты.Наименование КАК Контрагент
ИЗ
Справочник.Контрагенты КАК Справочник.Контрагенты
ГДЕ
(Справочник.Контрагенты.ИНН ЕСТЬ NULL ИЛИ Справочник.Контрагенты.ИНН = "")
И Справочник.Контрагенты.ДатаРегистрации <> ДАТАВРЕМЯ(1,1,1)
И ДЛСТР(Справочник.Контрагенты.Комментарий) > 0
Как экспортировать данные с пометкой пустых реквизитов в Excel?
Используйте конструкцию ВЫБОР КОГДА для создания колонки-индикатора:
ВЫБРАТЬ
Справочник.Номенклатура.Наименование КАК Товар,
ВЫБОР
КОГДА Справочник.Номенклатура.Артикул ЕСТЬ NULL
ТОГДА "Артикул отсутствует"
ИНАЧЕ "Артикул заполнен"
КОНЕЦ КАК СтатусАртикула
ИЗ
Справочник.Номенклатура КАК Справочник.Номенклатура
Затем экспортируйте результат через ЗаписьДанныхXML или ТабличныйДокумент.Записать().