Как сопоставить номенклатуру по наименованию в 1С: нечеткое сравнение строк и алгоритмы

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

Сопоставление загружаемой номенклатуры со справочником в базе данных — классическая и регулярная задача при интеграции 1С с внешними системами, маркетплейсами или прайс-листами поставщиков. Идеальный вариант — сопоставление по уникальным идентификаторам, штрихкодам или артикулам. Однако на практике часто приходится иметь дело только с текстовыми наименованиями. Ситуация усложняется тем, что в разных базах названия одного и того же товара могут писаться по-разному: с перестановкой слов, добавлением характеристик, использованием транслита или спецсимволов.

В этой статье мы подробно рассмотрим, как реализовать надежное нечеткое сравнение строк в среде 1С:Предприятие 8, проанализируем встроенные инструменты платформы, разберем популярные математические алгоритмы и научимся правильно готовить данные перед сравнением.

Почему не стоит использовать устаревшую библиотеку StrMatch.dll

В старых обсуждениях на форумах разработчики часто рекомендуют использовать внешнюю компоненту StrMatch.dll для COM-сопоставления строк. Мы крайне не рекомендуем использовать этот метод сегодня по следующим причинам:

  1. Эта библиотека была разработана еще в 2000-х годах под 32-битную архитектуру.
  2. Для ее работы требуются устаревшие системные библиотеки Windows, такие как mfc71.dll и msvcr71.dll, которых по умолчанию нет в современных операционных системах.
  3. На современных 64-битных серверах 1С попытка зарегистрировать и использовать эту компоненту приводит к критическим ошибкам или требует сложной настройки COM+ суррогатов, что существенно снижает стабильность работы всей системы.

Использование встроенных возможностей платформы 1С и БСП

Прежде чем писать собственный код сопоставления, давайте проанализируем инструменты, которые уже есть в платформе и Библиотеке Стандартных Подсистем (БСП).

Полнотекстовый поиск (ПТП): Платформа 1С обладает мощным движком полнотекстового поиска. Мы можем программно обращаться к индексу ПТП для поиска похожих строк. Преимущество метода в том, что поиск выполняется силами СУБД крайне быстро. ПТП умеет автоматически обрабатывать морфологию русского языка, транслитерацию и опечатки за счет встроенных операторов (например, оператор нечеткости *).

Механизм поиска дублей в БСП: Если в вашей конфигурации внедрена БСП, мы можем задействовать ее встроенные алгоритмы. В подсистеме «Поиск и удаление дублей» используется нечеткое сравнение на уровне СУБД. Программа разбивает наименования на отдельные слова и сравнивает их вхождения без учета порядка слов и знаков препинания.

Реализация нечеткого сравнения: Математические алгоритмы на языке 1С

Если штатных механизмов недостаточно и требуется разработать гибкую кастомную логику, мы можем реализовать один из классических алгоритмов нечеткого сравнения непосредственно на языке 1С.

1. Расстояние Левенштейна

Этот алгоритм определяет минимальное число односимвольных операций (вставка, удаление, замена), необходимых для превращения одной строки в другую. Рассмотрим его реализацию на 1С:


Функция РасстояниеЛевенштейна(Знач Строка1, Знач Строка2) Экспорт
    Длина1 = СтрДлина(Строка1);
    Длина2 = СтрДлина(Строка2);
    
    Если Длина1 = 0 Тогда Возврат Длина2; КонецЕсли;
    Если Длина2 = 0 Тогда Возврат Длина1; КонецЕсли;
    
    // Создаем матрицу расстояний
    Матрица = Новый ТаблицаЗначений;
    Для Колонка = 0 По Длина2 Цикл
        Матрица.Колонки.Добавить("К" + Колонка, Новый ОписаниеТипов("Число"));
    КонецЦикла;
    
    Для Индекс1 = 0 По Длина1 Цикл
        НоваяСтрока = Матрица.Добавить();
        НоваяСтрока.К0 = Индекс1;
    КонецЦикла;
    
    Для Колонка = 1 По Длина2 Цикл
        Матрица[0]["К" + Колонка] = Колонка;
    КонецЦикла;
    
    // Заполняем матрицу
    Для Индекс1 = 1 По Длина1 Цикл
        Символ1 = Сред(Строка1, Индекс1, 1);
        Для Индекс2 = 1 По Длина2 Цикл
            Символ2 = Сред(Строка2, Index2, 1);
            ЦенаЗамены = ?(Символ1 = Символ2, 0, 1);
            
            ВариантУдаления = Матрица[Индекс1 - 1]["К" + Индекс2] + 1;
            ВариантВставки   = Матрица[Индекс1]["К" + (Индекс2 - 1)] + 1;
            ВариантЗамены    = Матрица[Индекс1 - 1]["К" + (Индекс2 - 1)] + ЦенаЗамены;
            
            Минимум = ?(ВариантУдаления < ВариантВставки, ВариантУдаления, ВариантВставки);
            Минимум = ?(ВариантЗамены < Минимум, ВариантЗамены, Минимум);
            
            Матрица[Индекс1]["К" + Индекс2] = Минимум;
        КонецЦикла;
    КонецЦикла;
    
    Возврат Матрица[Длина1]["К" + Длина2];
КонецФункции

Важное примечание: Алгоритм Левенштейна очень чувствителен к перестановке слов. Например, строки "Телевизор Toshiba" и "Toshiba Телевизор" получат очень низкую оценку схожести, несмотря на то, что это один и тот же товар.

2. Триграммный анализ (N-граммы)

Более устойчивым к перестановке слов является триграммный метод. Строка разбивается на пересекающиеся группы по 3 символа, и оценивается отношение количества совпадающих триграмм к их общему числу. Этот метод работает быстро и может быть оптимизирован даже через запросы 1С с использованием оператора ПОДОБНО.

Предварительная подготовка и нормализация данных

Ни один алгоритм не покажет высокой точности, если сравнивать строки в «грязном» виде. Критически важно перед отправкой строк на сравнение провести их нормализацию. Нам нужно удалить все шумовые факторы, которые не несут смысловой нагрузки для идентификации товара.

Напишем функцию нормализации строки, которая решает следующие задачи:

  1. Приводит всю строку к нижнему регистру.
  2. Удаляет знаки препинания, кавычки, дефисы и спецсимволы.
  3. Исключает шумовые слова (например: "смартфон", "белый", "шт", "моноблок").
  4. Сортирует оставшиеся слова в алфавитном порядке. Благодаря этому порядок написания слов больше не будет влиять на результат сравнения.

Разберем пример такой функции на языке 1С:


Функция НормализоватьСтроку(Знач ВходнаяСтрока) Экспорт
    Результат = НРег(ВходнаяСтрока);
    
    // Очищаем от спецсимволов и пунктуации
    СпецСимволы = "!@#$%^&*()_+=-`~[]\{}|;':"",./<>?«»""";
    Для Индекс = 1 По СтрДлина(СпецСимволы) Цикл
        Символ = Сред(СпецСимволы, Индекс, 1);
        Результат = СтрЗаменить(Результат, Символ, " ");
    КонецЦикла;
    
    // Удаляем лишние двойные пробелы
    Пока Найти(Результат, "  ") > 0 Цикл
        Результат = СтрЗаменить(Результат, "  ", " ");
    КонецЦикла;
    Результат = СокрЛП(Результат);
    
    // Преобразуем в массив слов для фильтрации и сортировки
    МассивСлов = СтрРазделить(Результат, " ");
    
    // Список шумовых слов (можно хранить в регистре сведений)
    ШумовыеСлова = Новый Соответствие;
    ШумовыеСлова.Вставить("смартфон", Истина);
    ШумовыеСлова.Вставить("телевизор", Истина);
    ШумовыеСлова.Вставить("белый", Истина);
    ШумовыеСлова.Вставить("черный", Истина);
    ШумовыеСлова.Вставить("шт", Истина);
    ШумовыеСлова.Вставить("дюйма", Истина);
    
    СписокОчищенныхСлов = Новый СписокЗначений;
    Для Каждого Слово Из МассивСлов Цикл
        Если ШумовыеСлова[Слово] = Неопределено Тогда
            СписокОчищенныхСлов.Добавить(Слово);
        КонецЕсли;
    КонецЦикла;
    
    // Сортируем слова по алфавиту для устранения фактора перестановки
    СписокОчищенныхСлов.СортироватьПоЗначению();
    
    // Собираем строку обратно
    МассивОчищенныхСлов = СписокОчищенныхСлов.ВыгрузитьЗначения();
    РезультатСтрока = СтрСоединить(МассивОчищенныхСлов, " ");
    
    Возврат РезультатСтрока;
КонецФункции

Проанализируем работу этой функции. Если на вход мы подадим строку "Телевизор Toshiba 43L5780EC 43"" (2018)", то после нормализации мы получим очищенную строку "43 43l5780ec 2018 toshiba". Теперь ее можно легко сравнивать с другими очищенными строками, используя обычное равенство или простые весовые коэффициенты вхождения слов.

Современные готовые решения и интеграции

Если объем сопоставляемых данных велик (десятки и сотни тысяч позиций), написание собственных движков сопоставления внутри 1С может потребовать значительных вычислительных мощностей и времени разработки. В таких случаях имеет смысл рассмотреть готовые альтернативы:

  1. Профессиональные коммерческие модули: На рынке представлены готовые модули обработки прайсов (например, линейки продуктов класса «Мегапрайс» или разработки от «Subsystems»). Они содержат готовые высокопроизводительные движки очистки данных, ведение словарей синонимов брендов и автоматические алгоритмы связывания.
  2. Облачные сервисы сопоставления через API: Существуют внешние сервисы распознавания документов и сопоставления номенклатуры. Работает это следующим образом: ваша система отправляет нераспознанные строки по REST API, облачный сервис задействует обученные нейросети (LLM) и алгоритмы машинного обучения, после чего возвращает наиболее вероятного кандидата из вашей базы с указанием процента уверенности.

Подводя итог, можно сказать: для качественного сопоставления номенклатуры по строкам в 1С необходимо сочетать предварительную нормализацию (очистка, сортировка слов) с выбранным алгоритмом нечеткого сравнения. Для простых задач отлично подойдет встроенный механизм поиска дублей БСП, а для сложных — триграммный анализ или готовые интеграционные сервисы.

← На главную