Как правильно выполнить поиск по подстроке с помощью оператора ПОДОБНО в запросе 1С и избежать ошибки преобразования к числу?

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

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

Выясним причину возникновения ошибки

Проанализируем фрагмент запроса, вызвавший ошибку:


ВЫБОР
    КОГДА ПродажиСебестоимость.Номенклатура.Наименование ПОДОБНО "%" + Казах 
        ТОГДА 0
    ИНАЧЕ 1
КОНЕЦ КАК СебеСтоимость

В данном примере допущены сразу две синтаксические ошибки:

  1. Слово Казах написано без кавычек, из-за чего синтаксический анализатор запроса не воспринимает его как строку.
  2. В конструкции ПОДОБНО в качестве шаблона поиска допускается указывать только литерал (строковую константу в кавычках) или параметр запроса. Конкатенация строк через знак + справа от оператора ПОДОБНО синтаксически не поддерживается.

Когда парсер запроса встречает знак + вне допустимого контекста строковых операций, он пытается интерпретировать его как математическое сложение. В результате платформа пытается привести строку "%" к числу, что и вызывает исключение.

Способ 1. Использование строкового литерала в тексте запроса

Если искомая строка является фиксированной и не меняется динамически, простейший способ исправить ошибку — объединить шаблон в единую строковую константу. При формировании текста запроса внутри встроенного языка 1С строковые литералы экранируются двойными кавычками.

Посмотрим на пример корректного оформления условия:


Текст = "ВЫБРАТЬ
        |    ВЫБОР
        |        КОГДА ПродажиСебестоимость.Номенклатура.Наименование ПОДОБНО ""%Казах%""
        |            ТОГДА 0
        |        ИНАЧЕ 1
        |    КОНЕЦ КАК СебеСтоимость
        |ИЗ
        |    РегистрНакопления.ПродажиСебестоимость КАК ПродажиСебестоимость";

Спецсимвол % означает любую последовательность произвольных символов. Если необходимо найти вхождение в любой части строки, символ процента ставится с обеих сторон искомого слова.

Способ 2. Передача шаблона через параметр запроса

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

Разберем этот вариант подробнее:


ИскомыйТекст = "Казах";

Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |    ВЫБОР
    |        КОГДА ПродажиСебестоимость.Номенклатура.Наименование ПОДОБНО &ШаблонПоиска
    |            ТОГДА 0
    |        ИНАЧЕ 1
    |    КОНЕЦ КАК СебеСтоимость
    |ИЗ
    |    РегистрНакопления.ПродажиСебестоимость КАК ПродажиСебестоимость";

Запрос.УстановитьПараметр("ШаблонПоиска", "%" + ИскомыйТекст + "%");
РезультатЗапроса = Запрос.Выполнить();

Такой подход делает код более гибким, читаемым и исключает синтаксические ошибки при работе со сложными строками.

Особенности работы с оператором ПОДОБНО и ограничения платформы

Рассмотрим важные нюансы, которые необходимо учитывать при поиске подстрок в запросах 1С:

  1. Строки неограниченной длины: оператор ПОДОБНО не работает напрямую с полями неограниченной длины (например, многострочными комментариями или описаниями). Перед сравнением поле обязательно нужно явно привести к строке фиксированной длины с помощью функции ВЫРАЗИТЬ(Поле КАК СТРОКА(1000)).
  2. Экранирование служебных символов: если искомый текст сам по себе содержит символы %, _, [ или ], следует использовать конструкцию СПЕЦСИМВОЛ. Например: ПОДОБНО &ШаблонПоиска СПЕЦСИМВОЛ "~", предварительно экранировав символы тильдой в параметре.
  3. Производительность СУБД: использование символа % в начале шаблона ("%Текст") делает невозможным использование индексов по наименованию. База данных выполняет полное сканирование таблицы (Table Scan), что на больших объемах данных справочника Номенклатура приводит к существенным задержкам.
  4. Регистрозависимость: результат сравнения может зависеть от параметров сортировки (Collation) СУБД (например, в PostgreSQL). Для надежного поиска без учета регистра рекомендуется приводить поле и параметр к единому регистру с помощью функции ВРЕГ или НРЕГ.

Способ 3. Архитектурная оптимизация — использование реквизитов

Поиск по подстроке в наименовании для реализации бизнес-логики (расчета себестоимости, ценообразования, разделения номенклатуры по странам) считается неоптимальным подходом. Наименование товара может быть изменено пользователем, содержать опечатки или разный регистр букв.

Проанализируем правильное архитектурное решение:

  1. Добавить в справочник Номенклатура отдельный реквизит (например, СтранаПроисхождения со ссылкой на классификатор стран мира или признак типа ПеречислениеСсылка / Булево).
  2. При невозможности изменения типовой конфигурации задействовать механизм дополнительных реквизитов и сведений (план видов характеристик ДополнительныеРеквизитыИСведения).
  3. Заполнить признак групповой обработкой для существующей номенклатуры и в дальнейшем выполнять быстрое и надежное соединение или фильтрацию по ссылочному полю, а не по тексту наименования.
← На главную