При автоматизации загрузки данных с сайтов контрагентов мы часто сталкиваемся с ситуацией, когда единственным связующим звеном между базой поставщика и нашей собственной является наименование товара. Когда объем данных достигает десятков тысяч позиций, ручное сопоставление становится невозможным. Рассмотрим, как решить задачу сопоставления номенклатуры, используя встроенные возможности 1С, алгоритмы нечеткого поиска и современные методы нормализации данных.
Прежде чем приступать к алгоритмам поиска, нам необходимо определить, где мы будем хранить результаты сопоставления. Разберем стандартный подход: использование специализированного регистра сведений. В типовых конфигурациях (УТ 11, ERP, КА) уже существует объект РегистрСведений.НоменклатураКонтрагентов.
Если же мы работаем в кастомной конфигурации, нам следует создать регистр со следующей структурой:
Контрагент (тип СправочникСсылка.Контрагенты), НаименованиеПоставщика (тип Строка) или ссылка на отдельный справочник номенклатуры поставщика.Номенклатура (тип СправочникСсылка.Номенклатура), Характеристика (если используется).Проанализируем ситуацию: хранение соответствия позволяет нам один раз провести сопоставление (вручную или автоматически) и в дальнейшем мгновенно получать нашу ссылку на объект 1С при повторном парсинге сайта.
Основная проблема при сравнении строк — это лишние символы, разный порядок слов и сокращения. Выясним, как подготовить строки перед сравнением. Мы должны привести оба наименования (наше и спарсенное) к «каноническому» виду. Рассмотрим основные этапы очистки:
Посмотрим на пример функции для нормализации строки:
Функция НормализоватьСтроку(Знач ВхСтрока)
ВхСтрока = НРег(ВхСтрока); // Приводим к нижнему регистру
// Удаляем спецсимволы
СимволыДляУдаления = ".,!""@#$%^&*()-_=+[]{}";
Для Индекс = 1 По СтрДлина(СимволыДляУдаления) Цикл
СтрЗаменить(ВхСтрока, Сред(СимволыДляУдаления, Индекс, 1), " ");
КонецЦикла;
// Разбиваем в массив, сортируем и собираем обратно
МассивСлов = СтрРазделить(ВхСтрока, " ", Ложь);
// Здесь должна быть логика сортировки массива (например, через СписокЗначений)
СписокСлов = Новый СписокЗначений;
Для Каждого Слово Из МассивСлов Цикл
Если СтрДлина(СокрЛП(Слово)) > 1 Тогда
СписокСлов.Добавить(СокрЛП(Слово));
КонецЕсли;
КонецЦикла;
СписокСлов.СортироватьПоЗначению();
Возврат СтрСоединить(СписокСлов.ВыгрузитьЗначения(), " ");
КонецФункции
Когда простые методы сравнения не помогают, разберем более сложные математические подходы. Использование оператора ПОДОБНО в запросах 1С часто дает слишком много «мусора», поэтому лучше реализовать программное вычисление коэффициента похожести.
Расстояние Левенштейна — это количество операций (вставка, удаление, замена символа), необходимых для превращения одной строки в другую. Чем меньше расстояние, тем более похожи товары. Разберем реализацию алгоритма на языке 1С:
Функция РасстояниеЛевенштейна(Стр1, Стр2)
н = СтрДлина(Стр1);
м = СтрДлина(Стр2);
Если н = 0 Тогда Возврат м; КонецЕсли;
Если м = 0 Тогда Возврат н; КонецЕсли;
Матрица = Новый ТаблицаЗначений;
Для j = 0 По м Цикл Матрица.Колонки.Добавить("Кол" + j); КонецЦикла;
Для i = 0 По н Цикл
НоваяСтрока = Матрица.Добавить();
НоваяСтрока[0] = i;
КонецЦикла;
Для j = 1 По м Цикл
Матрица[0][j] = j;
КонецЦикла;
Для i = 1 По н Цикл
Для j = 1 По м Цикл
ЦенаЗамены = ?(Сред(Стр1, i, 1) = Сред(Стр2, j, 1), 0, 1);
Матрица[i][j] = Мин(Матрица[i-1][j] + 1,
Мин(Матрица[i][j-1] + 1,
Матрица[i-1][j-1] + ЦенаЗамены));
КонецЦикла;
КонецЦикла;
Возврат Матрица[н][м];
КонецФункции
Для практического применения мы рекомендуем пересчитывать это расстояние в процент совпадения. Если совпадение выше 85-90%, систему можно настроить на автоматическое сопоставление.
Проанализируем еще один эффективный метод — разбиение строки на части по 3 символа (триграммы). Например, слово «Маска» превратится в «Мас», «аск», «ска». Чем больше общих триграмм у двух строк, тем они ближе по смыслу. Этот метод работает быстрее Левенштейна на больших массивах данных и лучше справляется с опечатками в середине слова.
Часто в наименовании медицинских товаров или запчастей содержатся цифровые характеристики (например, «3-х слойная», «200 мл», «№50»). Посмотрим, как это использовать. Мы можем программно извлечь все числа из строки и создать «технический ключ».
Например, для строки «Маска медицинская 3-х слойная на резинке» ключом может стать МАСКА|3. Сначала мы ищем совпадения по этому ключу. Это позволит сократить выборку из 17 000 позиций до 10-20 потенциальных кандидатов, среди которых человек или алгоритм Левенштейна найдет верный вариант гораздо быстрее.
Нужно понимать, что ни один алгоритм не даст 100% точности на медицинских товарах без артикулов. Выясним, как организовать процесс сопоставления эффективно:
Рассмотрим полезный совет из практики: добавьте в форму номенклатуры кнопку «Найти аналоги у поставщика». Если при оформлении документа цена не подтянулась автоматически, менеджер сможет в один клик найти похожий товар на сайте и закрепить связь на будущее.
Если стандартных средств 1С недостаточно, можно рассмотреть интеграцию с внешними скриптами на Python или использование семантического поиска через нейросети (Embeddings). В этом случае система сравнивает не буквы, а «смысл» названий. Например, она поймет, что «ушные петли» и «на резинке» — это схожие характеристики, даже если в словах нет общего корня. Сейчас такие интеграции легко реализуются через HTTP-запросы из 1С к локальным или облачным языковым моделям.
Подведем итог: для сопоставления 17 000 позиций необходимо сначала максимально нормализовать строки (чистка, сортировка слов), затем применить комбинацию поиска по цифровым ключам и алгоритма Левенштейна. Основную часть работы система выполнит сама, а человеку останется подтвердить спорные моменты в удобном интерфейсе.