При автоматизации загрузки данных из внешних файлов (Excel, CSV) в 1С:ERP или другие конфигурации, разработчики часто сталкиваются с проблемой несовпадения наименований. Поставщик может называть товар «Масло SHELL Helix Ultra 5W-30», в то время как в базе НСИ он заведен как «Масло моторное Helix Ultra 5W30 (Shell)». В рамках данной статьи мы проанализируем различные стратегии решения этой задачи: от использования штатных механизмов 1С до реализации алгоритмов нечеткого поиска.
Прежде чем приступать к написанию сложных алгоритмов, проанализируем штатные возможности 1С:ERP и УТ 11. В этих конфигурациях предусмотрен регистр сведений НоменклатураКонтрагентов. Это наиболее правильный путь с точки зрения архитектуры системы.
Суть метода: при первой загрузке файла пользователь вручную сопоставляет строку из Excel с элементом справочника Номенклатура. Программа записывает эту связь в регистр. При последующих загрузках система сначала ищет точное совпадение по наименованию поставщика в этом регистре. Рассмотрим, как это упрощает жизнь: мы не пытаемся «угадать» позицию каждый раз, а используем накопленную базу знаний системы.
Любой интеллектуальный поиск работает эффективнее, если данные предварительно «очищены». Разберем основные этапы нормализации, которые стоит выполнить перед сравнением:
Платформа 1С:Предприятие 8.3 обладает мощным механизмом полнотекстового поиска (ПП). Мало кто знает, что его можно использовать программно для реализации нечеткого поиска. Для этого используется специальный оператор #.
Выясним, как это работает на практике. Если мы ищем слово «#искуство», поиск выдаст результат «искусство», так как допускается определенное количество отличий в символах. Рассмотрим пример кода для программного поиска:
СписокПоиска = ПолнотекстовыйПоиск.СоздатьСписок("ТекстИзЭкселя", 10);
СписокПоиска.ПорогНечеткости = 15; // Указываем процент отличия
СписокПоиска.ПерваяЧасть();
Для Каждого Результат Из СписокПоиска Цикл
Если ТипЗнч(Результат.Значение) = Тип("СправочникСсылка.Номенклатура") Тогда
// Добавляем найденный элемент в список вариантов для пользователя
КонецЕсли;
КонецЦикла;
Важно помнить, что этот метод требует актуального индекса полнотекстового поиска. Если индекс не обновлен, новые элементы номенклатуры найдены не будут.
Если штатный поиск не дает нужной гибкости, проанализируем классический алгоритм вычисления разницы между двумя строками — расстояние Левенштейна. Это количество правок (вставок, удалений, замен), необходимых для превращения одной строки в другую.
Рассмотрим реализацию функции на языке 1С:
Функция РасстояниеЛевенштейна(Стр1, Стр2)
н1 = СтрДлина(Стр1);
н2 = СтрДлина(Стр2);
// Инициализация матрицы...
// (реализация алгоритма через обход циклом)
// Возвращаем число - чем оно меньше, тем больше сходства
КонецФункции
Однако применение этого алгоритма в «лоб» ко всей базе номенклатуры (например, 50 000 позиций) приведет к серьезному замедлению. Правильный подход: сначала отфильтровать базу запросом (например, по первому слову или по группе), а затем среди 20-30 кандидатов вычислить наиболее релевантного по Левенштейну.
Ситуация с технически сложными товарами (например, маслами или метизами) требует особого внимания к числам. Разница между маслом «5W-30» и «5W-40» — всего один символ, но это разные товары. В то же время разница между «Масло» и «Маслице» — три символа, но это одно и то же.
Для решения этой проблемы мы рекомендуем использовать систему весов:
Просуммировав эти баллы, мы выведем пользователю список вариантов, отсортированный по релевантности. Самый подходящий вариант будет подсвечен цветом.
Как справедливо отмечают эксперты, полностью доверять автоматике нельзя — цена ошибки может быть слишком высока. Проанализируем оптимальную схему работы пользователя:
Таким образом, сочетание предварительной нормализации, программного использования полнотекстового поиска и алгоритмов сравнения строк позволяет значительно ускорить процесс обработки входящих документов, оставляя окончательный контроль за человеком.