При разработке механизмов загрузки данных или сопоставления объектов (например, при работе со справочником НоменклатураПоставщиков) программисты часто сталкиваются с ситуацией, когда запрос, использующий простое равенство в условии ГДЕ, не возвращает ожидаемых результатов. На первый взгляд код выглядит корректно, но база данных «упорно молчит».
В этой статье мы подробно разберем, почему стандартное сравнение строк через оператор = часто подводит, как правильно использовать оператор ПОДОБНО, и какие профессиональные подходы существуют для надежного сопоставления данных в системе 1С:Предприятие.
Рассмотрим исходную ситуацию. Программист пытается найти запись в справочнике по строковому представлению, используя следующий код:
НоменклатураПоставщиковСс = СтрокаТабличнойЧасти.ПредставлениеНоменклатуры;
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("НоменклатураПоставщиковСсылка", НоменклатураПоставщиковСС);
Запрос.Текст =
"ВЫБРАТЬ
| НоменклатураПоставщиков.Ссылка КАК Ссылка
|ИЗ
| Справочник.НоменклатураПоставщиков КАК НоменклатураПоставщиков
|ГДЕ
| НоменклатураПоставщиков.Наименование = &НоменклатураПоставщиковСсылка";
Проанализируем ситуацию и выясним причину неудачи. Основная проблема здесь кроется в механизме сравнения строк в SQL. Когда мы используем оператор =, система ищет абсолютно идентичную строку. Любое минимальное различие приведет к тому, что условие не выполнится. К таким различиям относятся:
Наименование задана фиксированная длина, СУБД может дополнять строку пробелами до этой длины.Важное замечание по типам: Как было замечено в обсуждении, часто возникает путаница: программист называет переменную НоменклатураПоставщиковСсылка, но передает в нее строку (наименование). Если в параметре запроса окажется объект типа СправочникСсылка, а сравнение идет с полем Наименование (строка), запрос никогда не найдет соответствие, так как типы несовместимы.
Если нам нужно найти строку, которая «похожа» на искомую или содержит ее, вместо оператора = следует использовать оператор ПОДОБНО. Это позволяет игнорировать некоторые неточности и использовать специальные символы-маски.
Разберем по шагам, как модифицировать запрос для стабильной работы:
// Очищаем строку от лишних пробелов по краям
ИскомоеИмя = СокрЛП(СтрокаТабличнойЧасти.ПредставлениеНоменклатуры);
// Добавляем спецсимволы "%" (любая последовательность символов)
// В данном случае мы ищем точное вхождение, но страхуемся от мусора в строке
ПараметрПоиска = "%" + ИскомоеИмя + "%";
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| НоменклатураПоставщиков.Ссылка
|ИЗ
| Справочник.НоменклатураПоставщиков КАК НоменклатураПоставщиков
|ГДЕ
| НоменклатураПоставщиков.Наименование ПОДОБНО &Наименование";
Запрос.УстановитьПараметр("Наименование", ПараметрПоиска);
Результат = Запрос.Выполнить();
Важные правила работы с ПОДОБНО:
% означает любое количество произвольных символов._ (подчеркивание) означает один произвольный символ."Товар%"), поиск будет выполняться только по началу строки. Это работает значительно быстрее, так как СУБД может использовать индексы.Хотя решение с ПОДОБНО "%Текст%" кажется спасением, у него есть серьезный минус. Проанализируем ситуацию со стороны сервера базы данных. Когда символ процента стоит в самом начале шаблона, SQL-сервер не может использовать индекс по наименованию. Ему приходится выполнять полное сканирование таблицы (Full Table Scan) — то есть прочитать каждую запись в справочнике и проверить ее на соответствие.
Если в вашем справочнике 100 000 позиций, такой запрос будет «вешать» систему при каждом выполнении. Поэтому рекомендуется:
Параметр = ИскомоеИмя + "%".=.Если задача заключается не просто в разовом запросе, а в качественном сопоставлении номенклатуры, рассмотрим более надежные способы.
1. Метод НайтиПоНаименованию
Для простых задач внутри кода (не в самом тексте запроса) можно использовать встроенный метод объекта Справочники. Он работает быстро и оптимизирован платформой:
НайденнаяСсылка = Справочники.НоменклатураПоставщиков.НайтиПоНаименованию(ИскомоеИмя, Истина);
Если Не НайденнаяСсылка.Пустая() Тогда
// Объект найден
КонецЕсли;
Второй параметр Истина означает «точное соответствие». Если передать Ложь, будет выполнен поиск по началу строки.
2. Полнотекстовый поиск (ПП)
Если пользователи хотят искать товары по обрывкам слов или со смещенным порядком слов (например, «Болт М8» вместо «М8 Болт»), используйте механизмы полнотекстового поиска 1С. Это мощный инструмент, который работает через предварительно созданные индексы и справляется с задачами поиска мгновенно.
3. Использование Артикула или Кода
Наименование — это самый нестабильный реквизит. Поставщики могут менять кавычки, добавлять пробелы или сокращать слова. Проанализируем ситуацию: профессиональная разработка всегда стремится к связи через уникальные идентификаторы. Попробуйте выполнять поиск по полю Артикул, предварительно очистив его от спецсимволов. Это гораздо надежнее поиска по строке Наименование.
Подведем итоги нашего анализа. Чтобы ваш запрос работал корректно:
СокрЛП() перед передачей параметра в запрос.ПОДОБНО с масками %.