Как правильно реализовать поиск подстроки по номеру заказа в запросе 1С?

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

Часто перед разработчиками встает задача поиска связанных данных, когда в строке описания платежа или комментария содержится номер документа. Попытки реализовать это «в лоб» через оператор ПОДОБНО с конкатенацией строк в запросе часто приводят к неработоспособности кода или серьезным проблемам с производительностью. Давайте разберем, почему так происходит и как решить задачу правильно.

Почему конструкция ПОДОБНО с конкатенацией не работает

Многие разработчики пробуют использовать конструкцию типа ГДЕ &ОписаниеПлатежа ПОДОБНО "%"+ВТ_Заказы.ЗаказСсылка.Номер+"%". С точки зрения архитектуры платформы 1С и работы СУБД, такая запись содержит ряд фундаментальных проблем:

  1. Ограничения платформы: Стандарты разработки 1С запрещают использовать динамические выражения в правой части оператора ПОДОБНО. Вы можете использовать только константные литералы или параметры запроса.
  2. Деградация производительности: Использование маски % в начале строки заставляет СУБД выполнять полное сканирование таблицы (Full Table Scan). Если таблица заказов содержит десятки тысяч записей, выполнение такого запроса будет крайне медленным.
  3. Регистрозависимость и символы: Разные СУБД (PostgreSQL, MS SQL) по-разному обрабатывают поиск строк. Кроме того, наличие спецсимволов или невидимых пробелов в номерах документов может привести к тому, что условие всегда будет возвращать Ложь.

Вариант 1: Предварительная обработка данных в коде

Наиболее надежный и быстрый способ — выделить номер заказа из строки описания еще до формирования запроса. Это позволит вам использовать обычное сравнение по полю, что дает возможность СУБД использовать индексы.

Рассмотрим алгоритм действий:

  1. На стороне сервера или клиента извлекаем номер заказа из строки ОписаниеПлатежа с помощью функций СтрНайти или регулярных выражений.
  2. Передаем полученный номер в качестве параметра в запрос.
  3. Выполняем поиск по точному соответствию.

// Пример извлечения и поиска
НомерЗаказа = ""; // Логика парсинга строки
// ... здесь код поиска номера, например:
// НомерЗаказа = Сред(ОписаниеПлатежа, 15, 9); 

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

Запрос.УстановитьПараметр("Номер", НомерЗаказа);

Вариант 2: Использование временных таблиц

Если вам нужно сопоставить большое количество описаний с большим списком заказов, лучше всего загрузить все данные во временные таблицы и выполнить соединение (Join).

  1. Создайте временную таблицу с номерами заказов, которые нужно найти.
  2. Используйте ВНУТРЕННЕЕ СОЕДИНЕНИЕ, чтобы отсеять лишние записи.

Этот метод считается «золотым стандартом» в 1С, так как он максимально эффективно использует возможности оптимизатора запросов СУБД.

Вариант 3: Анализ данных перед поиском

Если вы все же решили использовать запрос, проверьте чистоту данных. Часто причина неудачи кроется не в самом запросе, а в несоответствии строковых представлений:

Заключение

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

← На главную