При разработке конфигураций на платформе 1С часто возникает задача поиска ссылок на справочники по параметрам, которые могут быть записаны в разном формате. Например, в базе данных номер может храниться как 1234 567 89, 98-76 456-09 или 64 37 903-940, а от пользователя приходит чистая строка 123456789. Возникает естественное желание использовать СтрЗаменить прямо в языке запросов, чтобы очистить данные от пробелов и спецсимволов. Однако, давайте разберемся, почему это невозможно и как правильно решить такую задачу.
СтрЗаменить в запросе не работает?Язык запросов 1С ориентирован на работу с индексированными данными SQL-серверов. Использование функций обработки строк типа СтрЗаменить непосредственно внутри запроса привело бы к тому, что для каждой записи таблицы базе данных пришлось бы выполнять программную модификацию строки. Это исключает возможность использования индексов, что неизбежно ведет к полному сканированию всей таблицы (Table Scan). При росте объема данных такой подход приведет к критическому падению производительности.
Вместо того чтобы пытаться «сломать» логику работы запросов, рассмотрим способы приведения данных к единому, «православному» формату на уровне архитектуры.
Это самый эффективный метод. Мы добавляем в справочник дополнительный реквизит (например, КодБезРазделителей), который будет хранить «чистое» значение номера. Заполнение этого реквизита можно автоматизировать с помощью подписки на событие ПриЗаписи.
При записи элемента в справочник, обработчик событий будет очищать исходную строку от всех символов, кроме цифр, и записывать результат в новый реквизит. Для этого можно использовать следующую логику в модуле объекта:
Процедура ПриЗаписи(Отказ)
// Очистка от любых символов, кроме цифр
ЧистыйНомер = "";
Для Сч = 1 По СтрДлина(ЭтотОбъект.Номер) Цикл
Символ = Сред(ЭтотОбъект.Номер, Сч, 1);
Если Найти("0123456789", Символ) > 0 Тогда
ЧистыйНомер = ЧистыйНомер + Символ;
КонецЕсли;
КонецЦикла;
ЭтотОбъект.КодБезРазделителей = ЧистыйНомер;
КонецПроцедуры
После того как вы прогоните разовую обработку по существующим элементам, поиск будет работать мгновенно, так как вы сможете наложить на реквизит КодБезРазделителей обычный индекс.
Если внесение изменений в структуру справочника нежелательно (например, из-за сложности обновления конфигурации), используйте Регистр сведений. В нем можно хранить связь между ссылкой на элемент и его «очищенным» представлением.
СсылкаНаСправочник, а ресурсом — ОчищенныйКод.ЛЕВОЕ СОЕДИНЕНИЕ с этим регистром.Это позволит вам сохранить чистоту метаданных справочника, при этом обеспечив высокую скорость поиска через механизм соединений.
ПОДСТРОКА — это плохая идея?Иногда программисты пытаются использовать конструкцию ПОДСТРОКА и ПОДОБНО, проверяя каждый символ строки на соответствие цифре. Рассмотрим, как это выглядит в «лоб»:
ВЫБРАТЬ
А.Ссылка
ИЗ
Справочник.Клиенты КАК А
ГДЕ
ВЫБОР КОГДА ПОДСТРОКА(А.Номер, 1, 1) ПОДОБНО "[0-9]" ТОГДА ... ИНАЧЕ "" КОНЕЦ + ...
Такой подход крайне не рекомендуется по нескольким причинам:
Профессиональный подход в разработке на 1С требует понимания принципов работы СУБД. Всегда старайтесь нормализовать данные на этапе их внесения в систему (Data Entry). Создание дополнительных реквизитов или регистров сведений — это стандартная практика, которая обеспечивает быстродействие и стабильность базы данных на долгие годы вперед. Не ищите способы «обмануть» запрос, а приводите данные к тому виду, в котором системе будет удобно с ними работать.