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