Работа с данными в системе 1С:Предприятие часто сводится к выборке записей, соответствующих определенным критериям. Одной из самых частых ситуаций, с которой сталкивается разработчик, является необходимость фильтрации записей, где определенные поля не заполнены. Это может быть поиск товаров без артикула, контрагентов без ИНН или документов, по которым еще не проведен расчет.
Неправильная интерпретация понятия «пустота» в языке запросов может привести к тому, что нужные записи будут потеряны, либо, наоборот, в выборку попадет лишний мусор. Система 1С различает концепции NULL (неопределенное значение), пустой строки и логической истины. Понимание этих различий критически важно для написания корректного кода.
В данном материале мы детально разберем синтаксические конструкции, позволяющие отсеивать незаполненные данные, и рассмотрим подводные камни, связанные с типами данных и производительностью выполнения запросов.
Фундаментальные различия NULL и пустой строки
Прежде чем писать код, необходимо четко разграничить два состояния, которые пользователь часто воспринимает как одно и то же. В терминах баз данных и платформы 1С значение NULL означает, что значение поля неизвестно или не было задано вовсе. Это состояние «отсутствия данных» как таковых.
В то же время, поле текстового типа может содержать строку нулевой длины "". Это уже конкретное значение — строка, в которой нет символов. Для базы данных это полноценная запись, просто ее содержимое «пустое». Если ваш алгоритм требует найти именно незаполненные поля, использование условия равенства пустой строке не сработает для значений NULL.
Стандартный язык запросов 1С предоставляет специальный оператор ЕСТЬ NULL для работы с первым случаем. Игнорирование этого оператора — распространенная ошибка новичков, приводящая к тому, что запрос возвращает пустой результат, хотя в таблице есть записи с незаданными значениями.
⚠️ Внимание: Если в конфигурации для реквизита установлено свойство «Заполнять нулем» или аналогичные настройки типа данных, система может автоматически подставлять пустую строку вместо NULL. Всегда проверяйте метаданные конкретного реквизита перед написанием условия отбора.
Для полей числового типа ситуация аналогична: NULL — это не число, а отсутствие числа. Ноль 0 — это конкретное числовое значение. Спутать их нельзя, но проверить оба состояния в одном условии можно с помощью составных логических выражений.
Синтаксис оператора ЕСТЬ NULL
Основным инструментом для проверки на отсутствие значения является конструкция ЕСТЬ NULL. Она применяется непосредственно к имени поля в секции ГДЕ или ИМЕЮЩИЕ. Синтаксически это выглядит максимально просто и читается как естественный язык.
Рассмотрим пример выборки номенклатуры, у которой не заполнен артикул. Здесь мы явно указываем, что нас интересуют только те записи, где поле Артикул имеет значение NULL.
ВЫБРАТЬ
Номенклатура.Наименование,
Номенклатура.Артикул
ИЗ
Справочник.Номенклатура КАК Номенклатура
ГДЕ
Номенклатура.Артикул ЕСТЬ NULL
Важно отметить, что оператор ЕСТЬ NULL работает только с полями, которые допускают хранение неопределенного значения. Если тип данных поля строго определен и не допускает NULL (например, булевский тип или число с заполнением нулем по умолчанию), использование этого оператора будет избыточным, хотя и не вызовет ошибки.
- 🔍 Используйте
ЕСТЬ NULLдля полей строк, дат и ссылок, если они могут быть не заполнены. - 🚫 Не применяйте этот оператор для проверки на ноль в числовых полях, если ноль является валидным значением.
- ✅ Комбинируйте с
НЕ ЕСТЬ NULLдля выборки только заполненных записей.
Обратная операция, когда необходимо выбрать только заполненные значения, выполняется с помощью отрицания: НЕ (Поле ЕСТЬ NULL). Это эквивалентно проверке на то, что значение определено.
Проверка пустых строк и составные условия
Часто в реальных базах данных встречается смешанная ситуация: в одних записях поле не заполнено (NULL), а в других — записана пустая строка. Это может быть следствием импорта данных из внешних систем или ручного ввода пользователями в старых версиях конфигурации.
Чтобы охватить оба случая в одном запросе, необходимо использовать логическое выражение ИЛИ. Мы проверяем поле на наличие NULL и отдельно на равенство пустой строке. Это гарантирует, что ни одна «пустая» запись не проскользнет сквозь фильтр.
ВЫБРАТЬ
Контрагенты.Наименование,
Контрагенты.ИНН
ИЗ
Справочник.Контрагенты КАК Контрагенты
ГДЕ
(Контрагенты.ИНН ЕСТЬ NULL) ИЛИ (Контрагенты.ИНН = "")
Такой подход является наиболее надежным при работе с текстовыми реквизитами. Однако стоит помнить о производительности: составные условия могут усложнить план выполнения запроса, особенно если на поле наложен индекс. В большинстве случаев движок 1С справляется с этим эффективно, но на огромных массивах данных (миллионы строк) разница может стать заметной.
Если вы работаете с полями типа Булево, логика меняется. Там нет понятия пустой строки. Поле может быть Истина, Ложь или NULL (если тип допускает). Проверка на «пустоту» здесь сводится к проверке на NULL или, в зависимости от бизнес-логики, на значение Ложь.
⚠️ Внимание: При сравнении строк учитывайте регистр и пробелы. Строка, содержащая одни пробелы" ", не равна пустой строке""и не является NULL. Для очистки таких данных используйте функциюСТРЗАМЕНИТЬили проверяйте длину строки.
Использование функции ЕСТЬNULL в выражениях
Помимо фильтрации в секции ГДЕ, часто возникает необходимость подменить отсутствующее значение на какое-либо дефолтное прямо в результатах выборки. Для этого в языке запросов 1С существует функция ЕСТЬNULL(). Она принимает два аргумента: проверяемое выражение и значение подстановки.
Эта функция незаменима при формировании отчетов, где отсутствие значения должно отображаться как прочерк, ноль или текст «Не указано». Синтаксис функции позволяет встраивать её в любые вычисляемые поля.
ВЫБРАТЬ
Номенклатура.Наименование,
ЕСТЬNULL(Номенклатура.Артикул, "Нет артикула") КАК Артикул
ИЗ
Справочник.Номенклатура КАК Номенклатура
В данном примере, если поле Артикул содержит NULL, в результат выборки попадет строка «Нет артикула». Если же поле заполнено, функция вернет его фактическое значение. Это упрощает обработку данных на стороне клиента или в СКД (Системе Компоновки Данных), так как избавляет от необходимости писать дополнительные условия в коде 1С.
Функция ЕСТЬNULL() также может использоваться внутри условий ГДЕ, хотя это встречается реже. Например, если нужно найти записи, где поле либо пустое, либо равно определенному значению после подстановки.
Оптимизация функции ЕСТЬNULL
Использование функции ЕСТЬNULL в секции ГДЕ может препятствовать использованию индексов в некоторых редких случаях. Если производительность критична, попробуйте переписать условие через ИЛИ с явными проверками.
Специфика работы с типами данных и ссылками
Особое внимание следует уделить полям типа Ссылка. В 1С ссылка на несуществующий объект часто представляется как NULL. Однако в некоторых случаях (например, при использовании планов видов характеристик или динамических списков) может потребоваться проверка на пустую ссылку конкретного типа.
При работе с составными типами данных, где поле может содержать, например, и Справочник, и Строку, логика проверки усложняется. Система должна понимать, к какому типу относится текущее значение. Оператор ЕСТЬ NULL в этом контексте работает универсально: он проверяет, задано ли значение вообще, независимо от его типа.
| Тип данных | Значение "Пусто" | Проверка в запросе | Примечание |
|---|---|---|---|
| Строка | NULL или "" | ЕСТЬ NULL ИЛИ Поле = "" |
Чаще всего встречаются оба варианта |
| Число | NULL | ЕСТЬ NULL |
Ноль (0) — это значение |
| Дата | NULL | ЕСТЬ NULL |
Минимальная дата — это значение |
| Булево | NULL | ЕСТЬ NULL |
Ложь — это значение |
| Ссылка | NULL | ЕСТЬ NULL |
Пустая ссылка часто равна NULL |
Как видно из таблицы, для большинства типов, кроме строки, проверка сводится к использованию оператора ЕСТЬ NULL. Для строк всегда рекомендуется дублировать проверку на пустую строку, если нет гарантий чистоты данных в базе.
☑️ Аудит запроса на пустоту
Оптимизация и производительность запросов
Проверка на пустоту, особенно составная (ИЛИ), может влиять на скорость работы запроса. СУБД, лежащая в основе 1С (MSSQL, PostgreSQL, Oracle), по-разному обрабатывает индексы для условий IS NULL. В некоторых системах значения NULL вообще не хранятся в стандартных B-деревьях индексов.
Если таблица содержит миллионы записей, а выборка по условию «пустое поле» возвращает малое количество строк, наличие индекса может ускорить работу. Однако если «пустых» записей много (например, 50% и более), оптимизатор СУБД может принять решение об отказе от индекса и полном сканировании таблицы, что медленно.
Для ускорения таких выборок можно использовать вычисляемые поля или помечать «пустые» записи специальным флагом (виртуальным табличным полем), по которому уже налажен эффективный индекс. Но это требует изменения структуры метаданных.
⚠️ Внимание: Интерфейсы и механизмы работы СУБД могут обновляться. Детали реализации индексации NULL-значений зависят от конкретной версии СУБД и платформы 1С. Сверяйте актуальные рекомендации по оптимизации в официальной документации для вашей версии платформы.
Также стоит избегать использования функций над полями в секции ГДЕ, если это возможно. Хотя ЕСТЬ NULL является оператором, а не функцией в полном смысле, сложные обертки вокруг него могут затруднить работу оптимизатора.
Если проверка на пустоту выполняется в цикле для каждого элемента коллекции, вынесите логику в один общий запрос с временной таблицей. Это снизит нагрузку на сервер в сотни раз.
Комбинированная проверка (NULL ИЛИ "") для строк — это стандарт надежности, который защищает от рассинхронизации данных в базе.
Частые ошибки и методы отладки
Одной из самых коварных ошибок является попытка использовать знак равенства для проверки на NULL, как в SQL диалекте = NULL. В языке запросов 1С это недопустимо и приведет к ошибке синтаксиса или логической ошибке, так как NULL не сравним ни с чем, даже с самим собой, через операторы сравнения.
Еще одна проблема — невидимые символы. Поле может выглядеть пустым в интерфейсе, но содержать символ перевода строки Символ(10) или табуляцию. В таком случае проверка на "" не сработает. Для отладки таких ситуаций полезно выводить длину строки функцией СТРОКА или визуализировать спецсимволы.
При использовании консоли запросов всегда включайте отображение текста запроса, чтобы видеть, как именно система сформировала условие. Иногда параметры могут подставляться некорректно, если они передаются из внешнего кода.
// Пример отладки: вывод длины поля
ВЫБРАТЬ
Номенклатура.Наименование,
СТРОКА(ДЛИНА(Номенклатура.Артикул)) КАК ДлинаАртикула
ИЗ
Справочник.Номенклатура КАК Номенклатура
ГДЕ
Номенклатура.Артикул ЕСТЬ NULL ИЛИ Номенклатура.Артикул = ""
Если в результате выполнения такого запроса вы видите строки с длиной больше нуля, значит, в поле есть скрытые символы, и условие отбора нужно корректировать с учетом функции СТРЗАМЕНИТЬ для удаления пробелов.
Можно ли использовать оператор IS NULL как в SQL?
Нет, в языке запросов 1С используется синтаксическая конструкция ЕСТЬ NULL. Написание IS NULL вызовет ошибку синтаксического анализа, так как это недопустимый лексический элемент для данного языка.
Как проверить, что поле НЕ пустое?
Для этого используется отрицание: НЕ (Поле ЕСТЬ NULL). Если нужно исключить и пустые строки, условие усложняется: НЕ (Поле ЕСТЬ NULL) И Поле <> "".
Влияет ли проверка на NULL на использование индексов?
Да, влияние есть. Зависит от СУБД. В некоторых случаях запросы с ЕСТЬ NULL выполняются быстро благодаря специальным битовым картам или индексам, в других — могут требовать полного сканирования, если пустых значений очень много.
Что вернет функция ЕСТЬNULL, если поле заполнено нулем?
Если поле числовое и содержит значение 0, функция ЕСТЬNULL(Поле, Подстановка) вернет 0, так как ноль — это валидное значение, а не NULL. Подстановка сработает только при отсутствии значения.