Как в запросе 1С проверить заполненность ссылочных полей и длину строки

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При формировании выборок и отчетов в платформе 1С:Предприятие часто возникает задача отфильтровать записи, в которых не заполнены ключевые реквизиты — например, ссылка на контрагента или физическое лицо, либо строковое поле контактной информации (адрес электронной почты, номер телефона). Разберем по шагам, какими средствами языка запросов 1С можно выполнить такие проверки, а также рассмотрим подводные камни, возникающие при работе с составными типами данных и строковыми функциями.

Проверка заполненности ссылочных полей

Для того чтобы проверить, что поле ссылочного типа заполнено (то есть не содержит пустую ссылку), в секции ГДЕ или в условиях соединений используется литерал ЗНАЧЕНИЕ. Сравнение выполняется с предопределенной пустой ссылкой соответствующего метаданного.

Рассмотрим базовый пример проверки для поля однозначного типа:


ГДЕ
    Номенклатура.ОсновнойПоставщик <> ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка)

Если реквизит имеет составной тип данных (например, поле ВладелецКарты может ссылаться как на Справочник.Контрагенты, так и на Справочник.ФизическиеЛица), программисты часто допускают грубую логическую ошибку, связывая проверки через оператор ИЛИ. Выражение вида Владелец <> ПустаяСсылкаКонтрагента ИЛИ Владелец <> ПустаяСсылкаФизлица всегда возвращает Истина, так как ссылка одного типа гарантированно не равна пустой ссылке другого типа.

Проанализируем правильные способы проверки составного типа данных:

  1. Логическое условие «И»: если поле заполнено конкретной ссылкой, оно должно одновременно не равняться пустой ссылке справочника Контрагенты и пустой ссылке справочника ФизическиеЛица.
    
    ГДЕ
        ДисконтныеКарты.ВладелецКарты <> ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка)
        И ДисконтныеКарты.ВладелецКарты <> ЗНАЧЕНИЕ(Справочник.ФизическиеЛица.ПустаяСсылка)
    
  2. Проверка через оператор «ССЫЛКА»: проверяем принадлежность типу и непустоту для каждого конкретного типа справочника.
    
    ГДЕ
        ВЫБОР
            КОГДА ДисконтныеКарты.ВладелецКарты ССЫЛКА Справочник.Контрагенты
                ТОГДА ДисконтныеКарты.ВладелецКарты <> ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка)
            КОГДА ДисконтныеКарты.ВладелецКарты ССЫЛКА Справочник.ФизическиеЛица
                ТОГДА ДисконтныеКарты.ВладелецКарты <> ЗНАЧЕНИЕ(Справочник.ФизическиеЛица.ПустаяСсылка)
            ИНАЧЕ ЛОЖЬ
        КОНЕЦ
    

Проверка минимальной длины строкового поля

Когда требуется убедиться, что строка (например, адрес электронной почты) не пустая и содержит определенное минимальное количество символов (допустим, более 3 символов), можно применить два подхода в зависимости от версии используемой платформы.

  1. Использование встроенной функции ДЛИНАСТРОКИ (платформа 8.3.8 и выше): это наиболее современный, быстрый и читаемый способ.
    
    ГДЕ
        ДЛИНАСТРОКИ(КонтактнаяИнформация.Представление) > 3
    

    Важно помнить: функция ДЛИНАСТРОКИ учитывает концевые пробелы. Если в строке могут присутствовать только пробелы, дополнительно рекомендуется проверять условие на пустую строку или использовать обрезку пробелов.

  2. Использование функции ПОДСТРОКА (универсальный способ для старых платформ): если 4-й символ строки не равен пустой строке, значит длина поля составляет как минимум 4 символа (то есть строго больше 3).
    
    ГДЕ
        НЕ ПОДСТРОКА(КонтактнаяИнформация.Представление, 4, 1) = ""
    

Особенности левого соединения и значений NULL

Разберем типичную проблему: когда контактная информация присоединяется через ЛЕВОЕ СОЕДИНЕНИЕ, а условия на ее поля накладываются в секции ГДЕ, СУБД автоматически отсекает все записи, где правая таблица не найдена. Тем самым ЛЕВОЕ СОЕДИНЕНИЕ неявно превращается во ВНУТРЕННЕЕ СОЕДИНЕНИЕ.

Кроме того, строковые функции при передаче в них значения NULL могут вызывать непредвиденное поведение запроса. Для защиты строковых полей от NULL используем функцию ЕСТЬNULL.

Посмотрим на пример итогового корректного запроса, объединяющего все рассмотренные правила:


ВЫБРАТЬ
    ПродажиОбороты.ДисконтнаяКарта КАК ДисконтнаяКарта,
    ПродажиОбороты.ВладелецДисконтнойКарты КАК ВладелецДисконтнойКарты,
    ПродажиОбороты.Номенклатура КАК Номенклатура,
    ПродажиОбороты.СуммаОборот КАК СуммаОборот,
    ФизическиеЛицаКонтактнаяИнформация.Представление КАК АдресЭлектроннойПочты
ИЗ
    РегистрНакопления.ПродажиПоДисконтнымКартам.Обороты(
        &НачДата,
        &КонДата,
        Период,
        ДисконтнаяКарта.ВидДисконтнойКарты = &ВидДисконтнойКарты
    ) КАК ПродажиОбороты
    ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ФизическиеЛица.КонтактнаяИнформация КАК ФизическиеЛицаКонтактнаяИнформация
        ПО ПродажиОбороты.ВладелецДисконтнойКарты = ФизическиеЛицаКонтактнаяИнформация.Ссылка
        И ФизическиеЛицаКонтактнаяИнформация.Тип = ЗНАЧЕНИЕ(Перечисление.ТипыКонтактнойИнформации.АдресЭлектроннойПочты)
ГДЕ
    ПродажиОбороты.СуммаОборот > 0
    И (ПродажиОбороты.ДисконтнаяКарта.ВладелецКарты <> ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка)
        И ПродажиОбороты.ДисконтнаяКарта.ВладелецКарты <> ЗНАЧЕНИЕ(Справочник.ФизическиеЛица.ПустаяСсылка))
    И ДЛИНАСТРОКИ(ЕСТЬNULL(ФизическиеЛицаКонтактнаяИнформация.Представление, "")) > 3

Валидация формата Email в запросе и в коде

Язык запросов 1С не поддерживает регулярные выражения. Базовую проверку наличия символов @ и точки можно выполнить оператором ПОДОБНО:


ГДЕ
    ФизическиеЛицаКонтактнаяИнформация.Представление ПОДОБНО "%_@_%.__%"

Однако полноценную валидацию структуры адреса электронной почты (проверку допустимых символов, корректности доменной зоны) рекомендуется выполнять во встроенном языке 1С после выполнения запроса или с помощью стандартных функций БСП, например ОбщегоНазначенияКлиентСервер.АдресЭлектроннойПочтыКорректен.

← На главную