Работа с выборками данных в платформе 1С:Предприятие часто требует фильтрации результатов на уровне базы данных. Самая распространенная задача — исключить из выборки записи, где определенные реквизиты не заполнены. Это критически важно для корректного формирования отчетов и проведения сложных расчетов.
Неправильная интерпретация понятия "пустое значение" может привести к серьезным ошибкам в логике программы. В SQL-диалекте 1С существуют различные подходы к решению этой задачи, каждый из которых имеет свои особенности производительности и синтаксиса. Разберем их детально.
Понятие пустого значения в языке запросов 1С
Прежде чем писать условие отбора, необходимо четко понимать разницу между значением NULL и пустой строкой. В контексте СУБД, используемой 1С, NULL означает отсутствие значения как такового, в то время как пустая строка — это строковое значение нулевой длины.
Многие разработчики допускают ошибку, пытаясь сравнить поле со строкой "" (две кавычки подряд) там, где в базе фактически хранится NULL. Такое сравнение всегда вернет ложь, и запись с незаполненным полем попадет в выборку, нарушая логику работы.
Для корректной обработки необходимо использовать специальный синтаксис платформы. Оператор IS NULL предназначен строго для проверки на отсутствие значения. Использование обычного знака равенства здесь недопустимо с точки зрения стандартов ANSI SQL, которые использует 1С.
⚠️ Внимание: Никогда не используйте оператор
=для сравнения сNULL. ВыражениеПоле = NULLвсегда возвращает Неизвестно (Ложь в контексте фильтра), и нужные строки не будут отфильтрованы.
Использование оператора IS NULL и IS NOT NULL
Самый надежный и стандартный способ проверить, заполнено ли поле — использование конструкций IS NULL и IS NOT NULL. Эти операторы работают непосредственно на уровне движка базы данных, что обеспечивает максимальную производительность при выборке больших объемов данных.
Если вам нужно получить только те документы, где указан контрагент, вы должны использовать отрицание. Синтаксис выглядит следующим образом:
ВЫБРАТЬ
Документ.Ссылка,
Документ.Контрагент
ИЗ
Документ.РеализацияТоваровУслуг КАК Документ
ГДЕ
Документ.Контрагент IS NOT NULL
Обратная ситуация возникает, когда требуется найти "проблемные" документы, в которых забыли указать ответственного. В этом случае применяется прямое условие IS NULL. Это часто используется в регламентных заданиях для поиска ошибок ввода данных.
Используйте IS NOT NULL вместо НЕ (Поле IS NULL) для лучшей читаемости кода, хотя технически они эквивалентны.
Функция ЕПУСТО в условии отбора
Платформа 1С предоставляет специальную функцию ЕПУСТО(), которая является оберткой над стандартными SQL-операторами. Она проверяет значение на NULL и, в зависимости от типа данных, может также учитывать пустые строки.
Использование этой функции делает код запроса более компактным и понятным для русскоязычных разработчиков. Однако стоит помнить, что под капотом она трансформируется в те же самые конструкции IS NULL. Синтаксис применения в секции ГДЕ:
ГДЕ
ЕПУСТО(Документ.Комментарий) = ЛОЖЬ
В данном примере мы отбираем записи, где комментарий не пуст. Важно отметить, что для числовых полей и ссылок поведение функции идентично проверке на NULL. Для строк ситуация может зависеть от настроек сравнения, но в большинстве случаев 1С корректно обрабатывает оба типа "пустоты".
Внутреннее устройство ЕПУСТО
Функция ЕПУСТО транслируется сервером 1С в конструкцию CASE или COALESCE в зависимости от версии платформы и типа СУБД, но итоговый план выполнения обычно оптимизируется движком.
Проверка пустых строк и пробельных символов
Ситуация усложняется, когда поле типа Строка формально заполнено, но содержит только пробелы или табуляцию. Стандартный оператор IS NOT NULL пропустит такую запись, так как значение технически существует.
Для очистки таких данных на уровне запроса необходимо использовать функцию СокрЛП() (сокращение левых и правых пробелов). Комбинируя её с проверкой на длину или пустоту, можно добиться строгой фильтрации.
Рассмотрим пример, где нужно найти строки, содержащие реальный текст:
- 🔍 Проверяем, что поле не равно
NULL. - 🧹 Обрезаем пробелы функцией
СокрЛП(). - ✅ Сравниваем результат с пустой строкой.
Конструкция в запросе будет выглядеть громоздко, но она гарантирует точность:
ГДЕ
(Документ.Комментарий IS NOT NULL) И (СокрЛП(Документ.Комментарий) <> "")
Такой подход особенно актуален при выгрузке данных во внешние системы, где наличие строки из одних пробелов может вызвать ошибку парсинга на стороне приемника.
Сравнение производительности методов проверки
Выбор метода проверки заполненности может влиять на скорость выполнения запроса, особенно на больших выборках (миллионы записей). Использование индексов базы данных играет здесь ключевую роль.
Ниже приведена сравнительная таблица методов проверки с точки зрения нагрузки на СУБД:
| Метод проверки | Использование индекса | Читаемость кода | Рекомендация |
|---|---|---|---|
IS NOT NULL |
Полное (Optimal) | Средняя | Основной метод |
ЕПУСТО() = ЛОЖЬ |
Полное (Optimal) | Высокая | Для сложных условий |
СокрЛП() <> "" |
Частичное / Отсутствует | Низкая | Только для строк |
ЕСТЬNULL(Поле, 0) <> 0 |
Зависит от плана | Средняя | Альтернатива |
Как видно из таблицы, классические операторы IS NULL работают быстрее всего, так как СУБД может напрямую использовать битовые карты индексов. Функции обработки строк, такие как СокрЛП, часто вынуждают базу данных выполнять полный скан таблицы, что недопустимо в высоконагруженных системах.
Типичные ошибки при фильтрации данных
Одной из самых частых ошибок является попытка подмены NULL значением по умолчанию внутри условия ГДЕ с использованием функции ЕСТЬNULL(). Хотя этот метод работает, он может запутать оптимизатор запросов.
Например, конструкция ЕСТЬNULL(Поле, -1) = -1 логически верна для поиска пустых значений, но менее очевидна для поддержки кода другими разработчиками. Лучше явно писать намерение разработчика через IS NULL.
Также стоит избегать смешивания типов данных в условиях. Если поле числовое, сравнение его с пустой строкой "" вызовет ошибку выполнения запроса или неявное преобразование типов, что негативно скажется на производительности.
⚠️ Внимание: При работе с составными типами (например, СправочникСсылка.Номенклатура или Строка) убедитесь, что в базе данных не хранятся некорректные значения типов, которые могут пройти проверку
IS NOT NULL, но вызвать ошибку при последующей обработке в коде 1С.
Проверка заполненности в запросах к регистрам сведений
При работе с регистрами сведений ситуация осложняется наличием измерений и ресурсов. Часто требуется проверить заполненность именно измерения, чтобы понять, детализирована ли запись.
В запросах к виртуальным таблицам регистров (например, РегистрСведений.ЦеныНоменклатуры.СрезПоследних) проверка на NULL работает аналогично документам. Однако важно учитывать параметры виртуальной таблицы.
Если измерение входит в состав отбора виртуальной таблицы, оно не может быть NULL внутри результата среза, так как это часть ключа записи. Проверка имеет смысл только для ресурсов или дополнительных реквизитов, не входящих в ключ.
☑️ Аудит запроса на проверку пустоты
Особенности работы в управляемых формах
Хотя данная статья посвящена языку запросов, нельзя не упомянуть связь с клиентской частью. Данные, полученные из запроса, часто выводятся в списки форм. Если проверка на сервере выполнена некорректно, пользователь увидит "пустые" ячейки там, где должны быть прочерки или значения по умолчанию.
Для обработки таких ситуаций на клиенте используется свойство ПустаяСтрока или проверка на Неопределено. Но правильнее решать проблему на этапе формирования выборки, чтобы не передавать лишние данные по сети.
Использование конструкции ВЫБОР внутри запроса позволяет подменять NULL на понятные пользователю значения прямо в базе данных, например:
ВЫБОР
КОГДА Документ.Комментарий IS NULL ТОГДА "<Нет комментария>"
ИНАЧЕ Документ.Комментарий
КОНЕЦ КАК КомментарийТекст
Это упрощает отображение данных в отчетах и снижает нагрузку на клиентское приложение 1С.
Оптимальная стратегия — выполнять фильтрацию и замену пустых значений на уровне запроса к базе данных, а не обрабатывать массив результатов в цикле на стороне 1С.
В чем разница между ЕПУСТО и проверкой на NULL?
Функция ЕПУСТО является встроенной функцией языка 1С, которая внутри себя выполняет проверку на NULL. Для полей типа Строка она также может учитывать пустую строку, в то время как оператор IS NULL проверяет исключительно отсутствие значения в ячейке базы данных. В запросах они часто взаимозаменяемы, но IS NULL более универсален для всех типов.
Можно ли использовать оператор <> для проверки на заполненность?
Нет, оператор <> (не равно) не подходит для проверки на NULL. В логике SQL любое сравнение с NULL дает результат Unknown. Поэтому выражение Поле <> NULL никогда не вернет Истину. Всегда используйте IS NOT NULL.
Как проверить, что строка не содержит только пробелов?
Для этого необходимо скомбинировать проверку на IS NOT NULL и функцию обрезки пробелов. Условие будет выглядеть так: (Поле IS NOT NULL) И (СокрЛП(Поле) <> ""). Это гарантирует, что в поле есть хотя бы один видимый символ.
Влияет ли проверка на NULL на использование индексов?
Да, влияет положительно. Современные СУБД (PostgreSQL, MS SQL), используемые в 1С, умеют эффективно использовать индексы для поиска значений IS NULL и IS NOT NULL. Это одна из самых быстрых операций фильтрации.
Что вернет запрос, если в условии ГДЕ написано "Поле = NULL"?
Такой запрос вернет пустой набор данных. Условие Поле = NULL всегда ложно для любой строки таблицы, так как NULL не равен ничему, даже самому себе. Записи с незаполненным полем будут исключены из выборки.