Практическая работа с оператором «ПОДОБНО» и функцией ЕСТЬNULL в запросах 1С
Работа с оператором «ПОДОБНО» и функцией ЕСТЬNULL в запросах 1С требует понимания синтаксиса языка запросов и стандартов разработки. Оператор ПОДОБНО используется для поиска по шаблону, а ЕСТЬNULL() позволяет подменять пустые значения, возникающие при левых соединениях, обеспечивая корректность вычислений и вывода данных.
Оглавление
Оператор ПОДОБНО: синтаксис и шаблоны
Оператор ПОДОБНО является аналогом SQL-оператора LIKE, возвращает значение типа Булево и проверяет соответствие строки заданному шаблону. Применяется в секции ГДЕ или условных конструкциях. Сравнение выполняется без учета регистра символов.
Ключевые спецсимволы шаблона:
%(процент) — заменяет любую последовательность символов любой длины (включая пустую)._(подчеркивание) — заменяет ровно один произвольный символ.
Примеры использования:
"%Резец%"— найдет все строки, содержащие слово "Резец" в любом месте."Резец%"— найдет строки, начинающиеся со слова "Резец"."%Резец"— найдет строки, заканчивающиеся на "Резец"."__ABC"— найдет строки, где первые два символа любые, а далее идет "ABC".
Стандарты 1С и ограничения
Согласно стандартам разработки конфигураций 1С (документ std726), при использовании оператора ПОДОБНО необходимо соблюдать строгие правила для обеспечения кроссплатформенности и стабильности:
- Запрет на конкатенацию в тексте запроса. Шаблон должен быть либо константным литералом, либо параметром запроса. Формирование шаблона сложением строк прямо в тексте запроса запрещено.
- ✅ Правильно:
Реквизит ПОДОБНО &ПараметрШаблона - ❌ Неправильно:
Реквизит ПОДОБНО "%"+&ЧастьСтроки+"%"
- ✅ Правильно:
- Кроссплатформенность. Разрешено использовать только
%и_. Конструкции[...](диапазоны символов) и[^...](отрицание) не работают в СУБД IBM DB2, поэтому их использование запрещено в типовых конфигурациях. - Ограничение длины. Длина строки шаблона не должна превышать 1024 символа (ограничение MS SQL Server).
Экранирование спецсимволов
Если пользователь вводит в поиск символы %, _, [, ], ^, они будут восприняты как управляющие символы шаблона. Для поиска этих символов как обычного текста необходимо их экранировать.
Алгоритм экранирования:
- Выберите символ-экран (например,
~). - Замените в искомой строке сам экран на двойной экран (
~→~~). - Замените спецсимволы на комбинацию с экраном (
%→~%,_→~_и т.д.). - В запросе используйте ключевое слово
СПЕЦСИМВОЛ.
В Библиотеке стандартных подсистем (БСП) предусмотрена функция ОбщегоНазначения.СформироватьСтрокуДляПоискаВЗапросе, которая автоматически выполняет необходимое экранирование перед передачей строки в параметр запроса.
// В модуле перед выполнением запроса
СтрокаПоиска = ОбщегоНазначения.СформироватьСтрокуДляПоискаВЗапросе(ВведенныйТекст);
Запрос.УстановитьПараметр("Шаблон", "%" + СтрокаПоиска + "%");
// В тексте запроса
ГДЕ Номенклатура.Наименование ПОДОБНО &Шаблон СПЕЦСИМВОЛ "~"
Функция ЕСТЬNULL() и работа с NULL
Функция ЕСТЬNULL(<Проверяемое выражение>, <Выражение замены>) предназначена для замены значения NULL на другое, заранее определенное значение. Это критически важно при работе с внешними соединениями (ЛЕВОЕ СОЕДИНЕНИЕ), где отсутствие связанных записей приводит к появлению NULL в полях правой таблицы.
Если первое выражение не равно NULL, функция возвращает его значение. Если равно NULL — возвращает значение второго выражения.
Пример использования:
ВЫБРАТЬ
Номенклатура.Наименование,
ЕСТЬNULL(Остатки.КоличествоОстаток, 0) КАК КоличествоОстаток
ИЗ
Справочник.Номенклатура КАК Номенклатура
ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки КАК Остатки
ПО Остатки.Номенклатура = Номенклатура.Ссылка
Важные особенности:
- Приведение типов. Функция пытается привести тип "выражения замены" к типу "проверяемого выражения". Если проверяемое поле имеет тип
Строка(5), а вы подставляете замену"Отсутствует", результат будет обрезан до 5 символов ("Отсу"). Если приведение невозможно, запрос завершится с ошибкой. - Преимущества перед ВЫБОР. Использование
ЕСТЬNULL()предпочтительнее конструкцииВЫБОР КОГДА ... ЕСТЬ NULL ТОГДА .... Код становится компактнее, а производительность выше, так как выражение вычисляется один раз, а не дублируется в условиях. - Агрегатные функции. Часто применяется для защиты от
NULLв итогах:ЕСТЬNULL(СУММА(Документ.Сумма), 0).
Не путайте условие ЕСТЬ NULL и функцию ЕСТЬNULL(). ЕСТЬ NULL — это условие для проверки (используется в ГДЕ). ЕСТЬNULL() — это функция для подмены значения. Конструкция ГДЕ Поле = NULL всегда вернет Ложь. Для проверки на пустоту нужно использовать ЕСТЬ NULL или НЕ ЕСТЬ NULL.
Частые ошибки
- Использование конкатенации в шаблоне. Попытка собрать шаблон сложением строк прямо в тексте запроса нарушает стандарты 1С и может привести к ошибкам выполнения.
- Поиск спецсимволов без экранирования. Ввод пользователем
%или_в поле поиска без предварительной обработки ломает логику выборки, так как символы воспринимаются как управляющие. - Сравнение с NULL через равно. Написание
ГДЕ Поле = NULLилиГДЕ Поле <> NULLне работает. Необходимо использовать конструкциюГДЕ Поле ЕСТЬ NULL. - Игнорирование приведения типов в ЕСТЬNULL(). Подстановка строки большей длины, чем у проверяемого поля, приводит к тихому обрезанию значений, а подстановка несовместимого типа — к падению запроса.
- Использование диапазонов в ПОДОБНО. Применение конструкций
[...]или[^...]нарушает кроссплатформенность и запрещено стандартами из-за отсутствия поддержки в IBM DB2.
FAQ
Чем отличается ЕСТЬ NULL от ЕСТЬNULL()?
ЕСТЬ NULL — это логическое условие для фильтрации данных (например, в секции ГДЕ). ЕСТЬNULL() — это функция для замены пустого значения на альтернативное в списке выбираемых полей.
Почему в запросах 1С нельзя использовать диапазоны символов в ПОДОБНО?
Конструкции вроде [a-z] или [^0-9] не поддерживаются в СУБД IBM DB2. Стандарты разработки 1С запрещают их использование, чтобы гарантировать кроссплатформенность типовых конфигураций.
Как правильно искать слово, содержащее знак процента?
Необходимо экранировать спецсимвол. В тексте запроса используется ключевое слово СПЕЦСИМВОЛ с выбранным экраном (например, ~), а в самом параметре запроса знак % заменяется на ~%.
Что будет, если в ЕСТЬNULL() передать несовместимый тип замены?
Если приведение типов невозможно (например, подстановка большого числа в поле с ограничением Число(2)), запрос завершится с ошибкой выполнения.