Как правильно использовать оператор ПОДОБНО в запросах 1С и передавать параметры с маской поиска

Программист 1С v8.3 (Обычные формы)
← На главную

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

Разбор типичной проблемы: почему запрос ничего не возвращает?

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

Вариант 1: Правильная установка параметра в коде

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


// Подготовка значения артикула (очистка от лишних пробелов)
АртикулПоиска = СокрЛП(Строка(Ячейка.Value));

Запрос = Новый Запрос;
// Добавляем проценты к значению переменной ПЕРЕД передачей в запрос
Запрос.УстановитьПараметр("Артикул", "%" + АртикулПоиска + "%");

Запрос.Текст = 
    "ВЫБРАТЬ
    |	Номенклатура.Ссылка КАК Ссылка,
    |	Номенклатура.Артикул КАК Артикул
    |ИЗ
    |	Справочник.Номенклатура КАК Номенклатура
    |ГДЕ
    |	Номенклатура.Артикул ПОДОБНО &Артикул";

В данном случае, если в переменной АртикулПоиска находится значение "123", в параметр запроса уйдет строка "%123%". Это заставит систему искать все артикулы, которые содержат "123" в любой части строки.

Важность позиционирования выборки

Еще одна распространенная причина, по которой кажется, что запрос "ничего не выбирает" — это отсутствие обращения к результату. Выполнение метода Запрос.Выполнить().Выбрать() возвращает объект ВыборкаИзРезультатаЗапроса, который изначально не позиционирован ни на одной строке. Чтобы получить данные, необходимо вызвать метод Следующий().

Рассмотрим, как это должно выглядеть в рабочем коде:


РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();

// Обязательное условие для получения данных
Если Выборка.Следующий() Тогда
    // Данные найдены, можно обращаться к полям
    НайденнаяСсылка = Выборка.Ссылка;
Иначе
    // Данные не найдены
    Сообщить("Номенклатура с таким артикулом не обнаружена");
КонецЕсли;

Маски поиска и спецсимволы оператора ПОДОБНО

Оператор ПОДОБНО поддерживает несколько служебных символов, которые позволяют гибко настраивать условия поиска. Выясним, какие возможности они предоставляют:

  1. % (процент): Заменяет любую последовательность символов произвольной длины (включая пустую). Например, "А%" найдет все строки, начинающиеся на "А".
  2. _ (подчеркивание): Заменяет ровно один произвольный символ. Поиск "А_" найдет "А1", "АБ", но не найдет "А12".
  3. [ ] (квадратные скобки): Позволяют искать любой одиночный символ из указанного набора. Например, "А[123]" найдет "А1", "А2" или "А3".
  4. [^ ] (отрицание в скобках): Любой одиночный символ, кроме тех, что перечислены. "А[^0-9]" найдет "АБ", но проигнорирует "А1".

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


// Начинается на Артикул
Запрос.УстановитьПараметр("МаскаНачало", Артикул + "%");

// Заканчивается на Артикул
Запрос.УстановитьПараметр("МаскаКонец", "%" + Артикул);

// Содержит Артикул внутри
Запрос.УстановитьПараметр("МаскаВнутри", "%" + Артикул + "%");

Проблема лишних пробелов и функции работы со строками

В сообщениях форума часто упоминается проблема, когда поиск не срабатывает из-за невидимых пробелов в строках. В современных версиях платформы (начиная с 8.3.8) мы можем использовать функции обработки строк прямо внутри запроса. Это значительно эффективнее, чем строить сложные конструкции ВЫБОР КОГДА.

Посмотрим, как можно очистить данные в запросе перед сравнением:


Запрос.Текст = 
    "ВЫБРАТЬ
    |	Номенклатура.Ссылка
    |ИЗ
    |	Справочник.Номенклатура КАК Номенклатура
    |ГДЕ
    |	СОКРЛП(Номенклатура.Артикул) ПОДОБНО &Артикул";

Функция СОКРЛП() внутри запроса удалит пробелы в начале и в конце поля базы данных, что сделает поиск по части строки более надежным.

Сравнение двух полей таблицы по маске

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


Запрос.Текст = 
    "ВЫБРАТЬ
    |	Платежи.Ссылка
    |ИЗ
    |	Документ.ПлатежноеПоручение КАК Платежи
    |ВНУТРЕННЕЕ СОЕДИНЕНИЕ Документ.СчетНаОплату КАК Счета
    |ПО (Платежи.НазначениеПлатежа ПОДОБНО ""%"" + Счета.Номер + ""%"")";

Важный нюанс: Если такой запрос вызывает ошибку "Недостаточно памяти" или выполняется слишком долго, это означает, что СУБД не может эффективно использовать индексы для такого соединения. В этом случае рекомендуется использовать временные таблицы и полнотекстовый поиск или выполнять сопоставление в коде после получения данных.

Производительность и использование индексов

Разберем важный технический аспект: как оператор ПОДОБНО влияет на скорость работы системы. Помните: поиск с маской в начале строки (например, ПОДОБНО "123%") позволяет SQL-серверу использовать индекс по этому полю. Однако поиск с процентом в начале (ПОДОБНО "%123%") всегда приводит к полному сканированию таблицы (Full Scan). Если ваш справочник Номенклатура содержит сотни тысяч записей, такой запрос может существенно замедлить работу базы данных.

Для повышения производительности на больших объемах данных рассмотрите следующие альтернативы:

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

← На главную