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